mirror of
https://github.com/TheRealOwenRees/echecsfrance.git
synced 2026-07-23 12:36:57 +00:00
Add information about first notification email
This commit is contained in:
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user