diff --git a/apps/resources/app/(home)/page.tsx b/apps/resources/app/(home)/page.tsx index e7f60129..2fec1343 100644 --- a/apps/resources/app/(home)/page.tsx +++ b/apps/resources/app/(home)/page.tsx @@ -1,22 +1,16 @@ -import { Page } from 'components/Page/Page'; -import { SearchParams } from 'lib/types'; import { NewResources } from '../../components/NewResources/NewResources'; import { Newsletter } from '../../components/Newsletter/Newsletter'; import { About } from './About/About'; import { Header } from './Header/Header'; -interface Props { - searchParams: SearchParams; -} - -const Home = ({ searchParams }: Props) => { +const Home = () => { return ( - + <>
- + ); }; diff --git a/apps/resources/app/collections/[id]/page.tsx b/apps/resources/app/collections/[id]/page.tsx index 2ea7d057..5387d0f9 100644 --- a/apps/resources/app/collections/[id]/page.tsx +++ b/apps/resources/app/collections/[id]/page.tsx @@ -1,12 +1,11 @@ import { auth } from '@clerk/nextjs'; import { Resources } from 'app/resources/Resources/Resources'; import { Await } from 'components/Await/Await'; -import { Page } from 'components/Page/Page'; -import { Heading, Text } from 'design-system'; +import { UpdateCollectionDialog } from 'components/Collections/UpdateCollectionDialog/UpdateCollectionDialog'; +import { Button, Heading, Text } from 'design-system'; import { getCollectionCached } from 'lib/cache'; import { SearchParams } from 'lib/types'; import { DeleteCollectionButton } from '../../../components/Collections/DeleteCollectionButton/DeleteCollectionButton'; -import { UpdateBollectionButton } from '../../../components/Collections/UpdateBollectionButton'; interface Props { params: { @@ -21,12 +20,14 @@ const CollectionPage = async ({ params, searchParams }: Props) => { const { userId } = auth(); return ( - + <>
Collection Page {userId && (
- + + +
)} @@ -69,7 +70,7 @@ const CollectionPage = async ({ params, searchParams }: Props) => { ); }} - + ); }; diff --git a/apps/resources/app/collections/page.tsx b/apps/resources/app/collections/page.tsx index e0d66b44..692159c9 100644 --- a/apps/resources/app/collections/page.tsx +++ b/apps/resources/app/collections/page.tsx @@ -1,23 +1,21 @@ import { auth } from '@clerk/nextjs'; import { Await } from 'components/Await/Await'; -import { Page } from 'components/Page/Page'; -import { Heading, Text } from 'design-system'; +import { AddCollectionDialog } from 'components/Collections/AddCollectionDialog/AddCollectionDialog'; +import { Button, Heading, Text } from 'design-system'; import { getCollectionsCached } from 'lib/cache'; -import { SearchParams } from 'lib/types'; import Link from 'next/link'; -import { AddCollectionButton } from '../../components/Collections/AddCollectionButton'; -interface Props { - searchParams: SearchParams; -} - -const CollectionsPage = async ({ searchParams }: Props) => { +const CollectionsPage = async () => { const promise = getCollectionsCached(); const { userId } = auth(); return ( - + <> Collections - {userId && } + {userId && ( + + + + )} {(collections) => { return ( @@ -39,7 +37,7 @@ const CollectionsPage = async ({ searchParams }: Props) => { ); }} - + ); }; diff --git a/apps/resources/app/imprint/page.tsx b/apps/resources/app/imprint/page.tsx index ea7e1bc1..f749c709 100644 --- a/apps/resources/app/imprint/page.tsx +++ b/apps/resources/app/imprint/page.tsx @@ -1,31 +1,23 @@ -import { Page } from 'components/Page/Page'; import { allPages } from 'contentlayer/generated'; import { Heading } from 'design-system'; -import { SearchParams } from 'lib/types'; import { Metadata } from 'next'; export const metadata: Metadata = { title: 'Imprint', }; -interface Props { - searchParams: SearchParams; -} - -const ImprintPage = ({ searchParams }: Props) => { +const ImprintPage = () => { const content = allPages.find((page) => page.title === 'Imprint'); return ( - -
- - {content?.title} - -
-
-
+
+ + {content?.title} + +
+
); }; diff --git a/apps/resources/app/privacy/page.tsx b/apps/resources/app/privacy/page.tsx index 1f79f9bf..64e8f2ad 100644 --- a/apps/resources/app/privacy/page.tsx +++ b/apps/resources/app/privacy/page.tsx @@ -1,31 +1,23 @@ -import { Page } from 'components/Page/Page'; import { allPages } from 'contentlayer/generated'; import { Heading } from 'design-system'; -import { SearchParams } from 'lib/types'; import { Metadata } from 'next'; export const metadata: Metadata = { title: 'Privacy Policy', }; -interface Props { - searchParams: SearchParams; -} - -const PrivacyPage = ({ searchParams }: Props) => { +const PrivacyPage = () => { const content = allPages.find((page) => page.title === 'Privacy'); return ( - -
- - {content?.title} - -
-
-
+
+ + {content?.title} + +
+
); }; diff --git a/apps/resources/app/profile/page.tsx b/apps/resources/app/profile/page.tsx index d14863da..b63df679 100644 --- a/apps/resources/app/profile/page.tsx +++ b/apps/resources/app/profile/page.tsx @@ -4,45 +4,37 @@ import { SignedOut, UserProfile, } from '@clerk/nextjs'; -import { Page } from 'components/Page/Page'; import { Heading } from 'design-system'; -import { SearchParams } from 'lib/types'; import { DeleteAccountButton } from './DeleteAccountButton'; -interface Props { - searchParams: SearchParams; -} - -const ProfilePage = ({ searchParams }: Props) => { +const ProfilePage = () => { return ( - -
- - Profile - - +
+ + Profile + + +
+
- -
- -
+
- - - - -
- +
+ + + + + ); }; diff --git a/apps/resources/app/resources/[slug]/page.tsx b/apps/resources/app/resources/[slug]/page.tsx index 3bce480e..65d60f17 100644 --- a/apps/resources/app/resources/[slug]/page.tsx +++ b/apps/resources/app/resources/[slug]/page.tsx @@ -1,5 +1,3 @@ -import { Page } from 'components/Page/Page'; -import { SearchParams } from 'lib/types'; import { Comments } from '../../../components/Comments/Comments'; import { NewResources } from '../../../components/NewResources/NewResources'; import { Newsletter } from '../../../components/Newsletter/Newsletter'; @@ -57,21 +55,20 @@ interface Props { params: { slug: string; }; - searchParams: SearchParams; } -const ResourcePage = async ({ params, searchParams }: Props) => { +const ResourcePage = async ({ params }: Props) => { const { slug } = params; const { resourceId, resourceType } = parseResourceSlug(slug); return ( - + <> - + ); }; diff --git a/apps/resources/app/resources/page.tsx b/apps/resources/app/resources/page.tsx index 7d7df244..18c602b6 100644 --- a/apps/resources/app/resources/page.tsx +++ b/apps/resources/app/resources/page.tsx @@ -1,4 +1,3 @@ -import { Page } from 'components/Page/Page'; import { SearchParams } from 'lib/types'; import { Metadata } from 'next'; import { Resources } from './Resources/Resources'; @@ -14,10 +13,10 @@ interface Props { const ResourcesPage = ({ searchParams }: Props) => { return ( - + <> - + ); }; diff --git a/apps/resources/app/sign-in/[[...sign-in]]/page.tsx b/apps/resources/app/sign-in/[[...sign-in]]/page.tsx index 1c220a4d..4947c7c6 100644 --- a/apps/resources/app/sign-in/[[...sign-in]]/page.tsx +++ b/apps/resources/app/sign-in/[[...sign-in]]/page.tsx @@ -1,44 +1,36 @@ import { SignIn } from '@clerk/nextjs'; -import { Page } from 'components/Page/Page'; import { Heading } from 'design-system'; -import { SearchParams } from 'lib/types'; -interface Props { - searchParams: SearchParams; -} - -const SignInPage = ({ searchParams }: Props) => { +const SignInPage = () => { return ( - -
- - Sign in - -
- -
-
-
+
+ + Sign in + +
+ +
+
); }; diff --git a/apps/resources/app/sign-up/[[...sign-up]]/page.tsx b/apps/resources/app/sign-up/[[...sign-up]]/page.tsx index fe2a6137..5a0e486d 100644 --- a/apps/resources/app/sign-up/[[...sign-up]]/page.tsx +++ b/apps/resources/app/sign-up/[[...sign-up]]/page.tsx @@ -1,52 +1,44 @@ import { SignUp } from '@clerk/nextjs'; -import { Page } from 'components/Page/Page'; import { Heading, Link, Text } from 'design-system'; -import { SearchParams } from 'lib/types'; -interface Props { - searchParams: SearchParams; -} - -const SignUpPage = ({ searchParams }: Props) => { +const SignUpPage = () => { return ( - -
- - Sign up - - - Sign up for an account to be able to use personalized features like - liking resources and more. - -
- -
- - With your registration you declare to have read and to agree with our{' '} - privacy policy. - -
-
+
+ + Sign up + + + Sign up for an account to be able to use personalized features like + liking resources and more. + +
+ +
+ + With your registration you declare to have read and to agree with our{' '} + privacy policy. + +
); }; diff --git a/apps/resources/components/Card/CollectionButton.tsx b/apps/resources/components/Card/CollectionButton.tsx index b4b47a5c..683f7428 100644 --- a/apps/resources/components/Card/CollectionButton.tsx +++ b/apps/resources/components/Card/CollectionButton.tsx @@ -1,7 +1,8 @@ 'use client'; -import { AddToCollectionButton } from 'components/Collections/AddToCollectionButton'; +import { AddToCollectionDialog } from 'components/Collections/AddToCollectionDialog/AddToCollectionDialog'; import { AddToThisCollectionButton } from 'components/Collections/AddToThisCollectionButton'; +import { Button } from 'design-system'; import { ContentType } from 'lib/resources'; import { usePathname } from 'next/navigation'; @@ -26,10 +27,12 @@ export const CollectionButton = ({ resourceId, resourceType }: Props) => { resourceType={resourceType} /> ) : ( - + > + + )} ); diff --git a/apps/resources/components/Collections/AddCollectionButton.tsx b/apps/resources/components/Collections/AddCollectionButton.tsx deleted file mode 100644 index 7aecb528..00000000 --- a/apps/resources/components/Collections/AddCollectionButton.tsx +++ /dev/null @@ -1,18 +0,0 @@ -'use client'; - -import { useServerDialog } from 'components/ServerDialog/useServerDialog'; -import { Button } from 'design-system'; - -export const AddCollectionButton = () => { - const { openDialog, isPending } = useServerDialog(); - return ( - - ); -}; diff --git a/apps/resources/components/Collections/AddCollectionDialog/AddCollectionDialog.tsx b/apps/resources/components/Collections/AddCollectionDialog/AddCollectionDialog.tsx index b040ceac..2ead9837 100644 --- a/apps/resources/components/Collections/AddCollectionDialog/AddCollectionDialog.tsx +++ b/apps/resources/components/Collections/AddCollectionDialog/AddCollectionDialog.tsx @@ -1,22 +1,141 @@ -import { ServerDialogRoot } from 'components/ServerDialog/ServerDialogRoot'; +'use client'; + +import { cva } from 'class-variance-authority'; import { + Button, + Dialog, DialogContent, DialogOverlay, DialogPortal, + DialogTrigger, Heading, + InfoBox, } from 'design-system'; -import { AddCollectionForm } from './AddCollectionForm'; +import { useZodForm } from 'hooks/useZodForm'; +import { useAction } from 'lib/serverActions/client'; +import { AlertTriangle, Loader2, MessageCircle } from 'lucide-react'; +import { ReactNode, useState } from 'react'; +import { SubmitHandler } from 'react-hook-form'; +import { addCollection } from './actions'; +import { AddCollectionSchema, addCollectionSchema } from './schemas'; + +const inputStyles = cva( + 'px-8 py-4 text-base text-text-secondary bg-ghost-main-dark-bg outline-none w-full ring-inset', + { + variants: { + error: { + true: 'ring-2 ring-red-700', + false: 'focus-visible:ring-2 focus-visible:ring-ghost-contrast-text', + }, + }, + }, +); + +const errorStyles = + 'absolute left-0 bottom-0 -mb-4 text-red-700 text-sm slide-in-from-top-full duration-100 ease-in-out fade-in animate-in'; + +interface Props { + children: ReactNode; + goToCollection?: boolean; + onChange?: () => void; +} + +export const AddCollectionDialog = ({ + children, + goToCollection = true, + onChange, +}: Props) => { + const [open, setOpen] = useState(false); + const { error, runAction, isRunning } = useAction(addCollection, { + onSuccess: () => { + setOpen(false); + }, + onSettled: onChange, + }); + const { + register, + handleSubmit, + formState: { errors }, + } = useZodForm({ + schema: addCollectionSchema, + }); + + const onSubmit: SubmitHandler = async ({ + title, + description, + }) => { + await runAction({ + title, + description, + goToCollection, + }); + }; -export const AddCollectionDialog = () => { return ( - + + {children} Add Collection - +
+ {/* Title input */} +
+ + + {errors.title && ( +

{errors.title.message}

+ )} +
+ + {/* Description input */} +
+ +