mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-18 10:41:56 +10:00
feat(i18n): translate error messages
This commit is contained in:
@ -1,6 +1,5 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { t } from "@lingui/macro";
|
||||
import { Warning } from "@phosphor-icons/react";
|
||||
import { twoFactorBackupSchema } from "@reactive-resume/dto";
|
||||
import { usePasswordToggle } from "@reactive-resume/hooks";
|
||||
import {
|
||||
@ -13,13 +12,11 @@ import {
|
||||
FormMessage,
|
||||
Input,
|
||||
} from "@reactive-resume/ui";
|
||||
import { AxiosError } from "axios";
|
||||
import { useRef } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { z } from "zod";
|
||||
|
||||
import { toast } from "@/client/hooks/use-toast";
|
||||
import { useBackupOtp } from "@/client/services/auth";
|
||||
|
||||
type FormValues = z.infer<typeof twoFactorBackupSchema>;
|
||||
@ -43,17 +40,6 @@ export const BackupOtpPage = () => {
|
||||
navigate("/dashboard");
|
||||
} catch (error) {
|
||||
form.reset();
|
||||
|
||||
if (error instanceof AxiosError) {
|
||||
const message = error.response?.data.message || error.message;
|
||||
|
||||
toast({
|
||||
variant: "error",
|
||||
icon: <Warning size={16} weight="bold" />,
|
||||
title: t`An error occurred while trying to sign in to your account.`,
|
||||
description: message,
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { t } from "@lingui/macro";
|
||||
import { Warning } from "@phosphor-icons/react";
|
||||
import { forgotPasswordSchema } from "@reactive-resume/dto";
|
||||
import {
|
||||
Alert,
|
||||
@ -14,12 +13,10 @@ import {
|
||||
FormMessage,
|
||||
Input,
|
||||
} from "@reactive-resume/ui";
|
||||
import { AxiosError } from "axios";
|
||||
import { useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
|
||||
import { toast } from "@/client/hooks/use-toast";
|
||||
import { useForgotPassword } from "@/client/services/auth";
|
||||
|
||||
type FormValues = z.infer<typeof forgotPasswordSchema>;
|
||||
@ -34,22 +31,10 @@ export const ForgotPasswordPage = () => {
|
||||
});
|
||||
|
||||
const onSubmit = async (data: FormValues) => {
|
||||
try {
|
||||
await forgotPassword(data);
|
||||
setSubmitted(true);
|
||||
form.reset();
|
||||
} catch (error) {
|
||||
if (error instanceof AxiosError) {
|
||||
const message = error.response?.data.message || error.message;
|
||||
await forgotPassword(data);
|
||||
|
||||
toast({
|
||||
variant: "error",
|
||||
icon: <Warning size={16} weight="bold" />,
|
||||
title: t`An error occurred while trying to send your password recovery email.`,
|
||||
description: message,
|
||||
});
|
||||
}
|
||||
}
|
||||
setSubmitted(true);
|
||||
form.reset();
|
||||
};
|
||||
|
||||
if (submitted) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { t, Trans } from "@lingui/macro";
|
||||
import { ArrowRight, Warning } from "@phosphor-icons/react";
|
||||
import { ArrowRight } from "@phosphor-icons/react";
|
||||
import { loginSchema } from "@reactive-resume/dto";
|
||||
import { usePasswordToggle } from "@reactive-resume/hooks";
|
||||
import {
|
||||
@ -14,19 +14,16 @@ import {
|
||||
FormMessage,
|
||||
Input,
|
||||
} from "@reactive-resume/ui";
|
||||
import { AxiosError } from "axios";
|
||||
import { useRef } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { Link } from "react-router-dom";
|
||||
import { z } from "zod";
|
||||
|
||||
import { useToast } from "@/client/hooks/use-toast";
|
||||
import { useLogin } from "@/client/services/auth";
|
||||
|
||||
type FormValues = z.infer<typeof loginSchema>;
|
||||
|
||||
export const LoginPage = () => {
|
||||
const { toast } = useToast();
|
||||
const { login, loading } = useLogin();
|
||||
|
||||
const formRef = useRef<HTMLFormElement>(null);
|
||||
@ -42,17 +39,6 @@ export const LoginPage = () => {
|
||||
await login(data);
|
||||
} catch (error) {
|
||||
form.reset();
|
||||
|
||||
if (error instanceof AxiosError) {
|
||||
const message = error.response?.data.message || error.message;
|
||||
|
||||
toast({
|
||||
variant: "error",
|
||||
icon: <Warning size={16} weight="bold" />,
|
||||
title: t`An error occurred while trying to sign in to your account.`,
|
||||
description: message,
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { t, Trans } from "@lingui/macro";
|
||||
import { ArrowRight, Warning } from "@phosphor-icons/react";
|
||||
import { ArrowRight } from "@phosphor-icons/react";
|
||||
import { registerSchema } from "@reactive-resume/dto";
|
||||
import { usePasswordToggle } from "@reactive-resume/hooks";
|
||||
import {
|
||||
@ -14,13 +14,11 @@ import {
|
||||
FormMessage,
|
||||
Input,
|
||||
} from "@reactive-resume/ui";
|
||||
import { AxiosError } from "axios";
|
||||
import { useRef } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { z } from "zod";
|
||||
|
||||
import { toast } from "@/client/hooks/use-toast";
|
||||
import { useRegister } from "@/client/services/auth";
|
||||
|
||||
type FormValues = z.infer<typeof registerSchema>;
|
||||
@ -50,17 +48,6 @@ export const RegisterPage = () => {
|
||||
navigate("/auth/verify-email");
|
||||
} catch (error) {
|
||||
form.reset();
|
||||
|
||||
if (error instanceof AxiosError) {
|
||||
const message = error.response?.data.message || error.message;
|
||||
|
||||
toast({
|
||||
variant: "error",
|
||||
icon: <Warning size={16} weight="bold" />,
|
||||
title: t`An error occurred while trying to create a new account.`,
|
||||
description: message,
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { t, Trans } from "@lingui/macro";
|
||||
import { Warning } from "@phosphor-icons/react";
|
||||
import { resetPasswordSchema } from "@reactive-resume/dto";
|
||||
import { usePasswordToggle } from "@reactive-resume/hooks";
|
||||
import {
|
||||
@ -14,13 +13,11 @@ import {
|
||||
FormMessage,
|
||||
Input,
|
||||
} from "@reactive-resume/ui";
|
||||
import { AxiosError } from "axios";
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useNavigate, useSearchParams } from "react-router-dom";
|
||||
import { z } from "zod";
|
||||
|
||||
import { toast } from "@/client/hooks/use-toast";
|
||||
import { useResetPassword } from "@/client/services/auth";
|
||||
|
||||
type FormValues = z.infer<typeof resetPasswordSchema>;
|
||||
@ -47,17 +44,6 @@ export const ResetPasswordPage = () => {
|
||||
navigate("/auth/login");
|
||||
} catch (error) {
|
||||
form.reset();
|
||||
|
||||
if (error instanceof AxiosError) {
|
||||
const message = error.response?.data.message || error.message;
|
||||
|
||||
toast({
|
||||
variant: "error",
|
||||
icon: <Warning size={16} weight="bold" />,
|
||||
title: t`An error occurred while trying to reset your password.`,
|
||||
description: message,
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { t, Trans } from "@lingui/macro";
|
||||
import { ArrowRight, Info, SealCheck, Warning } from "@phosphor-icons/react";
|
||||
import { ArrowRight, Info, SealCheck } from "@phosphor-icons/react";
|
||||
import { Alert, AlertDescription, AlertTitle, Button } from "@reactive-resume/ui";
|
||||
import { AxiosError } from "axios";
|
||||
import { useEffect } from "react";
|
||||
import { Link, useNavigate, useSearchParams } from "react-router-dom";
|
||||
|
||||
@ -19,29 +18,16 @@ export const VerifyEmailPage = () => {
|
||||
|
||||
useEffect(() => {
|
||||
const handleVerifyEmail = async (token: string) => {
|
||||
try {
|
||||
await verifyEmail({ token });
|
||||
await queryClient.invalidateQueries({ queryKey: ["user"] });
|
||||
await verifyEmail({ token });
|
||||
await queryClient.invalidateQueries({ queryKey: ["user"] });
|
||||
|
||||
toast({
|
||||
variant: "success",
|
||||
icon: <SealCheck size={16} weight="bold" />,
|
||||
title: t`Your email address has been verified successfully.`,
|
||||
});
|
||||
toast({
|
||||
variant: "success",
|
||||
icon: <SealCheck size={16} weight="bold" />,
|
||||
title: t`Your email address has been verified successfully.`,
|
||||
});
|
||||
|
||||
navigate("/dashboard/resumes", { replace: true });
|
||||
} catch (error) {
|
||||
if (error instanceof AxiosError) {
|
||||
const message = error.response?.data.message || error.message;
|
||||
|
||||
toast({
|
||||
variant: "error",
|
||||
icon: <Warning size={16} weight="bold" />,
|
||||
title: t`An error occurred while trying to verify your email address.`,
|
||||
description: message,
|
||||
});
|
||||
}
|
||||
}
|
||||
navigate("/dashboard/resumes", { replace: true });
|
||||
};
|
||||
|
||||
if (!token) return;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { t } from "@lingui/macro";
|
||||
import { ArrowRight, Warning } from "@phosphor-icons/react";
|
||||
import { ArrowRight } from "@phosphor-icons/react";
|
||||
import { twoFactorSchema } from "@reactive-resume/dto";
|
||||
import { usePasswordToggle } from "@reactive-resume/hooks";
|
||||
import {
|
||||
@ -13,13 +13,11 @@ import {
|
||||
FormMessage,
|
||||
Input,
|
||||
} from "@reactive-resume/ui";
|
||||
import { AxiosError } from "axios";
|
||||
import { useRef } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { z } from "zod";
|
||||
|
||||
import { toast } from "@/client/hooks/use-toast";
|
||||
import { useVerifyOtp } from "@/client/services/auth";
|
||||
|
||||
type FormValues = z.infer<typeof twoFactorSchema>;
|
||||
@ -43,17 +41,6 @@ export const VerifyOtpPage = () => {
|
||||
navigate("/dashboard");
|
||||
} catch (error) {
|
||||
form.reset();
|
||||
|
||||
if (error instanceof AxiosError) {
|
||||
const message = error.response?.data.message || error.message;
|
||||
|
||||
toast({
|
||||
variant: "error",
|
||||
icon: <Warning size={16} weight="bold" />,
|
||||
title: t`An error occurred while trying to sign in to your account.`,
|
||||
description: message,
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -187,7 +187,7 @@ export const ImportDialog = () => {
|
||||
toast({
|
||||
variant: "error",
|
||||
icon: <Warning size={16} weight="bold" />,
|
||||
title: t`An error occurred while importing your resume.`,
|
||||
title: t`Oops, the server returned an error.`,
|
||||
description: importError?.message,
|
||||
});
|
||||
}
|
||||
|
||||
@ -34,12 +34,10 @@ import {
|
||||
Tooltip,
|
||||
} from "@reactive-resume/ui";
|
||||
import { generateRandomName, kebabCase } from "@reactive-resume/utils";
|
||||
import { AxiosError } from "axios";
|
||||
import { useEffect } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
|
||||
import { useToast } from "@/client/hooks/use-toast";
|
||||
import { useCreateResume, useDeleteResume, useUpdateResume } from "@/client/services/resume";
|
||||
import { useImportResume } from "@/client/services/resume/import";
|
||||
import { useDialog } from "@/client/stores/dialog";
|
||||
@ -49,7 +47,6 @@ const formSchema = createResumeSchema.extend({ id: idSchema.optional() });
|
||||
type FormValues = z.infer<typeof formSchema>;
|
||||
|
||||
export const ResumeDialog = () => {
|
||||
const { toast } = useToast();
|
||||
const { isOpen, mode, payload, close } = useDialog<ResumeDto>("resume");
|
||||
|
||||
const isCreate = mode === "create";
|
||||
@ -79,49 +76,37 @@ export const ResumeDialog = () => {
|
||||
}, [form.watch("title")]);
|
||||
|
||||
const onSubmit = async (values: FormValues) => {
|
||||
try {
|
||||
if (isCreate) {
|
||||
await createResume({ slug: values.slug, title: values.title, visibility: "private" });
|
||||
}
|
||||
|
||||
if (isUpdate) {
|
||||
if (!payload.item?.id) return;
|
||||
|
||||
await updateResume({
|
||||
...payload.item,
|
||||
title: values.title,
|
||||
slug: values.slug,
|
||||
});
|
||||
}
|
||||
|
||||
if (isDuplicate) {
|
||||
if (!payload.item?.id) return;
|
||||
|
||||
await duplicateResume({
|
||||
title: values.title,
|
||||
slug: values.slug,
|
||||
data: payload.item.data,
|
||||
});
|
||||
}
|
||||
|
||||
if (isDelete) {
|
||||
if (!payload.item?.id) return;
|
||||
|
||||
await deleteResume({ id: payload.item?.id });
|
||||
}
|
||||
|
||||
close();
|
||||
} catch (error) {
|
||||
if (error instanceof AxiosError) {
|
||||
const message = error.response?.data?.message || error.message;
|
||||
|
||||
toast({
|
||||
variant: "error",
|
||||
title: t`An error occurred while trying to create your resume.`,
|
||||
description: message,
|
||||
});
|
||||
}
|
||||
if (isCreate) {
|
||||
await createResume({ slug: values.slug, title: values.title, visibility: "private" });
|
||||
}
|
||||
|
||||
if (isUpdate) {
|
||||
if (!payload.item?.id) return;
|
||||
|
||||
await updateResume({
|
||||
...payload.item,
|
||||
title: values.title,
|
||||
slug: values.slug,
|
||||
});
|
||||
}
|
||||
|
||||
if (isDuplicate) {
|
||||
if (!payload.item?.id) return;
|
||||
|
||||
await duplicateResume({
|
||||
title: values.title,
|
||||
slug: values.slug,
|
||||
data: payload.item.data,
|
||||
});
|
||||
}
|
||||
|
||||
if (isDelete) {
|
||||
if (!payload.item?.id) return;
|
||||
|
||||
await deleteResume({ id: payload.item?.id });
|
||||
}
|
||||
|
||||
close();
|
||||
};
|
||||
|
||||
const onReset = () => {
|
||||
|
||||
@ -28,7 +28,6 @@ import {
|
||||
FormMessage,
|
||||
Input,
|
||||
} from "@reactive-resume/ui";
|
||||
import { AxiosError } from "axios";
|
||||
import { QRCodeSVG } from "qrcode.react";
|
||||
import { useEffect } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
@ -93,23 +92,11 @@ export const TwoFactorDialog = () => {
|
||||
if (isUpdate) {
|
||||
if (!values.code) return;
|
||||
|
||||
try {
|
||||
const data = await enable2FA({ code: values.code });
|
||||
form.setValue("backupCodes", data.backupCodes);
|
||||
await queryClient.invalidateQueries({ queryKey: ["user"] });
|
||||
const data = await enable2FA({ code: values.code });
|
||||
form.setValue("backupCodes", data.backupCodes);
|
||||
await queryClient.invalidateQueries({ queryKey: ["user"] });
|
||||
|
||||
open("duplicate");
|
||||
} catch (error) {
|
||||
if (error instanceof AxiosError) {
|
||||
const message = error.response?.data?.message || error.message;
|
||||
|
||||
toast({
|
||||
variant: "error",
|
||||
title: t`An error occurred while trying to enable two-factor authentication.`,
|
||||
description: message,
|
||||
});
|
||||
}
|
||||
}
|
||||
open("duplicate");
|
||||
}
|
||||
|
||||
if (isDuplicate) {
|
||||
|
||||
@ -153,15 +153,18 @@ const Question4 = () => {
|
||||
>
|
||||
<div className="relative bg-secondary-accent font-medium">
|
||||
<span className="px-2 py-1">{language.name}</span>
|
||||
<span
|
||||
className={cn(
|
||||
"inset-0 bg-warning px-1.5 py-1 text-xs text-white",
|
||||
language.progress < 40 && "bg-error",
|
||||
language.progress > 80 && "bg-success",
|
||||
)}
|
||||
>
|
||||
{language.progress}%
|
||||
</span>
|
||||
|
||||
{language.progress && (
|
||||
<span
|
||||
className={cn(
|
||||
"inset-0 bg-warning px-1.5 py-1 text-xs text-white",
|
||||
language.progress < 40 && "bg-error",
|
||||
language.progress > 80 && "bg-success",
|
||||
)}
|
||||
>
|
||||
{language.progress}%
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</a>
|
||||
))}
|
||||
|
||||
@ -8,7 +8,6 @@ import { Link, LoaderFunction, redirect, useLoaderData } from "react-router-dom"
|
||||
|
||||
import { Icon } from "@/client/components/icon";
|
||||
import { ThemeSwitch } from "@/client/components/theme-switch";
|
||||
import { toast } from "@/client/hooks/use-toast";
|
||||
import { queryClient } from "@/client/libs/query-client";
|
||||
import { findResumeByUsernameSlug } from "@/client/services/resume";
|
||||
|
||||
@ -101,11 +100,6 @@ export const publicLoader: LoaderFunction<ResumeDto> = async ({ params }) => {
|
||||
|
||||
return resume;
|
||||
} catch (error) {
|
||||
toast({
|
||||
variant: "error",
|
||||
title: t`The resume you were looking for doesn't seem to exist, please check the link and try again.`,
|
||||
});
|
||||
|
||||
return redirect("/");
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user