Skip to content

Commit

Permalink
Merge pull request #75 from websitesieutoc/make-crud-for-pages
Browse files Browse the repository at this point in the history
Make crud for pages
  • Loading branch information
sangdth authored Sep 13, 2023
2 parents f72893b + 57e4ee4 commit 0469dd2
Show file tree
Hide file tree
Showing 41 changed files with 761 additions and 190 deletions.
4 changes: 2 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
NEXTAUTH_SECRET=topsecret
ARGON_SECRET=topsecret
SITE_DOMAIN=localhost:3000
NEXTAUTH_SECRET=topsecret
NEXTAUTH_URL=http://localhost:3000

KV_REST_API_URL=
KV_REST_API_TOKEN=
Expand Down
35 changes: 5 additions & 30 deletions app/[locale]/(auth)/login/LoginForm/index.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
'use client';
import {
Input,
VStack,
Divider,
Button,
FormLabel,
FormControl,
} from '@/components/chakra';
import { useAuth, useEffect, useMemo, useState, useRouter } from '@/hooks';
import { getProviders, signIn } from 'next-auth/react';

import { Input, Button, FormLabel, FormControl } from '@/components/chakra';
import { useAuth, useEffect, useState, useRouter } from '@/hooks';
import { signIn } from 'next-auth/react';
import { NextLink } from '@/components/client';

export default function LoginForm() {
const router = useRouter();
const providers = useMemo(async () => await getProviders(), []);
const { isAuthenticated } = useAuth();
const [credentials, setCredentials] = useState({
email: '',
Expand All @@ -34,27 +27,9 @@ export default function LoginForm() {
router.back();
}
}, [isAuthenticated, router]);

return (
<>
<VStack>
{Object.values(providers)
.filter((p) => p.name !== 'Credentials')
.map((provider) => (
<Button
key={provider.name}
width="100%"
colorScheme="gray"
onClick={() =>
signIn(provider.id, { callbackUrl: getCallbackUrl() })
}
>
Sign in with {provider.name}
</Button>
))}
</VStack>

<Divider />

<FormControl
isRequired
isInvalid={credentials.email.length > 0 && !validEmail}
Expand Down
3 changes: 2 additions & 1 deletion app/[locale]/(custom)/blog/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Box, Heading } from '@/components/chakra';
import { prisma } from '@/utils/prisma';

type PagePostProps = {
params: { slug: string };
Expand All @@ -7,7 +8,7 @@ type PagePostProps = {

export default async function PagePost({ params }: PagePostProps) {
const { slug } = params;
const data = await prisma?.post.findUnique({ where: { id: slug } });
const data = await prisma.post.findUnique({ where: { id: slug } });
if (!data) return <>Post not found!</>;
return (
<Box>
Expand Down
18 changes: 7 additions & 11 deletions app/[locale]/(custom)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Box, Flex, HStack } from '@/components/chakra';
import { Navbar } from '@/components/client';
import { LocaleSwitcher, ProfileMenu } from '@/components/server';
import { LocaleSwitcher, Navbar } from '@/components/client';
import { Box, Flex } from '@/components/chakra';
import { ProfileMenu } from '@/components/server';
import type { ReactNode } from '@/types';
import type { Locale } from '@/configs/i18n.config';

Expand All @@ -14,14 +14,10 @@ export default function CustomLayout({
return (
<Flex direction="column">
<Navbar>
<HStack spacing={1}>
<Box>
<LocaleSwitcher locale={params.locale} />
</Box>
<Box>
<ProfileMenu />
</Box>
</HStack>
<Flex gap={1}>
<LocaleSwitcher locale={params.locale} />
<ProfileMenu />
</Flex>
</Navbar>

<Box padding={6} width="100%" height="100vh" overflowY="scroll">
Expand Down
3 changes: 0 additions & 3 deletions app/[locale]/(default)/dashboard/dashboard/files/page.tsx

This file was deleted.

12 changes: 0 additions & 12 deletions app/[locale]/(default)/dashboard/dashboard/pages/AddPageButton.tsx

This file was deleted.

38 changes: 0 additions & 38 deletions app/[locale]/(default)/dashboard/dashboard/pages/page.tsx

This file was deleted.

3 changes: 0 additions & 3 deletions app/[locale]/(default)/dashboard/dashboard/posts/page.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion app/[locale]/(default)/dashboard/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export default function DashboardPage() {
return 'dashboard will be here';
return 'dashboard overview will be here';
}
12 changes: 0 additions & 12 deletions app/[locale]/(default)/dashboard/pages/AddPageButton.tsx

This file was deleted.

32 changes: 32 additions & 0 deletions app/[locale]/(default)/dashboard/pages/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Flex, Heading, Spinner, Stack } from '@/components/chakra';
import { GoBackButton } from '@/components/client';
import { prisma } from '@/utils/prisma';
import { Suspense } from 'react';

import { PageForm } from '../components';

type EditPageProps = {
params: { id: string };
};

export default async function EditPage({ params }: EditPageProps) {
const { id } = params;

const data = await prisma.page.findUnique({ where: { id } });

return (
<Flex direction="column">
<Stack direction="row" align="center">
<GoBackButton path="/dashboard/pages" />

<Heading as="h3" size="lg" alignItems="center" color="gray">
Edit Page
</Heading>
</Stack>

<Suspense fallback={<Spinner />}>
{data && <PageForm data={data} />}
</Suspense>
</Flex>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import {
AlertDialog,
AlertDialogBody,
AlertDialogCloseButton,
AlertDialogContent,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogOverlay,
Button,
Card,
CardBody,
CardFooter,
CardHeader,
Divider,
Flex,
FormControl,
FormLabel,
Heading,
Input,
Skeleton,
Stack,
Text,
} from '@/components/chakra';
import {
useColorModeValue,
useDisclosure,
useRef,
useRouter,
useState,
useToast,
} from '@/hooks';
import { deletePage } from '@/services/pages';
import type { Page } from '@/types';

export type PageDeleteSectionProps = {
page: Page;
};

export const DeleteSection = ({ page }: PageDeleteSectionProps) => {
const [isLoading, setIsLoading] = useState(false);
const router = useRouter();
const toast = useToast();
const cancelRef = useRef(null);

const { isOpen, onOpen, onClose } = useDisclosure();

const [confirmText, setConfirmText] = useState('');

const pageId = page?.id ?? '';

const handleCancel = () => {
setConfirmText('');
onClose();
};

const handleDelete = async () => {
try {
if (!page) return;

setIsLoading(true);

await deletePage(pageId);

toast({ description: 'Delete successfully' });

setIsLoading(false);

onClose();

router.refresh();
router.push('/dashboard/pages');
} catch (error: any) {
toast({ status: 'error', title: `Error: ${error.message}` });
}
};

const backgroundColor = useColorModeValue('red.50', 'red.900');
const footerBorder = useColorModeValue('red.100', 'red.600');

if (!pageId) {
return <Skeleton height="40px" />;
}

return (
<>
<Card bg={backgroundColor} direction="column" width="100%">
<CardHeader>
<Heading size="md">Delete Page</Heading>
</CardHeader>

<CardBody>
<Stack spacing={6} maxW="480px" minW="240px">
<Text>
The page will be permanently deleted. This action is irreversible
and can not be undone.
</Text>
</Stack>
</CardBody>

<Divider color={footerBorder} />

<CardFooter>
<Flex width="100%" direction="row" justify="end">
<Button
colorScheme="red"
isDisabled={isLoading}
isLoading={isLoading}
onClick={onOpen}
>
Delete
</Button>
</Flex>
</CardFooter>
</Card>

<AlertDialog
motionPreset="slideInBottom"
leastDestructiveRef={cancelRef}
onClose={onClose}
isOpen={isOpen}
isCentered
>
<AlertDialogOverlay />

<AlertDialogContent>
<AlertDialogHeader>Are you sure?</AlertDialogHeader>
<AlertDialogCloseButton />
<AlertDialogBody>
<FormControl>
<FormLabel>
Confirm by typing:{' '}
<Text as="span" fontWeight="bold">
YES
</Text>
</FormLabel>
<Input
placeholder="YES"
value={confirmText ?? ''}
onChange={(event) => setConfirmText(event.target.value)}
/>
</FormControl>
</AlertDialogBody>
<AlertDialogFooter>
<Stack direction="row" spacing={3}>
<Button
ref={cancelRef}
isDisabled={isLoading}
onClick={handleCancel}
>
Cancel
</Button>
<Button
isLoading={isLoading}
isDisabled={confirmText !== 'YES' || isLoading}
colorScheme="red"
onClick={handleDelete}
>
Yes, delete it
</Button>
</Stack>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</>
);
};
Loading

0 comments on commit 0469dd2

Please sign in to comment.