Add information about first notification email

This commit is contained in:
Timothy Armes
2024-10-21 15:16:38 +02:00
parent b4e1b6d24c
commit 3dfbde0ef9
12 changed files with 196 additions and 103 deletions
@@ -9,7 +9,7 @@ import { FormProvider, useForm } from "react-hook-form";
import { z } from "zod";
import { Button } from "@/components/Button";
import { clearMessage } from "@/components/InfoMessage";
import { InfoMessageType } from "@/components/InfoMessage";
import InfoMessage from "@/components/InfoMessage";
import LoadingMap from "@/components/LoadingMap";
import { DateField } from "@/components/form/DateField";
@@ -32,10 +32,10 @@ const TournamentForm = () => {
const t = useTranslations("AddTournament");
const at = useTranslations("App");
const [responseMessage, setResponseMessage] = useState({
isSuccessful: false,
message: "",
});
const [responseMessage, setResponseMessage] = useState<{
type: InfoMessageType;
message: string;
} | null>(null);
const form = useForm<TournamentFormValues>({
resolver: zodResolver(addTournamentSchema),
@@ -51,20 +51,18 @@ const TournamentForm = () => {
try {
await addTournament(data);
setResponseMessage({
isSuccessful: true,
type: "success",
message: t("success"),
});
clearMessage(setResponseMessage);
form.reset();
} catch (err: unknown) {
console.log(err);
setResponseMessage({
isSuccessful: false,
type: "error",
message: t("failure"),
});
clearMessage(setResponseMessage);
}
};
@@ -220,7 +218,14 @@ const TournamentForm = () => {
{t("clearForm")}
</Button>
</div>
<InfoMessage responseMessage={responseMessage} />
{responseMessage && (
<InfoMessage
message={responseMessage.message}
type={responseMessage.type}
onDismiss={() => setResponseMessage(null)}
/>
)}
</form>
</FormProvider>
);
+1 -1
View File
@@ -52,7 +52,7 @@ const ClubTable = () => {
<div className="flex flex-col gap-0 text-gray-900 dark:text-white"></div>
</div>
<div className="overflow-x-scroll bg-red-50">
<div className="overflow-x-scroll">
<table className="relative min-w-full table-fixed text-center text-xs lg:min-w-full">
<thead>
<tr>
@@ -9,7 +9,7 @@ import { z } from "zod";
import { Button } from "@/components/Button";
import InfoMessage from "@/components/InfoMessage";
import { clearMessage } from "@/components/InfoMessage";
import { InfoMessageType } from "@/components/InfoMessage";
import { TextAreaField } from "@/components/form/TextAreaField";
import { TextField } from "@/components/form/TextField";
import { contactUsSchema } from "@/schemas";
@@ -20,10 +20,10 @@ type TournamentFormValues = z.infer<typeof contactUsSchema>;
const ContactForm = () => {
const t = useTranslations("Contact");
const [responseMessage, setResponseMessage] = useState({
isSuccessful: false,
message: "",
});
const [responseMessage, setResponseMessage] = useState<{
type: InfoMessageType;
message: string;
} | null>(null);
const form = useForm<TournamentFormValues>({
resolver: zodResolver(contactUsSchema),
@@ -33,20 +33,17 @@ const ContactForm = () => {
try {
await contactUs(data);
setResponseMessage({
isSuccessful: true,
type: "success",
message: t("success"),
});
clearMessage(setResponseMessage);
form.reset();
} catch (err: unknown) {
console.log(err);
setResponseMessage({
isSuccessful: false,
type: "error",
message: t("failure"),
});
clearMessage(setResponseMessage);
}
};
@@ -82,7 +79,13 @@ const ContactForm = () => {
{form.formState.isSubmitting ? t("sending") : t("sendButton")}
</Button>
<InfoMessage responseMessage={responseMessage} />
{responseMessage && (
<InfoMessage
message={responseMessage.message}
type={responseMessage.type}
onDismiss={() => setResponseMessage(null)}
/>
)}
</form>
</FormProvider>
);
@@ -50,10 +50,7 @@ export default function Contact() {
</h2>
{deleted ? (
<InfoMessage
className="text-center"
responseMessage={{ isSuccessful: true, message: t("success") }}
/>
<InfoMessage className="mb-8" type="success" message={t("success")} />
) : (
<>
<p className="mb-8 text-center font-light text-gray-500 dark:text-gray-400 sm:text-xl lg:mb-16">
@@ -62,8 +59,9 @@ export default function Contact() {
{error && (
<InfoMessage
className="mb-8 text-center"
responseMessage={{ isSuccessful: false, message: t("failure") }}
className="mb-8"
type="error"
message={t("failure")}
/>
)}
@@ -6,6 +6,7 @@ import { FormProvider, useForm } from "react-hook-form";
import { z } from "zod";
import { Button } from "@/components/Button";
import InfoMessage from "@/components/InfoMessage";
import { InlineSwitchField } from "@/components/form/InlineSwitchField";
import { Label } from "@/components/form/Label";
import { TextField } from "@/components/form/TextField";
@@ -20,6 +21,7 @@ type ZoneFormProps = {
zone?: Zone;
onSubmit: (data: ZoneFormValues) => Promise<void>;
onCancel: () => void;
withInfo?: boolean;
submitTitle?: string;
cancelTitle?: string;
};
@@ -28,6 +30,7 @@ export const ZoneForm = ({
zone,
onSubmit,
onCancel,
withInfo,
submitTitle,
cancelTitle,
}: ZoneFormProps) => {
@@ -58,8 +61,14 @@ export const ZoneForm = ({
},
});
const features = form.watch("features");
console.log(features);
const [cn, rn, bn, on] = form.watch([
"classicNotifications",
"rapidNotifications",
"blitzNotifications",
"otherNotifications",
]);
const requestingNotifications = cn || rn || bn || on;
return (
<FormProvider {...form}>
@@ -89,22 +98,34 @@ export const ZoneForm = ({
control={form.control}
label={at("timeControlEnum", { tc: TimeControl.Classic })}
/>
<InlineSwitchField
name="rapidNotifications"
control={form.control}
label={at("timeControlEnum", { tc: TimeControl.Rapid })}
/>
<InlineSwitchField
name="blitzNotifications"
control={form.control}
label={at("timeControlEnum", { tc: TimeControl.Blitz })}
/>
<InlineSwitchField
name="otherNotifications"
control={form.control}
label={at("timeControlEnum", { tc: TimeControl.Other })}
/>
{withInfo && requestingNotifications && (
<div className="col-span-4">
<InfoMessage
type="info"
message={t.rich("firstNotificationInfo", { br: () => <br /> })}
/>
</div>
)}
<section id="map" className="z-0 col-span-4 flex h-auto">
<ZoneEditorField name="features" control={form.control} />
</section>
+19 -10
View File
@@ -4,7 +4,7 @@ import { useState } from "react";
import { useTranslations } from "next-intl";
import InfoMessage, { clearMessage } from "@/components/InfoMessage";
import InfoMessage, { InfoMessageType } from "@/components/InfoMessage";
import { useZones } from "@/hooks/useZones";
import { createZone } from "@/server/createZone";
import { useRouter } from "@/utils/routing";
@@ -15,10 +15,10 @@ const CreateZone = () => {
const t = useTranslations("Zones");
const router = useRouter();
const [responseMessage, setResponseMessage] = useState({
isSuccessful: false,
message: "",
});
const [responseMessage, setResponseMessage] = useState<{
type: InfoMessageType;
message: string;
} | null>(null);
const { refetch } = useZones();
@@ -31,11 +31,9 @@ const CreateZone = () => {
} catch (err: unknown) {
console.log(err);
setResponseMessage({
isSuccessful: false,
type: "error",
message: t("createFailure"),
});
clearMessage(setResponseMessage);
}
};
@@ -48,8 +46,19 @@ const CreateZone = () => {
{t("createTitle")}
</h2>
<ZoneForm onSubmit={onSubmit} onCancel={() => router.push("/zones")} />
<InfoMessage responseMessage={responseMessage} />
<ZoneForm
withInfo
onSubmit={onSubmit}
onCancel={() => router.push("/zones")}
/>
{responseMessage && (
<InfoMessage
message={responseMessage.message}
type={responseMessage.type}
onDismiss={() => setResponseMessage(null)}
/>
)}
</div>
);
};
@@ -5,7 +5,7 @@ import { useState } from "react";
import { useTranslations } from "next-intl";
import { useParams } from "next/navigation";
import InfoMessage, { clearMessage } from "@/components/InfoMessage";
import InfoMessage, { InfoMessageType } from "@/components/InfoMessage";
import { useZones } from "@/hooks/useZones";
import { editZone } from "@/server/editZone";
import { useRouter } from "@/utils/routing";
@@ -17,10 +17,10 @@ const EditZone = () => {
const router = useRouter();
const params = useParams();
const [responseMessage, setResponseMessage] = useState({
isSuccessful: false,
message: "",
});
const [responseMessage, setResponseMessage] = useState<{
type: InfoMessageType;
message: string;
} | null>(null);
const { zones, isFetching, refetch } = useZones();
@@ -51,11 +51,9 @@ const EditZone = () => {
router.push("/zones");
} catch (error) {
setResponseMessage({
isSuccessful: false,
type: "error",
message: t("createFailure"),
});
clearMessage(setResponseMessage);
}
};
@@ -74,7 +72,13 @@ const EditZone = () => {
zone={zone}
/>
<InfoMessage responseMessage={responseMessage} />
{responseMessage && (
<InfoMessage
message={responseMessage.message}
type={responseMessage.type}
onDismiss={() => setResponseMessage(null)}
/>
)}
</div>
);
};
+13 -10
View File
@@ -7,7 +7,7 @@ import dynamic from "next/dynamic";
import { IoAdd } from "react-icons/io5";
import { Button, buttonVariants } from "@/components/Button";
import InfoMessage, { clearMessage } from "@/components/InfoMessage";
import InfoMessage, { InfoMessageType } from "@/components/InfoMessage";
import { Modal } from "@/components/Modal";
import { Spinner } from "@/components/Spinner";
import { useZones } from "@/hooks/useZones";
@@ -27,11 +27,10 @@ const Zones = () => {
const format = useFormatter();
const [deletingZoneId, setDeletingZoneId] = useState<string | null>(null);
const [responseMessage, setResponseMessage] = useState({
isSuccessful: false,
message: "",
});
const [responseMessage, setResponseMessage] = useState<{
type: InfoMessageType;
message: string;
} | null>(null);
const { zones, isFetching, refetch } = useZones();
const onDelete = async () => {
@@ -46,11 +45,9 @@ const Zones = () => {
} catch (err: unknown) {
console.log(err);
setResponseMessage({
isSuccessful: false,
type: "error",
message: t("createFailure"),
});
clearMessage(setResponseMessage);
}
};
@@ -154,7 +151,13 @@ const Zones = () => {
title={t("deleteZoneTitle")}
subTitle={t("deleteZoneInfo")}
>
<InfoMessage responseMessage={responseMessage} />
{responseMessage && (
<InfoMessage
message={responseMessage.message}
type={responseMessage.type}
onDismiss={() => setResponseMessage(null)}
/>
)}
<div className="flex items-center justify-between space-x-4 text-sm font-bold">
<Button