forked from cruip/tailwind-landing-page-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4a15fe5
commit bc09449
Showing
18 changed files
with
5,812 additions
and
559 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
'use client' | ||
|
||
import React from 'react' | ||
import "react-datepicker/dist/react-datepicker.css"; | ||
import ScrollToTop from "react-scroll-to-top"; | ||
import {Button} from "@nextui-org/button"; | ||
import {Input} from "@nextui-org/input"; | ||
import {useForm, Controller} from "react-hook-form"; | ||
import 'react-quill/dist/quill.snow.css'; | ||
import ReactQuill from 'react-quill'; | ||
import DatePicker from "react-datepicker"; | ||
import moment from "moment/moment"; | ||
import {useParams} from "next/navigation"; | ||
|
||
export default function ListPage() { | ||
const { | ||
register, | ||
handleSubmit, | ||
control, | ||
watch, | ||
reset, | ||
formState: {errors}, | ||
} = useForm({ | ||
mode: "onBlur", | ||
defaultValues: { | ||
name: "", | ||
publish_at: undefined, | ||
content: "", | ||
thumbnail: "", | ||
}, | ||
}); | ||
|
||
const params = useParams(); | ||
const type = params['slug']; | ||
|
||
const onSubmit = async (data: any) => { | ||
data.publish_at = moment(data.publish_at).format("x"); | ||
const res = await fetch('/admin/api', { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
body: JSON.stringify({type, data}), | ||
}) | ||
|
||
}; | ||
|
||
const inputRegister = register("name", {required: true}); | ||
|
||
return ( | ||
<main className="grow"> | ||
<section className="relative"> | ||
<div className="relative max-w-6xl mx-auto px-4 sm:px-6"> | ||
<div className="py-12 md:py-20"> | ||
{/* Section header */} | ||
<div className="max-w-3xl mx-auto text-center pb-2 md:pb-2"> | ||
<h1 className="h2 mb-4 text-3xl">Thêm mới</h1> | ||
</div> | ||
|
||
{/* Section content */} | ||
<form | ||
onSubmit={handleSubmit(onSubmit)} | ||
className="flex flex-col items-start gap-4" | ||
> | ||
<div className="flex flex-col mt-4 w-full gap-4"> | ||
<Input | ||
label="Tên bài viết" | ||
placeholder="Nhập tên bài viết" | ||
variant="bordered" | ||
errorMessage={errors.name && "Tên yêu cầu"} | ||
radius={'md'} | ||
// @ts-ignore | ||
validationState={errors.name ? "invalid" : "valid"} | ||
{...inputRegister} | ||
/> | ||
|
||
<Controller | ||
name="publish_at" | ||
control={control} | ||
rules={{required: true}} | ||
render={({field}) => { | ||
return <DatePicker | ||
showIcon | ||
className="border w-full rounded-md" | ||
selected={field.value} | ||
placeholderText="Ngày đăng" | ||
{...field} | ||
/> | ||
}} | ||
/> | ||
|
||
<Controller | ||
name="content" | ||
control={control} | ||
rules={{required: true}} | ||
render={({field}) => <ReactQuill theme="snow" {...field} className={'h-96'} modules={{ | ||
toolbar: [ | ||
[{'header': [1, 2, false]}], | ||
['bold', 'italic', 'underline', 'strike', 'blockquote'], | ||
[{'list': 'ordered'}, {'list': 'bullet'}, {'indent': '-1'}, {'indent': '+1'}], | ||
['link', 'image'], | ||
['clean'] | ||
], | ||
}}/>} | ||
/> | ||
</div> | ||
<div className="flex items-center gap-4"> | ||
<Button | ||
color="primary" | ||
variant="bordered" | ||
type="submit" | ||
className="mt-10 shadow-sm hover:bg-blue-500 hover:text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600" | ||
> | ||
Save | ||
</Button> | ||
</div> | ||
</form> | ||
|
||
</div> | ||
</div> | ||
</section> | ||
<ScrollToTop smooth color={'rgb(51 140 245)'}/> | ||
</main> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
'use client' | ||
|
||
import {useEffect, useState} from "react"; | ||
import {useParams} from 'next/navigation' | ||
import {useSession} from "next-auth/react"; | ||
import ScrollToTop from "react-scroll-to-top"; | ||
import List from "@/components/admin/list"; | ||
import {Spinner} from "@nextui-org/spinner"; | ||
|
||
export default function ListPage() { | ||
const {data: session} = useSession(); | ||
const [list, setList] = useState<[]>([]); | ||
const [loading, setLoading] = useState(true); | ||
|
||
const params = useParams(); | ||
const type = params['slug']; | ||
|
||
// This code inside useEffect will run when the component is mounted | ||
useEffect(() => { | ||
const fetchData = async () => { | ||
const res = await fetch(`/admin/api?type=${type}`); | ||
|
||
return await res.json(); | ||
} | ||
|
||
if (session?.user) { | ||
fetchData().then(res => { | ||
setList(res) | ||
setLoading(false); | ||
}); | ||
} | ||
}, [session]); | ||
|
||
if (loading) { | ||
return <main className="grow"> | ||
<section className="relative"> | ||
<div className="relative max-w-6xl mx-auto px-4 sm:px-6"> | ||
<div className="py-12 md:py-20 text-center"> | ||
<Spinner label="Loading" color="primary" labelColor="primary"/> | ||
</div> | ||
</div> | ||
</section> | ||
</main> | ||
} | ||
|
||
return ( | ||
<main className="grow"> | ||
<section className="relative"> | ||
<div className="relative max-w-6xl mx-auto px-4 sm:px-6"> | ||
<div className="py-12 md:py-20"> | ||
{/* Section header */} | ||
<div className="max-w-3xl mx-auto text-center pb-2 md:pb-2"> | ||
<h1 className="h2 mb-4 text-3xl">Danh sách {type === 'news' ? 'tin tức' : 'dự án'}</h1> | ||
</div> | ||
|
||
{/* Section content */} | ||
// @ts-ignore | ||
<List data={list} type={type}/> | ||
</div> | ||
</div> | ||
</section> | ||
<ScrollToTop smooth color={'rgb(51 140 245)'}/> | ||
</main> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import {type NextRequest, type NextResponse} from 'next/server' | ||
import dbConnect from "@/lib/dbConnect"; | ||
import News from "@/models/News"; | ||
import Project from "@/models/Project"; | ||
|
||
export async function GET(req: NextRequest) { | ||
const searchParams = req.nextUrl.searchParams | ||
const type = searchParams.get('type') | ||
|
||
await dbConnect(); | ||
|
||
if (type === 'news') { | ||
const data = await News.find({}); | ||
return new Response(JSON.stringify(data), { | ||
status: 200, | ||
}) | ||
} | ||
|
||
const data = await Project.find({}); | ||
|
||
return new Response(JSON.stringify(data), { | ||
status: 200, | ||
}) | ||
} | ||
|
||
export async function POST(req: NextRequest, res: NextResponse) { | ||
const {data, type} = await req.json() | ||
|
||
await dbConnect(); | ||
|
||
if (type === 'news') { | ||
await News.create(data); | ||
} else { | ||
await Project.create(data); | ||
} | ||
|
||
return new Response('Successfully', { | ||
status: 200, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import React from "react"; | ||
|
||
export default function AdminLayout({children}: { | ||
children: React.ReactNode; | ||
}) { | ||
return ( | ||
<> | ||
{children} | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import React from "react"; | ||
import {getServerSession} from "next-auth/next"; | ||
import {config} from "@/auth"; | ||
import Link from "next/link"; | ||
import {Button} from "@nextui-org/button"; | ||
|
||
export default async function AdminPage() { | ||
const session = await getServerSession(config); | ||
|
||
if (!session) { | ||
return <main className="grow"> | ||
<section className="relative"> | ||
<div className="relative max-w-6xl mx-auto px-4 sm:px-6"> | ||
<div className="py-20 md:pt-20"> | ||
<div className="max-w-3xl mx-auto text-center pb-2 md:pb-2"> | ||
<Button | ||
href={'/api/auth/signin'} | ||
as={Link} | ||
color="primary" | ||
variant="bordered" | ||
className={'shadow-sm hover:bg-blue-500 hover:text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600'} | ||
> | ||
Đăng nhập | ||
</Button> | ||
</div> | ||
</div> | ||
</div> | ||
</section> | ||
</main> | ||
} | ||
|
||
return ( | ||
<main className="grow"> | ||
<section className="relative"> | ||
<div className="relative max-w-6xl mx-auto px-4 sm:px-6"> | ||
<div className="py-20 md:pt-20"> | ||
<div className="max-w-3xl mx-auto text-center pb-2 md:pb-2"> | ||
<h1 className="h2 mb-4 text-3xl font-bold">Xin chào, {session?.user?.name}</h1> | ||
<p className="text-xl text-gray-600" data-aos="fade-up">Chào mừng đến với trang quản lý của Little Universe</p> | ||
</div> | ||
{/* Section content */} | ||
|
||
</div> | ||
</div> | ||
</section> | ||
</main> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.