implemented post management dashboard and started work on projects
This commit is contained in:
75
src/app/admin/[...slug]/page.tsx
Normal file
75
src/app/admin/[...slug]/page.tsx
Normal file
@@ -0,0 +1,75 @@
|
||||
'use server'
|
||||
import { getCookieAuth } from "@/app/lib/actions";
|
||||
import AdminPanel from "@/components/server/admin/adminPanel";
|
||||
import ServerAdminPanel from "@/components/server/admin/ServerAdminPanel";
|
||||
import AuthHandler from "@/components/server/admin/authHandler";
|
||||
import Sidebar from "@/components/server/admin/views/sidebar";
|
||||
import { cookies } from "next/headers";
|
||||
import PostView from "@/components/server/admin/views/PostView";
|
||||
import { ReactNode } from "react";
|
||||
|
||||
type Props = {
|
||||
params: {
|
||||
slug: string[]
|
||||
};
|
||||
}
|
||||
|
||||
export type SidebarEntry = {
|
||||
label:string;
|
||||
view:string;
|
||||
}
|
||||
|
||||
|
||||
function Home(){
|
||||
return <div>home</div>
|
||||
}
|
||||
function PostManager(){
|
||||
return <div>posts</div>
|
||||
}
|
||||
|
||||
|
||||
async function getViewMap():Promise<Map<string, JSX.Element>>{
|
||||
return new Map([
|
||||
['home', <Home></Home>],
|
||||
['man-post', <PostView></PostView>]
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
async function getSidebarEntries():Promise<Array<SidebarEntry>>{
|
||||
return [
|
||||
{ label: 'Home', view: 'home'},
|
||||
{ label: 'Post Management', view: 'man-post'},
|
||||
{ label: 'Project Management', view: 'man-proj'},
|
||||
{ label: 'Tag Management', view: 'man-tags'},
|
||||
{ label: 'User Management', view: 'man-user'},
|
||||
]
|
||||
}
|
||||
|
||||
async function getCurrentView(view:string):Promise<JSX.Element>{
|
||||
const viewMap = await getViewMap();
|
||||
const viewJSX = viewMap.get(view);
|
||||
return viewJSX ? viewJSX : <Home></Home>;
|
||||
}
|
||||
|
||||
export default async function Page(props:Props){
|
||||
const sidebarEntries:Array<SidebarEntry> = await getSidebarEntries();
|
||||
|
||||
const slug:string|string[] = props.params.slug ? props.params.slug : 'home';
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<main className="h-screen w-screen flex flex-col p-0 bg-gray-300 box-border m-0">
|
||||
<AuthHandler params={null}>
|
||||
<Sidebar sidebarEntries={sidebarEntries} slug={slug.toString()}></Sidebar>
|
||||
<AdminPanel slug={slug.toString()} auth={await getCookieAuth()}>
|
||||
{await getCurrentView(slug.toString())}
|
||||
</AdminPanel>
|
||||
</AuthHandler>
|
||||
{/* <section>{JSON.stringify(cookies().getAll())}</section> */}
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import '../globals.css'
|
||||
// import '../globals.css'
|
||||
import { Inter } from 'next/font/google'
|
||||
import StyledJsxRegistry from '../registry';
|
||||
import Providers from '@/providers/providers';
|
||||
|
||||
@@ -1,12 +1,45 @@
|
||||
import AdminPanel from "@/components/client/admin/adminPanel";
|
||||
'use server'
|
||||
import { getCookieAuth } from "@/app/lib/actions";
|
||||
import AdminPanel from "@/components/server/admin/adminPanel";
|
||||
import ServerAdminPanel from "@/components/server/admin/ServerAdminPanel";
|
||||
import AuthHandler from "@/components/server/admin/authHandler";
|
||||
import Sidebar from "@/components/server/admin/views/sidebar";
|
||||
import { cookies } from "next/headers";
|
||||
|
||||
type Props = {
|
||||
params: {
|
||||
slug: string[]
|
||||
};
|
||||
}
|
||||
|
||||
export default async function Page(){
|
||||
export type SidebarEntry = {
|
||||
label:string;
|
||||
view:string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function getSidebarEntries():Promise<Array<SidebarEntry>>{
|
||||
return [
|
||||
{ label: 'Home', view: 'home'},
|
||||
{ label: 'Post Management', view: 'man-post'},
|
||||
{ label: 'Project Management', view: 'man-proj'},
|
||||
{ label: 'Tag Management', view: 'man-tags'},
|
||||
{ label: 'User Management', view: 'man-user'},
|
||||
]
|
||||
}
|
||||
|
||||
export default async function Page(props:Props){
|
||||
const sidebarEntries:Array<SidebarEntry> = await getSidebarEntries();
|
||||
|
||||
const slug:string|string[] = props.params.slug ? props.params.slug : 'home';
|
||||
|
||||
return (
|
||||
<main className="h-screen w-screen flex flex-col p-0 bg-background-500 box-border m-0">
|
||||
<AuthHandler params={null}><AdminPanel></AdminPanel></AuthHandler>
|
||||
<AuthHandler params={null}>
|
||||
<Sidebar sidebarEntries={sidebarEntries} slug={""}></Sidebar>
|
||||
<ServerAdminPanel slug={slug.toString()} auth={await getCookieAuth()}></ServerAdminPanel>
|
||||
</AuthHandler>
|
||||
{/* <section>{JSON.stringify(cookies().getAll())}</section> */}
|
||||
</main>
|
||||
);
|
||||
|
||||
14
src/app/admin/page.tsx.bak
Normal file
14
src/app/admin/page.tsx.bak
Normal file
@@ -0,0 +1,14 @@
|
||||
import AdminPanel from "@/components/client/admin/adminPanel";
|
||||
import AuthHandler from "@/components/server/admin/authHandler";
|
||||
import { cookies } from "next/headers";
|
||||
import { Router } from "next/router";
|
||||
|
||||
|
||||
export default async function Page(){
|
||||
return (
|
||||
<main className="h-screen w-screen flex flex-col p-0 bg-background-500 box-border m-0">
|
||||
<AuthHandler params={null}><AdminPanel></AdminPanel></AuthHandler>
|
||||
{/* <section>{JSON.stringify(cookies().getAll())}</section> */}
|
||||
</main>
|
||||
);
|
||||
}
|
||||
92
src/app/api/attachment/route.ts
Normal file
92
src/app/api/attachment/route.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
'use server'
|
||||
|
||||
import { APIError, attemptAPIAction } from "@/util/api/error";
|
||||
import { Auth, Post, PostTag, Tag, User } from "@/model/Models";
|
||||
import { cookies } from "next/headers";
|
||||
|
||||
|
||||
|
||||
async function tryCreateAttachment(request: Request) {
|
||||
|
||||
// Make sure the DB is ready
|
||||
await PostTag.sync();
|
||||
await Tag.sync();
|
||||
await Post.sync();
|
||||
|
||||
// Prepare data
|
||||
const requestBody = await request.json();
|
||||
const authCkie = await cookies().get("auth");
|
||||
|
||||
// Sanity check auth cookie
|
||||
if ( !authCkie || !authCkie.value) throw new APIError({ status: 500, responseText: "missing auth cookie" });
|
||||
|
||||
// Get JSON from the Cookie
|
||||
const cookieJSON = authCkie.value;
|
||||
const authObject = JSON.parse(cookieJSON);
|
||||
|
||||
// Fetch User Auth from the database
|
||||
const auth = await Auth.findOne({
|
||||
include: [
|
||||
{
|
||||
model: User.withScope(['withPerms']),
|
||||
attributes: {
|
||||
exclude: ['username', 'password', 'updatedAt', 'createdAt']
|
||||
}
|
||||
}
|
||||
],
|
||||
where: { token: authObject.token }
|
||||
});
|
||||
|
||||
// Sanity check the auth and associated user
|
||||
if (!auth || !auth.user) throw new APIError({ status: 401, responseText: "Authentication Error" });
|
||||
|
||||
// Handle incomplete data or other problems
|
||||
if (!requestBody) throw new APIError({ status: 500, responseText: "Empty request body" });
|
||||
if (!requestBody.title) throw new APIError({ status: 500, responseText: "Missing post title" });
|
||||
if (!requestBody.content) throw new APIError({ status: 500, responseText: "Missing post content" });
|
||||
if (!auth.user.id) throw new APIError({ status: 500, responseText: "Missing user id" });
|
||||
if (!auth.user.perms || !auth.user.perms.isAdmin) throw new APIError({ status: 401, responseText: `Unauthorized ${JSON.stringify(auth.user)}` });
|
||||
|
||||
// Create a new Post in the database
|
||||
const post = await Post.create(
|
||||
{
|
||||
content: requestBody.content,
|
||||
user_id: auth.user.id,
|
||||
title: requestBody.title,
|
||||
},{
|
||||
include: {
|
||||
association: Post.associations.user
|
||||
}
|
||||
}).then(post=>post.reload())
|
||||
|
||||
// Return the response
|
||||
return new Response(JSON.stringify(post), { status: 200 });
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
export async function tryFetchAttachments(request: Request) {
|
||||
|
||||
await Post.sync();
|
||||
|
||||
const foundPosts = await Post.findAll({
|
||||
include: [
|
||||
{
|
||||
association: Post.associations.user,
|
||||
attributes: { exclude: ['password', 'createdAt', 'updatedAt'] }
|
||||
},{
|
||||
association: Post.associations.postTags
|
||||
}]
|
||||
});
|
||||
|
||||
return new Response(JSON.stringify(foundPosts), { status: 200 });
|
||||
|
||||
}
|
||||
|
||||
export async function GET(request: Request) {
|
||||
return await attemptAPIAction(tryFetchAttachments,request);
|
||||
}
|
||||
export async function POST(request: Request) {
|
||||
return await attemptAPIAction(tryCreateAttachment,request);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
'use server'
|
||||
|
||||
import { APIError } from "@/app/lib/api/error";
|
||||
import { APIError } from "@/util/api/error";
|
||||
import { Post } from "@/model/Models";
|
||||
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ async function tryCreatePost(request: Request) {
|
||||
|
||||
|
||||
|
||||
async function tryFetchPosts(request: Request) {
|
||||
export async function tryFetchPosts(request: Request) {
|
||||
|
||||
await Post.sync();
|
||||
|
||||
|
||||
@@ -5,8 +5,10 @@ import { cookies } from "next/headers"
|
||||
import { parseSetCookie } from "@/util/parseSetCookie";
|
||||
import makeFetchCookie from 'fetch-cookie';
|
||||
import fetchCookie from "fetch-cookie";
|
||||
import { Attributes } from "@sequelize/core";
|
||||
import { Attribute, Attributes } from "@sequelize/core";
|
||||
import { User } from "@/model/User";
|
||||
import { AuthProps } from "@/providers/providers";
|
||||
import { Auth } from "@/model/Auth";
|
||||
|
||||
type LoginReturn = {
|
||||
cookie?:unknown,
|
||||
@@ -80,6 +82,48 @@ export async function serverValidateSessionCookie(koek:string):Promise<boolean>
|
||||
|
||||
export async function userIsAdmin(user:Partial<Attributes<User>>):Promise<boolean>
|
||||
{
|
||||
const cookieAuthValue = await cookies().get('auth')?.value;
|
||||
const cookieAuthSanitized = decodeURIComponent(cookieAuthValue ? cookieAuthValue: "");
|
||||
|
||||
if(!cookieAuthSanitized) return false;
|
||||
const parsedAuth = JSON.parse(cookieAuthSanitized);
|
||||
|
||||
if(!parsedAuth.id || !parsedAuth.token || !parsedAuth.user_id) return false
|
||||
|
||||
const p:AuthProps = {
|
||||
auth: {
|
||||
id:parsedAuth.id,
|
||||
token:parsedAuth.token,
|
||||
user_id:parsedAuth.user_id
|
||||
}
|
||||
};
|
||||
|
||||
const foundAuth = await Auth.findOne({where: { id: p.auth?.id}});
|
||||
if(!foundAuth || foundAuth.token != p.auth?.token ) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export async function getCookieAuth():Promise<AuthProps>
|
||||
{
|
||||
const cookieAuthValue = await cookies().get('auth')?.value;
|
||||
const cookieAuthSanitized = decodeURIComponent(cookieAuthValue ? cookieAuthValue: "");
|
||||
|
||||
if(!cookieAuthSanitized) return {}
|
||||
|
||||
const kd = JSON.parse(cookieAuthSanitized);
|
||||
if(!kd.id || !kd.token || !kd.user_id) return {};
|
||||
|
||||
const foundAuth = await Auth.findOne({where: { id: kd.id},include:{model:User}});
|
||||
if(!foundAuth) return {};
|
||||
const authObject:AuthProps = {
|
||||
auth: {
|
||||
id:kd.id,
|
||||
token:kd.token,
|
||||
user_id:kd.user_id
|
||||
},
|
||||
user: await foundAuth.user
|
||||
}
|
||||
return authObject;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
15
src/app/lib/postActions.ts
Normal file
15
src/app/lib/postActions.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
'use server';
|
||||
import { Post } from "@/model/Post";
|
||||
import { Attributes } from "@sequelize/core";
|
||||
|
||||
|
||||
export async function deletePost(postID: number): Promise<boolean> {
|
||||
const destroy = await Post.destroy({ where: { id: postID } });
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
export async function getPosts(): Promise<string> {
|
||||
const posts = await Post.findAll();
|
||||
return JSON.stringify(posts);
|
||||
}
|
||||
Reference in New Issue
Block a user