From 7fb0226ddc11ad0e122da1303e9983c79e053c08 Mon Sep 17 00:00:00 2001 From: Amruth Pillai Date: Sun, 12 Jan 2025 19:41:18 +0100 Subject: [PATCH] update to react-router v7 --- apps/artboard/index.html | 7 -- apps/artboard/src/components/brand-icon.tsx | 6 +- apps/artboard/src/main.tsx | 2 +- apps/artboard/src/pages/artboard.tsx | 2 +- apps/artboard/src/providers/index.tsx | 2 +- apps/artboard/src/router/index.tsx | 4 +- apps/client/index.html | 7 -- apps/client/src/components/user-options.tsx | 4 +- apps/client/src/libs/axios.ts | 2 +- apps/client/src/main.tsx | 2 +- .../client/src/pages/auth/backup-otp/page.tsx | 6 +- .../src/pages/auth/forgot-password/page.tsx | 4 +- apps/client/src/pages/auth/layout.tsx | 2 +- apps/client/src/pages/auth/login/page.tsx | 2 +- apps/client/src/pages/auth/register/page.tsx | 4 +- .../src/pages/auth/reset-password/page.tsx | 6 +- .../src/pages/auth/verify-email/page.tsx | 4 +- .../client/src/pages/auth/verify-otp/page.tsx | 4 +- .../src/pages/builder/_components/header.tsx | 2 +- apps/client/src/pages/builder/layout.tsx | 2 +- apps/client/src/pages/builder/page.tsx | 2 +- .../src/pages/builder/sidebars/left/index.tsx | 2 +- .../pages/dashboard/_components/sidebar.tsx | 6 +- apps/client/src/pages/dashboard/layout.tsx | 2 +- .../dashboard/resumes/_dialogs/resume.tsx | 2 +- .../_layouts/grid/_components/resume-card.tsx | 4 +- .../_layouts/list/_components/resume-item.tsx | 4 +- .../dashboard/settings/_sections/danger.tsx | 4 +- .../src/pages/home/components/footer.tsx | 2 +- .../src/pages/home/components/header.tsx | 2 +- apps/client/src/pages/home/layout.tsx | 2 +- .../home/sections/hero/call-to-action.tsx | 2 +- apps/client/src/pages/public/page.tsx | 6 +- apps/client/src/providers/index.tsx | 2 +- apps/client/src/router/guards/auth.tsx | 2 +- apps/client/src/router/guards/guest.tsx | 2 +- apps/client/src/router/index.tsx | 5 +- apps/client/src/router/loaders/auth.ts | 2 +- apps/client/src/services/auth/login.ts | 4 +- libs/dto/package.json | 3 +- libs/dto/src/resume/create.ts | 7 +- libs/dto/src/resume/import.ts | 7 +- libs/utils/src/namespaces/page.ts | 2 +- package.json | 2 +- pnpm-lock.yaml | 66 +++++++++++-------- 45 files changed, 112 insertions(+), 106 deletions(-) diff --git a/apps/artboard/index.html b/apps/artboard/index.html index 2705af91..e4b13a8d 100644 --- a/apps/artboard/index.html +++ b/apps/artboard/index.html @@ -40,12 +40,5 @@ - - - diff --git a/apps/artboard/src/components/brand-icon.tsx b/apps/artboard/src/components/brand-icon.tsx index abf9a5df..a572568c 100644 --- a/apps/artboard/src/components/brand-icon.tsx +++ b/apps/artboard/src/components/brand-icon.tsx @@ -1,5 +1,3 @@ -import { cn } from "@reactive-resume/utils"; - type BrandIconProps = { slug: string; }; @@ -8,12 +6,12 @@ export const BrandIcon = ({ slug }: BrandIconProps) => { if (slug === "linkedin") { return ( LinkedIn ); } - return ; + return {slug}; }; diff --git a/apps/artboard/src/main.tsx b/apps/artboard/src/main.tsx index 6190e31c..26f9e5ba 100644 --- a/apps/artboard/src/main.tsx +++ b/apps/artboard/src/main.tsx @@ -1,6 +1,6 @@ import { StrictMode } from "react"; import * as ReactDOM from "react-dom/client"; -import { RouterProvider } from "react-router-dom"; +import { RouterProvider } from "react-router"; import { router } from "./router"; diff --git a/apps/artboard/src/pages/artboard.tsx b/apps/artboard/src/pages/artboard.tsx index 18facf62..5b212cb0 100644 --- a/apps/artboard/src/pages/artboard.tsx +++ b/apps/artboard/src/pages/artboard.tsx @@ -1,5 +1,5 @@ import { useEffect, useMemo } from "react"; -import { Outlet } from "react-router-dom"; +import { Outlet } from "react-router"; import webfontloader from "webfontloader"; import { useArtboardStore } from "../store/artboard"; diff --git a/apps/artboard/src/providers/index.tsx b/apps/artboard/src/providers/index.tsx index dbb51031..5370e15e 100644 --- a/apps/artboard/src/providers/index.tsx +++ b/apps/artboard/src/providers/index.tsx @@ -1,5 +1,5 @@ import { useEffect } from "react"; -import { Outlet } from "react-router-dom"; +import { Outlet } from "react-router"; import { useArtboardStore } from "../store/artboard"; diff --git a/apps/artboard/src/router/index.tsx b/apps/artboard/src/router/index.tsx index 5b83fc66..ca9e8bef 100644 --- a/apps/artboard/src/router/index.tsx +++ b/apps/artboard/src/router/index.tsx @@ -1,4 +1,4 @@ -import { createBrowserRouter, createRoutesFromChildren, Route } from "react-router-dom"; +import { createBrowserRouter, createRoutesFromChildren, Route } from "react-router"; import { ArtboardPage } from "../pages/artboard"; import { BuilderLayout } from "../pages/builder"; @@ -6,7 +6,7 @@ import { PreviewLayout } from "../pages/preview"; import { Providers } from "../providers"; export const routes = createRoutesFromChildren( - }> + } hydrateFallbackElement={
Loading...
}> }> } /> } /> diff --git a/apps/client/index.html b/apps/client/index.html index 879f1200..c910c5ce 100644 --- a/apps/client/index.html +++ b/apps/client/index.html @@ -43,12 +43,5 @@ - - - diff --git a/apps/client/src/components/user-options.tsx b/apps/client/src/components/user-options.tsx index 2690bdaa..9061426b 100644 --- a/apps/client/src/components/user-options.tsx +++ b/apps/client/src/components/user-options.tsx @@ -7,7 +7,7 @@ import { DropdownMenuTrigger, KeyboardShortcut, } from "@reactive-resume/ui"; -import { useNavigate } from "react-router-dom"; +import { useNavigate } from "react-router"; import { useLogout } from "../services/auth"; @@ -26,7 +26,7 @@ export const UserOptions = ({ children }: Props) => { { - navigate("/dashboard/settings"); + void navigate("/dashboard/settings"); }} > {t`Settings`} diff --git a/apps/client/src/libs/axios.ts b/apps/client/src/libs/axios.ts index e7fa7a0a..7fb7d225 100644 --- a/apps/client/src/libs/axios.ts +++ b/apps/client/src/libs/axios.ts @@ -2,7 +2,7 @@ import { t } from "@lingui/macro"; import { deepSearchAndParseDates, ErrorMessage } from "@reactive-resume/utils"; import _axios from "axios"; import createAuthRefreshInterceptor from "axios-auth-refresh"; -import { redirect } from "react-router-dom"; +import { redirect } from "react-router"; import { refreshToken } from "@/client/services/auth"; diff --git a/apps/client/src/main.tsx b/apps/client/src/main.tsx index 6190e31c..26f9e5ba 100644 --- a/apps/client/src/main.tsx +++ b/apps/client/src/main.tsx @@ -1,6 +1,6 @@ import { StrictMode } from "react"; import * as ReactDOM from "react-dom/client"; -import { RouterProvider } from "react-router-dom"; +import { RouterProvider } from "react-router"; import { router } from "./router"; diff --git a/apps/client/src/pages/auth/backup-otp/page.tsx b/apps/client/src/pages/auth/backup-otp/page.tsx index 606f7602..200d6743 100644 --- a/apps/client/src/pages/auth/backup-otp/page.tsx +++ b/apps/client/src/pages/auth/backup-otp/page.tsx @@ -16,7 +16,7 @@ import { import { useRef } from "react"; import { Helmet } from "react-helmet-async"; import { useForm } from "react-hook-form"; -import { useNavigate } from "react-router-dom"; +import { useNavigate } from "react-router"; import { z } from "zod"; import { useBackupOtp } from "@/client/services/auth"; @@ -39,7 +39,7 @@ export const BackupOtpPage = () => { try { await backupOtp(data); - navigate("/dashboard"); + void navigate("/dashboard"); } catch { form.reset(); } @@ -92,7 +92,7 @@ export const BackupOtpPage = () => { variant="link" className="px-5" onClick={() => { - navigate(-1); + void navigate(-1); }} > diff --git a/apps/client/src/pages/auth/forgot-password/page.tsx b/apps/client/src/pages/auth/forgot-password/page.tsx index ebad0d6d..1bc11fd2 100644 --- a/apps/client/src/pages/auth/forgot-password/page.tsx +++ b/apps/client/src/pages/auth/forgot-password/page.tsx @@ -17,7 +17,7 @@ import { import { useState } from "react"; import { Helmet } from "react-helmet-async"; import { useForm } from "react-hook-form"; -import { useNavigate } from "react-router-dom"; +import { useNavigate } from "react-router"; import { z } from "zod"; import { useForgotPassword } from "@/client/services/auth"; @@ -93,7 +93,7 @@ export const ForgotPasswordPage = () => { variant="link" className="px-5" onClick={() => { - navigate(-1); + void navigate(-1); }} > diff --git a/apps/client/src/pages/auth/layout.tsx b/apps/client/src/pages/auth/layout.tsx index 0f6c18ce..4a23e2d6 100644 --- a/apps/client/src/pages/auth/layout.tsx +++ b/apps/client/src/pages/auth/layout.tsx @@ -1,7 +1,7 @@ import { t } from "@lingui/macro"; import { cn } from "@reactive-resume/utils"; import { useMemo } from "react"; -import { Link, matchRoutes, Outlet, useLocation } from "react-router-dom"; +import { Link, matchRoutes, Outlet, useLocation } from "react-router"; import { LocaleSwitch } from "@/client/components/locale-switch"; import { Logo } from "@/client/components/logo"; diff --git a/apps/client/src/pages/auth/login/page.tsx b/apps/client/src/pages/auth/login/page.tsx index 708895aa..4204a888 100644 --- a/apps/client/src/pages/auth/login/page.tsx +++ b/apps/client/src/pages/auth/login/page.tsx @@ -20,7 +20,7 @@ import { cn } from "@reactive-resume/utils"; import { useRef } from "react"; import { Helmet } from "react-helmet-async"; import { useForm } from "react-hook-form"; -import { Link } from "react-router-dom"; +import { Link } from "react-router"; import { z } from "zod"; import { useLogin } from "@/client/services/auth"; diff --git a/apps/client/src/pages/auth/register/page.tsx b/apps/client/src/pages/auth/register/page.tsx index 5e7fe1fb..64451676 100644 --- a/apps/client/src/pages/auth/register/page.tsx +++ b/apps/client/src/pages/auth/register/page.tsx @@ -20,7 +20,7 @@ import { cn } from "@reactive-resume/utils"; import { useRef } from "react"; import { Helmet } from "react-helmet-async"; import { useForm } from "react-hook-form"; -import { Link, useNavigate } from "react-router-dom"; +import { Link, useNavigate } from "react-router"; import { z } from "zod"; import { useRegister } from "@/client/services/auth"; @@ -51,7 +51,7 @@ export const RegisterPage = () => { try { await register(data); - navigate("/auth/verify-email"); + void navigate("/auth/verify-email"); } catch { form.reset(); } diff --git a/apps/client/src/pages/auth/reset-password/page.tsx b/apps/client/src/pages/auth/reset-password/page.tsx index ed138eb9..ee868b4a 100644 --- a/apps/client/src/pages/auth/reset-password/page.tsx +++ b/apps/client/src/pages/auth/reset-password/page.tsx @@ -16,7 +16,7 @@ import { import { useEffect, useRef } from "react"; import { Helmet } from "react-helmet-async"; import { useForm } from "react-hook-form"; -import { useNavigate, useSearchParams } from "react-router-dom"; +import { useNavigate, useSearchParams } from "react-router"; import { z } from "zod"; import { useResetPassword } from "@/client/services/auth"; @@ -42,7 +42,7 @@ export const ResetPasswordPage = () => { try { await resetPassword(data); - navigate("/auth/login"); + void navigate("/auth/login"); } catch { form.reset(); } @@ -50,7 +50,7 @@ export const ResetPasswordPage = () => { // Redirect the user to the forgot password page if the token is not present. useEffect(() => { - if (!token) navigate("/auth/forgot-password"); + if (!token) void navigate("/auth/forgot-password"); }, [token, navigate]); return ( diff --git a/apps/client/src/pages/auth/verify-email/page.tsx b/apps/client/src/pages/auth/verify-email/page.tsx index 76ce2996..bc81a559 100644 --- a/apps/client/src/pages/auth/verify-email/page.tsx +++ b/apps/client/src/pages/auth/verify-email/page.tsx @@ -3,7 +3,7 @@ import { ArrowRight, Info, SealCheck } from "@phosphor-icons/react"; import { Alert, AlertDescription, AlertTitle, Button } from "@reactive-resume/ui"; import { useEffect } from "react"; import { Helmet } from "react-helmet-async"; -import { Link, useNavigate, useSearchParams } from "react-router-dom"; +import { Link, useNavigate, useSearchParams } from "react-router"; import { useToast } from "@/client/hooks/use-toast"; import { queryClient } from "@/client/libs/query-client"; @@ -28,7 +28,7 @@ export const VerifyEmailPage = () => { title: t`Your email address has been verified successfully.`, }); - navigate("/dashboard/resumes", { replace: true }); + void navigate("/dashboard/resumes", { replace: true }); }; if (!token) return; diff --git a/apps/client/src/pages/auth/verify-otp/page.tsx b/apps/client/src/pages/auth/verify-otp/page.tsx index 2ad06bcf..5f01e498 100644 --- a/apps/client/src/pages/auth/verify-otp/page.tsx +++ b/apps/client/src/pages/auth/verify-otp/page.tsx @@ -16,7 +16,7 @@ import { import { useRef } from "react"; import { Helmet } from "react-helmet-async"; import { useForm } from "react-hook-form"; -import { Link, useNavigate } from "react-router-dom"; +import { Link, useNavigate } from "react-router"; import { z } from "zod"; import { useVerifyOtp } from "@/client/services/auth"; @@ -39,7 +39,7 @@ export const VerifyOtpPage = () => { try { await verifyOtp(data); - navigate("/dashboard"); + void navigate("/dashboard"); } catch { form.reset(); } diff --git a/apps/client/src/pages/builder/_components/header.tsx b/apps/client/src/pages/builder/_components/header.tsx index 3650a26c..e3f55e2b 100644 --- a/apps/client/src/pages/builder/_components/header.tsx +++ b/apps/client/src/pages/builder/_components/header.tsx @@ -2,7 +2,7 @@ import { t } from "@lingui/macro"; import { HouseSimple, Lock, SidebarSimple } from "@phosphor-icons/react"; import { Button, Tooltip } from "@reactive-resume/ui"; import { cn } from "@reactive-resume/utils"; -import { Link } from "react-router-dom"; +import { Link } from "react-router"; import { useBuilderStore } from "@/client/stores/builder"; import { useResumeStore } from "@/client/stores/resume"; diff --git a/apps/client/src/pages/builder/layout.tsx b/apps/client/src/pages/builder/layout.tsx index c824ee9a..4d095520 100644 --- a/apps/client/src/pages/builder/layout.tsx +++ b/apps/client/src/pages/builder/layout.tsx @@ -1,7 +1,7 @@ import { useBreakpoint } from "@reactive-resume/hooks"; import { Panel, PanelGroup, PanelResizeHandle, Sheet, SheetContent } from "@reactive-resume/ui"; import { cn } from "@reactive-resume/utils"; -import { Outlet } from "react-router-dom"; +import { Outlet } from "react-router"; import { useBuilderStore } from "@/client/stores/builder"; diff --git a/apps/client/src/pages/builder/page.tsx b/apps/client/src/pages/builder/page.tsx index 85cb4756..babae226 100644 --- a/apps/client/src/pages/builder/page.tsx +++ b/apps/client/src/pages/builder/page.tsx @@ -2,7 +2,7 @@ import { t } from "@lingui/macro"; import { ResumeDto } from "@reactive-resume/dto"; import { useCallback, useEffect } from "react"; import { Helmet } from "react-helmet-async"; -import { LoaderFunction, redirect } from "react-router-dom"; +import { LoaderFunction, redirect } from "react-router"; import { queryClient } from "@/client/libs/query-client"; import { findResumeById } from "@/client/services/resume"; diff --git a/apps/client/src/pages/builder/sidebars/left/index.tsx b/apps/client/src/pages/builder/sidebars/left/index.tsx index f4d03474..9262b1b4 100644 --- a/apps/client/src/pages/builder/sidebars/left/index.tsx +++ b/apps/client/src/pages/builder/sidebars/left/index.tsx @@ -17,7 +17,7 @@ import { } from "@reactive-resume/schema"; import { Button, ScrollArea, Separator } from "@reactive-resume/ui"; import { Fragment, useRef } from "react"; -import { Link } from "react-router-dom"; +import { Link } from "react-router"; import { Icon } from "@/client/components/icon"; import { UserAvatar } from "@/client/components/user-avatar"; diff --git a/apps/client/src/pages/dashboard/_components/sidebar.tsx b/apps/client/src/pages/dashboard/_components/sidebar.tsx index 9d7229ca..a2f39381 100644 --- a/apps/client/src/pages/dashboard/_components/sidebar.tsx +++ b/apps/client/src/pages/dashboard/_components/sidebar.tsx @@ -3,7 +3,7 @@ import { FadersHorizontal, ReadCvLogo } from "@phosphor-icons/react"; import { Button, KeyboardShortcut, Separator } from "@reactive-resume/ui"; import { cn } from "@reactive-resume/utils"; import { motion } from "framer-motion"; -import { Link, useLocation, useNavigate } from "react-router-dom"; +import { Link, useLocation, useNavigate } from "react-router"; import useKeyboardShortcut from "use-keyboard-shortcut"; import { Copyright } from "@/client/components/copyright"; @@ -71,12 +71,12 @@ export const Sidebar = ({ setOpen }: SidebarProps) => { const navigate = useNavigate(); useKeyboardShortcut(["shift", "r"], () => { - navigate("/dashboard/resumes"); + void navigate("/dashboard/resumes"); setOpen?.(false); }); useKeyboardShortcut(["shift", "s"], () => { - navigate("/dashboard/settings"); + void navigate("/dashboard/settings"); setOpen?.(false); }); diff --git a/apps/client/src/pages/dashboard/layout.tsx b/apps/client/src/pages/dashboard/layout.tsx index 08c6cae1..a218b4fa 100644 --- a/apps/client/src/pages/dashboard/layout.tsx +++ b/apps/client/src/pages/dashboard/layout.tsx @@ -2,7 +2,7 @@ import { SidebarSimple } from "@phosphor-icons/react"; import { Button, Sheet, SheetClose, SheetContent, SheetTrigger } from "@reactive-resume/ui"; import { motion } from "framer-motion"; import { useState } from "react"; -import { Outlet } from "react-router-dom"; +import { Outlet } from "react-router"; import { Sidebar } from "./_components/sidebar"; diff --git a/apps/client/src/pages/dashboard/resumes/_dialogs/resume.tsx b/apps/client/src/pages/dashboard/resumes/_dialogs/resume.tsx index c2615960..2621e11f 100644 --- a/apps/client/src/pages/dashboard/resumes/_dialogs/resume.tsx +++ b/apps/client/src/pages/dashboard/resumes/_dialogs/resume.tsx @@ -43,7 +43,7 @@ import { useCreateResume, useDeleteResume, useUpdateResume } from "@/client/serv import { useImportResume } from "@/client/services/resume/import"; import { useDialog } from "@/client/stores/dialog"; -const formSchema = createResumeSchema.extend({ id: idSchema.optional() }); +const formSchema = createResumeSchema.extend({ id: idSchema.optional(), slug: z.string() }); type FormValues = z.infer; diff --git a/apps/client/src/pages/dashboard/resumes/_layouts/grid/_components/resume-card.tsx b/apps/client/src/pages/dashboard/resumes/_layouts/grid/_components/resume-card.tsx index 4eefd04c..e33835bc 100644 --- a/apps/client/src/pages/dashboard/resumes/_layouts/grid/_components/resume-card.tsx +++ b/apps/client/src/pages/dashboard/resumes/_layouts/grid/_components/resume-card.tsx @@ -18,7 +18,7 @@ import { import { cn } from "@reactive-resume/utils"; import dayjs from "dayjs"; import { AnimatePresence, motion } from "framer-motion"; -import { useNavigate } from "react-router-dom"; +import { useNavigate } from "react-router"; import { useDialog } from "@/client/stores/dialog"; @@ -37,7 +37,7 @@ export const ResumeCard = ({ resume }: Props) => { const lastUpdated = dayjs().to(resume.updatedAt); const onOpen = () => { - navigate(`/builder/${resume.id}`); + void navigate(`/builder/${resume.id}`); }; const onUpdate = () => { diff --git a/apps/client/src/pages/dashboard/resumes/_layouts/list/_components/resume-item.tsx b/apps/client/src/pages/dashboard/resumes/_layouts/list/_components/resume-item.tsx index 0e72a738..aa11d032 100644 --- a/apps/client/src/pages/dashboard/resumes/_layouts/list/_components/resume-item.tsx +++ b/apps/client/src/pages/dashboard/resumes/_layouts/list/_components/resume-item.tsx @@ -22,7 +22,7 @@ import { DropdownMenuTrigger, } from "@reactive-resume/ui"; import dayjs from "dayjs"; -import { useNavigate } from "react-router-dom"; +import { useNavigate } from "react-router"; import { useDialog } from "@/client/stores/dialog"; @@ -40,7 +40,7 @@ export const ResumeListItem = ({ resume }: Props) => { const lastUpdated = dayjs().to(resume.updatedAt); const onOpen = () => { - navigate(`/builder/${resume.id}`); + void navigate(`/builder/${resume.id}`); }; const onUpdate = () => { diff --git a/apps/client/src/pages/dashboard/settings/_sections/danger.tsx b/apps/client/src/pages/dashboard/settings/_sections/danger.tsx index 6db99f9e..6ae567e2 100644 --- a/apps/client/src/pages/dashboard/settings/_sections/danger.tsx +++ b/apps/client/src/pages/dashboard/settings/_sections/danger.tsx @@ -11,7 +11,7 @@ import { Input, } from "@reactive-resume/ui"; import { useForm } from "react-hook-form"; -import { useNavigate } from "react-router-dom"; +import { useNavigate } from "react-router"; import { useCounter } from "usehooks-ts"; import { z } from "zod"; @@ -52,7 +52,7 @@ export const DangerZoneSettings = () => { title: t`Your account and all your data has been deleted successfully. Goodbye!`, }); - navigate("/"); + void navigate("/"); } }; diff --git a/apps/client/src/pages/home/components/footer.tsx b/apps/client/src/pages/home/components/footer.tsx index 5e5c2df2..fb597d0e 100644 --- a/apps/client/src/pages/home/components/footer.tsx +++ b/apps/client/src/pages/home/components/footer.tsx @@ -1,6 +1,6 @@ import { t } from "@lingui/macro"; import { Separator } from "@reactive-resume/ui"; -import { Link } from "react-router-dom"; +import { Link } from "react-router"; import { Copyright } from "@/client/components/copyright"; import { LocaleSwitch } from "@/client/components/locale-switch"; diff --git a/apps/client/src/pages/home/components/header.tsx b/apps/client/src/pages/home/components/header.tsx index b104583c..9b997c67 100644 --- a/apps/client/src/pages/home/components/header.tsx +++ b/apps/client/src/pages/home/components/header.tsx @@ -1,5 +1,5 @@ import { motion } from "framer-motion"; -import { Link } from "react-router-dom"; +import { Link } from "react-router"; import { Logo } from "@/client/components/logo"; diff --git a/apps/client/src/pages/home/layout.tsx b/apps/client/src/pages/home/layout.tsx index 8da7057d..4329719e 100644 --- a/apps/client/src/pages/home/layout.tsx +++ b/apps/client/src/pages/home/layout.tsx @@ -1,5 +1,5 @@ import { ScrollArea } from "@reactive-resume/ui"; -import { Outlet } from "react-router-dom"; +import { Outlet } from "react-router"; import { Footer } from "./components/footer"; import { Header } from "./components/header"; diff --git a/apps/client/src/pages/home/sections/hero/call-to-action.tsx b/apps/client/src/pages/home/sections/hero/call-to-action.tsx index 5274c70c..92e823e4 100644 --- a/apps/client/src/pages/home/sections/hero/call-to-action.tsx +++ b/apps/client/src/pages/home/sections/hero/call-to-action.tsx @@ -1,7 +1,7 @@ import { t } from "@lingui/macro"; import { Book, SignOut } from "@phosphor-icons/react"; import { Button } from "@reactive-resume/ui"; -import { Link } from "react-router-dom"; +import { Link } from "react-router"; import { useLogout } from "@/client/services/auth"; import { useAuthStore } from "@/client/stores/auth"; diff --git a/apps/client/src/pages/public/page.tsx b/apps/client/src/pages/public/page.tsx index 1ae7ce2b..b1f08b76 100644 --- a/apps/client/src/pages/public/page.tsx +++ b/apps/client/src/pages/public/page.tsx @@ -5,7 +5,7 @@ import { Button } from "@reactive-resume/ui"; import { pageSizeMap } from "@reactive-resume/utils"; import { useCallback, useEffect, useRef } from "react"; import { Helmet } from "react-helmet-async"; -import { Link, LoaderFunction, redirect, useLoaderData } from "react-router-dom"; +import { Link, LoaderFunction, redirect, useLoaderData } from "react-router"; import { Icon } from "@/client/components/icon"; import { ThemeSwitch } from "@/client/components/theme-switch"; @@ -22,8 +22,8 @@ export const PublicResumePage = () => { const { printResume, loading } = usePrintResume(); - const { id, title, data: resume } = useLoaderData() as ResumeDto; - const format = resume.metadata.page.format; + const { id, title, data: resume } = useLoaderData(); + const format = resume.metadata.page.format as keyof typeof pageSizeMap; const updateResumeInFrame = useCallback(() => { if (!frameRef.current?.contentWindow) return; diff --git a/apps/client/src/providers/index.tsx b/apps/client/src/providers/index.tsx index a0e92a04..bb573ac7 100644 --- a/apps/client/src/providers/index.tsx +++ b/apps/client/src/providers/index.tsx @@ -1,7 +1,7 @@ import { TooltipProvider } from "@reactive-resume/ui"; import { QueryClientProvider } from "@tanstack/react-query"; import { HelmetProvider } from "react-helmet-async"; -import { Outlet } from "react-router-dom"; +import { Outlet } from "react-router"; import { helmetContext } from "../constants/helmet"; import { queryClient } from "../libs/query-client"; diff --git a/apps/client/src/router/guards/auth.tsx b/apps/client/src/router/guards/auth.tsx index c725f5e9..eeab3356 100644 --- a/apps/client/src/router/guards/auth.tsx +++ b/apps/client/src/router/guards/auth.tsx @@ -1,4 +1,4 @@ -import { Navigate, Outlet, useLocation } from "react-router-dom"; +import { Navigate, Outlet, useLocation } from "react-router"; import { useUser } from "@/client/services/user"; diff --git a/apps/client/src/router/guards/guest.tsx b/apps/client/src/router/guards/guest.tsx index 62abecd5..0d265024 100644 --- a/apps/client/src/router/guards/guest.tsx +++ b/apps/client/src/router/guards/guest.tsx @@ -1,4 +1,4 @@ -import { Navigate, Outlet, useSearchParams } from "react-router-dom"; +import { Navigate, Outlet, useSearchParams } from "react-router"; import { useAuthStore } from "@/client/stores/auth"; diff --git a/apps/client/src/router/index.tsx b/apps/client/src/router/index.tsx index a2525571..94b5b796 100644 --- a/apps/client/src/router/index.tsx +++ b/apps/client/src/router/index.tsx @@ -1,4 +1,4 @@ -import { createBrowserRouter, createRoutesFromElements, Navigate, Route } from "react-router-dom"; +import { createBrowserRouter, createRoutesFromElements, Navigate, Route } from "react-router"; import { BackupOtpPage } from "../pages/auth/backup-otp/page"; import { ForgotPasswordPage } from "../pages/auth/forgot-password/page"; @@ -23,7 +23,8 @@ import { GuestGuard } from "./guards/guest"; import { authLoader } from "./loaders/auth"; export const routes = createRoutesFromElements( - }> + // eslint-disable-next-line lingui/no-unlocalized-strings + } hydrateFallbackElement={
Loading...
}> }> } /> diff --git a/apps/client/src/router/loaders/auth.ts b/apps/client/src/router/loaders/auth.ts index a70c499c..021a83b5 100644 --- a/apps/client/src/router/loaders/auth.ts +++ b/apps/client/src/router/loaders/auth.ts @@ -1,5 +1,5 @@ import { authResponseSchema, UserDto } from "@reactive-resume/dto"; -import { LoaderFunction, redirect } from "react-router-dom"; +import { LoaderFunction, redirect } from "react-router"; import { USER_KEY } from "@/client/constants/query-keys"; import { queryClient } from "@/client/libs/query-client"; diff --git a/apps/client/src/services/auth/login.ts b/apps/client/src/services/auth/login.ts index 27142cf6..41c90ee2 100644 --- a/apps/client/src/services/auth/login.ts +++ b/apps/client/src/services/auth/login.ts @@ -1,7 +1,7 @@ import { AuthResponseDto, LoginDto } from "@reactive-resume/dto"; import { useMutation } from "@tanstack/react-query"; import { AxiosResponse } from "axios"; -import { useNavigate } from "react-router-dom"; +import { useNavigate } from "react-router"; import { axios } from "@/client/libs/axios"; import { queryClient } from "@/client/libs/query-client"; @@ -28,7 +28,7 @@ export const useLogin = () => { mutationFn: login, onSuccess: (data) => { if (data.status === "2fa_required") { - navigate("/auth/verify-otp"); + void navigate("/auth/verify-otp"); return; } diff --git a/libs/dto/package.json b/libs/dto/package.json index a88a3814..5c3cae28 100644 --- a/libs/dto/package.json +++ b/libs/dto/package.json @@ -14,6 +14,7 @@ "@sindresorhus/slugify": "^2.2.1", "nestjs-zod": "^3.0.0", "@swc/helpers": "~0.5.11", - "zod": "^3.24.1" + "zod": "^3.24.1", + "@paralleldrive/cuid2": "^2.2.2" } } diff --git a/libs/dto/src/resume/create.ts b/libs/dto/src/resume/create.ts index 2bebf05a..c371820b 100644 --- a/libs/dto/src/resume/create.ts +++ b/libs/dto/src/resume/create.ts @@ -1,3 +1,4 @@ +import { createId } from "@paralleldrive/cuid2"; import slugify from "@sindresorhus/slugify"; import { createZodDto } from "nestjs-zod/dto"; import { z } from "zod"; @@ -7,7 +8,11 @@ export const createResumeSchema = z.object({ slug: z .string() .min(1) - .transform((value) => slugify(value)) + .transform((value) => { + const slug = slugify(value); + if (!slug) return createId(); + return slug; + }) .optional(), visibility: z.enum(["public", "private"]).default("private"), }); diff --git a/libs/dto/src/resume/import.ts b/libs/dto/src/resume/import.ts index 702c3028..125418c0 100644 --- a/libs/dto/src/resume/import.ts +++ b/libs/dto/src/resume/import.ts @@ -1,3 +1,4 @@ +import { createId } from "@paralleldrive/cuid2"; import { resumeDataSchema } from "@reactive-resume/schema"; import slugify from "@sindresorhus/slugify"; import { createZodDto } from "nestjs-zod/dto"; @@ -8,7 +9,11 @@ export const importResumeSchema = z.object({ slug: z .string() .min(1) - .transform((value) => slugify(value)) + .transform((value) => { + const slug = slugify(value); + if (slug === "") return createId(); + return slug; + }) .optional(), visibility: z.enum(["public", "private"]).default("private").optional(), data: resumeDataSchema, diff --git a/libs/utils/src/namespaces/page.ts b/libs/utils/src/namespaces/page.ts index 44098150..8510e5b1 100644 --- a/libs/utils/src/namespaces/page.ts +++ b/libs/utils/src/namespaces/page.ts @@ -7,4 +7,4 @@ export const pageSizeMap = { width: 216, height: 279, }, -}; +} as const; diff --git a/package.json b/package.json index 2e0ae593..39bce427 100644 --- a/package.json +++ b/package.json @@ -224,7 +224,7 @@ "react-hook-form": "^7.54.2", "react-parallax-tilt": "^1.7.272", "react-resizable-panels": "^2.1.7", - "react-router-dom": "^6.28.1", + "react-router": "^7.1.1", "react-zoom-pan-pinch": "^3.6.1", "reflect-metadata": "^0.2.2", "rxjs": "^7.8.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 010eb404..85c54548 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -323,9 +323,9 @@ importers: react-resizable-panels: specifier: ^2.1.7 version: 2.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react-router-dom: - specifier: ^6.28.1 - version: 6.28.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-router: + specifier: ^7.1.1 + version: 7.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-zoom-pan-pinch: specifier: ^3.6.1 version: 3.6.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -3579,10 +3579,6 @@ packages: '@remirror/core-constants@3.0.0': resolution: {integrity: sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==} - '@remix-run/router@1.21.0': - resolution: {integrity: sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA==} - engines: {node: '>=14.0.0'} - '@rollup/pluginutils@5.1.4': resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} engines: {node: '>=14.0.0'} @@ -4235,6 +4231,9 @@ packages: peerDependencies: '@types/express': '*' + '@types/cookie@0.6.0': + resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + '@types/cookies@0.9.0': resolution: {integrity: sha512-40Zk8qR147RABiQ7NQnBzWzDcjKzNrntB5BAmeGCb2p/MIyOE+4BVvc17wumsUqUw00bJYqoXFHYygQnEFh4/Q==} @@ -5601,6 +5600,10 @@ packages: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} + cookie@1.0.2: + resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} + engines: {node: '>=18'} + cookies@0.9.1: resolution: {integrity: sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==} engines: {node: '>= 0.8'} @@ -9680,18 +9683,15 @@ packages: react: ^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc react-dom: ^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - react-router-dom@6.28.1: - resolution: {integrity: sha512-YraE27C/RdjcZwl5UCqF/ffXnZDxpJdk9Q6jw38SZHjXs7NNdpViq2l2c7fO7+4uWaEfcwfGCv3RSg4e1By/fQ==} - engines: {node: '>=14.0.0'} + react-router@7.1.1: + resolution: {integrity: sha512-39sXJkftkKWRZ2oJtHhCxmoCrBCULr/HAH4IT5DHlgu/Q0FCPV0S4Lx+abjDTx/74xoZzNYDYbOZWlJjruyuDQ==} + engines: {node: '>=20.0.0'} peerDependencies: - react: '>=16.8' - react-dom: '>=16.8' - - react-router@6.28.1: - resolution: {integrity: sha512-2omQTA3rkMljmrvvo6WtewGdVh45SpL9hGiCI9uUrwGGfNFDIvGK4gYJsKlJoNVi6AQZcopSCballL+QGOm7fA==} - engines: {node: '>=14.0.0'} - peerDependencies: - react: '>=16.8' + react: '>=18' + react-dom: '>=18' + peerDependenciesMeta: + react-dom: + optional: true react-style-singleton@2.2.1: resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} @@ -10073,6 +10073,9 @@ packages: resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} engines: {node: '>= 0.8.0'} + set-cookie-parser@2.7.1: + resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} + set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -10768,6 +10771,9 @@ packages: resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} engines: {node: '>=0.6.x'} + turbo-stream@2.4.0: + resolution: {integrity: sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -15223,8 +15229,6 @@ snapshots: '@remirror/core-constants@3.0.0': {} - '@remix-run/router@1.21.0': {} - '@rollup/pluginutils@5.1.4(rollup@4.30.1)': dependencies: '@types/estree': 1.0.6 @@ -15927,6 +15931,8 @@ snapshots: dependencies: '@types/express': 4.17.21 + '@types/cookie@0.6.0': {} + '@types/cookies@0.9.0': dependencies: '@types/connect': 3.4.38 @@ -17597,6 +17603,8 @@ snapshots: cookie@0.7.2: {} + cookie@1.0.2: {} + cookies@0.9.1: dependencies: depd: 2.0.0 @@ -22694,17 +22702,15 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-router-dom@6.28.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + react-router@7.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@remix-run/router': 1.21.0 + '@types/cookie': 0.6.0 + cookie: 1.0.2 react: 18.3.1 + set-cookie-parser: 2.7.1 + turbo-stream: 2.4.0 + optionalDependencies: react-dom: 18.3.1(react@18.3.1) - react-router: 6.28.1(react@18.3.1) - - react-router@6.28.1(react@18.3.1): - dependencies: - '@remix-run/router': 1.21.0 - react: 18.3.1 react-style-singleton@2.2.1(@types/react@18.3.18)(react@18.3.1): dependencies: @@ -23153,6 +23159,8 @@ snapshots: transitivePeerDependencies: - supports-color + set-cookie-parser@2.7.1: {} + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -23973,6 +23981,8 @@ snapshots: tsscmp@1.0.6: {} + turbo-stream@2.4.0: {} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1