Refactoring and reworking dbsetup route
This commit is contained in:
parent
c076918d05
commit
665da4be29
0
db/.gitkeep
Normal file
0
db/.gitkeep
Normal file
29
db/seed/posts.json
Normal file
29
db/seed/posts.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"projects": [
|
||||
{
|
||||
"name": "Blog",
|
||||
"readableIdentifier": "blog",
|
||||
"posts": [
|
||||
{
|
||||
"title": "Test Post",
|
||||
"content": "# Hello <ExampleComponent />\nthis is some **test** markdown and we make some edits\n",
|
||||
"description": "A new post to test the blog system",
|
||||
"project_id": 1,
|
||||
"user_id": 1,
|
||||
"buckets": [
|
||||
{
|
||||
"id": "788dfc19-55ba-482c-8124-277702296dfb",
|
||||
"attachments": [
|
||||
{
|
||||
"path": "FB_IMG_1716665756868.jpg"
|
||||
},{
|
||||
"path": "patchnotes.jpg"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
db/seed/posts/FB_IMG_1716665756868.jpg
Normal file
BIN
db/seed/posts/FB_IMG_1716665756868.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 124 KiB |
BIN
db/seed/posts/patchnotes.png
Normal file
BIN
db/seed/posts/patchnotes.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
21
db/seed/users.json
Normal file
21
db/seed/users.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"users": [{
|
||||
"username": "admin",
|
||||
"password": "changeme",
|
||||
"perms": {
|
||||
"isAdmin": true
|
||||
}
|
||||
},{
|
||||
"username": "notadmin",
|
||||
"password": "changeme",
|
||||
"perms": {
|
||||
"isAdmin": false
|
||||
}
|
||||
},{
|
||||
"username": "theodore",
|
||||
"password": "changeme",
|
||||
"perms": {
|
||||
"isAdmin": false
|
||||
}
|
||||
}]
|
||||
}
|
||||
@ -5,38 +5,109 @@ import { cookies } from "next/headers";
|
||||
import { APIError} from "@/util/api/error"
|
||||
import { UserAuth, parseBasicAuth, getAssociatedUser } from "@/util/api/user"
|
||||
import { Attachment, Auth, Bucket, DBState, Post, PostTag, Project, Tag, User, UserPerms,dbSync,sequelize} from "@/models";
|
||||
import Sequelize, { DataTypes } from "@sequelize/core";
|
||||
import Sequelize, { CreationAttributes, DataTypes } from "@sequelize/core";
|
||||
import { SqliteColumnsDescription, SqliteDialect, SqliteQueryInterface } from "@sequelize/sqlite3";
|
||||
import { hashPassword } from "@/util/Auth";
|
||||
import { copyFile, readFileSync } from "fs";
|
||||
import path from "path";
|
||||
import { Attributes } from '@sequelize/core';
|
||||
import { DeepPartial } from "@/util/DeepPartial";
|
||||
import { UUID } from "crypto";
|
||||
|
||||
async function seedUsers(qif: SqliteQueryInterface<SqliteDialect>){
|
||||
const fp = path.resolve('./db/seed/users.json');
|
||||
const json: {users: CreationAttributes<User>[]} = JSON.parse(Buffer.from(readFileSync(fp).valueOf()).toString());
|
||||
|
||||
const users = json.users.map(async user=>{
|
||||
user.password = await hashPassword(user.password);
|
||||
return user;
|
||||
})
|
||||
|
||||
const dbUsers = await User.bulkCreate(await Promise.all(users), {include: User.associations.perms})
|
||||
}
|
||||
|
||||
async function seedPosts(qif: SqliteQueryInterface<SqliteDialect>){
|
||||
const fp = path.resolve('./db/seed/posts.json');
|
||||
const json: {users: CreationAttributes<User>[]} = JSON.parse(Buffer.from(readFileSync(fp).valueOf()).toString());
|
||||
const projects =[
|
||||
{
|
||||
"name": "Blog",
|
||||
"readableIdentifier": "blog",
|
||||
"posts": [
|
||||
{
|
||||
"title": "Test Post",
|
||||
"content": "# Hello <ExampleComponent />\nthis is some **test** markdown and we make some edits\n",
|
||||
"description": "A new post to test the blog system",
|
||||
"project_id": 1,
|
||||
"user_id": 1,
|
||||
"buckets": [
|
||||
{
|
||||
"id": "788dfc19-55ba-482c-8124-277702296dfb",
|
||||
"attachments": [
|
||||
{
|
||||
"filename": "FB_IMG_1716665756868.jpg"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}]
|
||||
projects.map(project=>{
|
||||
Project.create({name: project.name, readableIdentifier: project.readableIdentifier});
|
||||
project.posts.map(async post=>{
|
||||
const pst = await Post.create({title:post.title, content:post.content, description:post.description, project_id: post.project_id, user_id: post.user_id});
|
||||
post.buckets.map(async bucket=>{
|
||||
pst.createBucket({id:bucket.id as UUID});
|
||||
bucket.attachments.map(attachment=>{
|
||||
Attachment.create({bucket_id:bucket.id as UUID, filename: attachment.filename}).then((a)=>{
|
||||
copyFile(
|
||||
path.resolve('.','db','seed','post',a.filename),
|
||||
path.resolve('.','bucket',bucket.id,a.filename),
|
||||
()=>{
|
||||
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
||||
async function seedDatabase(queryInterface:SqliteQueryInterface<SqliteDialect>){
|
||||
|
||||
const password = await hashPassword('changeme');
|
||||
const project = await Project.findOne({where: {
|
||||
readableIdentifier: 'blog'
|
||||
}}).then(e=> e ? e : Project.create({name:'General Blog',readableIdentifier:'blog'}));
|
||||
const user = await User.findOne({where: {
|
||||
username: 'admin'
|
||||
}}).then(e=> e ? e : User.create({username: 'admin', password: password, perms: {isAdmin: true}}, {include: User.associations.perms}));
|
||||
await Post.create({
|
||||
title: 'Test Post',
|
||||
content: `
|
||||
# Hello <ExampleComponent />
|
||||
this is some **test** markdown
|
||||
`,
|
||||
project_id: project.id,
|
||||
user_id: user.id
|
||||
})
|
||||
await Post.create({
|
||||
title: 'Test Post 2',
|
||||
content: `
|
||||
# Hello <ExampleComponent />
|
||||
this is amother post with some **test** markdown
|
||||
`,
|
||||
project_id: project.id,
|
||||
user_id: user.id
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
async function seedDatabase(qif:SqliteQueryInterface<SqliteDialect>){
|
||||
await seedUsers(qif);
|
||||
await seedPosts(qif)
|
||||
|
||||
// await Post.create({
|
||||
// title: 'Test Post',
|
||||
// content: `
|
||||
// # Hello <ExampleComponent />
|
||||
// this is some **test** markdown
|
||||
// `,
|
||||
// project_id: project.id,
|
||||
// user_id: user.id
|
||||
// })
|
||||
// await Post.create({
|
||||
// title: 'Test Post 2',
|
||||
// content: `
|
||||
// # Hello <ExampleComponent />
|
||||
// this is amother post with some **test** markdown
|
||||
// `,
|
||||
// project_id: project.id,
|
||||
// user_id: user.id
|
||||
// })
|
||||
}
|
||||
|
||||
async function trySetup(request:Request){
|
||||
|
||||
@ -1,8 +1,30 @@
|
||||
import { Attachment, Bucket, dbSync } from "@/models";
|
||||
import { open, openSync, readFileSync } from "fs";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import path from "path";
|
||||
|
||||
export async function GET(req:NextRequest, { params }: {params:{slug: string}}){
|
||||
export async function GET(req:NextRequest, { params }: {params:{slug: string[]}}){
|
||||
await dbSync;
|
||||
const filename: `${string}${'.'}${string}` = params.slug[params.slug.length-1] as `${string}${'.'}${string}`;
|
||||
const bucket = await Bucket.findOne({
|
||||
where: {
|
||||
id:params.slug[0],
|
||||
},
|
||||
include: [{
|
||||
association: Bucket.associations.attachments,
|
||||
where: {
|
||||
filename: params.slug[params.slug.length-1]
|
||||
}
|
||||
}]
|
||||
},)
|
||||
console.log(params.slug);
|
||||
if(!bucket || !bucket.attachments || !bucket.attachments[0] || bucket.attachments[0].filename != params.slug[params.slug.length-1]){
|
||||
const headers = new Headers();
|
||||
headers.set("Content-Type", "application/json");
|
||||
return new NextResponse(JSON.stringify({
|
||||
error:"Access Denied"
|
||||
}),{headers:headers});
|
||||
}
|
||||
const fp = path.resolve('.',`bucket`,...params.slug);
|
||||
return new Response(readFileSync(fp));
|
||||
}
|
||||
@ -71,3 +71,12 @@ export async function updatePost(postAttributes: Partial<Attributes<Post>>): Pro
|
||||
const post = await Post.update(postAttributes, {where:{id:postAttributes.id}});
|
||||
return {result:JSON.parse(JSON.stringify(post))};
|
||||
}
|
||||
|
||||
export type PostServerActions = {
|
||||
deletePost: (id: number) => Promise<ActionResult<boolean>>;
|
||||
getPosts: () => Promise<ActionResult<GetPostsAttributes[]>>;
|
||||
getProjects: () => Promise<ActionResult<Attributes<Project>[]>>;
|
||||
savePost: (
|
||||
data: Partial<Attributes<Post>>
|
||||
) => Promise<ActionResult<Attributes<Post>[]>>;
|
||||
};
|
||||
|
||||
@ -2,6 +2,7 @@ import { GetPostsAttributes } from "@/app/lib/actions/entityManagement/postActio
|
||||
import { Post, Project, Bucket, PostBucket, Attachment } from "@/models";
|
||||
import { Attributes } from "@sequelize/core";
|
||||
import { UUID } from "crypto";
|
||||
import { EntityEditorTextArea } from '../input/EntityEditorTextArea';
|
||||
import {
|
||||
ChangeEventHandler,
|
||||
MouseEventHandler,
|
||||
@ -49,23 +50,6 @@ export default function PostEditor({
|
||||
let [postProjectIDState, setPostProjectIDState] = useState(
|
||||
editorPost.project.id
|
||||
);
|
||||
let textbox: any = useRef(undefined);
|
||||
|
||||
// Autosize the text area
|
||||
function textAreaAutoSize(
|
||||
textbox: MutableRefObject<HTMLTextAreaElement>
|
||||
): void {
|
||||
if (!textbox.current || !textbox.current.style) return;
|
||||
textbox.current.style.height = "fit-content";
|
||||
textbox.current.style.height = `${textbox.current.scrollHeight}px`;
|
||||
}
|
||||
useLayoutEffect(() => textAreaAutoSize(textbox));
|
||||
|
||||
// Handle user input on the text area by updating state and autosizing the textfield
|
||||
const onTextAreaChange: ChangeEventHandler<HTMLTextAreaElement> = (e) => {
|
||||
setPostContentState(e.target.value); // Update State
|
||||
textAreaAutoSize(textbox); // Autosize the text area
|
||||
};
|
||||
|
||||
// Handle changing the selected project using the dropdown select
|
||||
const projectSelectionChange: ChangeEventHandler<HTMLSelectElement> = (e) =>
|
||||
@ -102,14 +86,14 @@ export default function PostEditor({
|
||||
<h2 key="label-content" className="m-2">
|
||||
Content
|
||||
</h2>
|
||||
<textarea
|
||||
key="input-content"
|
||||
onChange={onTextAreaChange}
|
||||
ref={textbox}
|
||||
value={postContentState}
|
||||
style={{ height: "100%" }}
|
||||
className="w-[100%] min-h-auto h-content align-top text-start text-base line-clamp-6 m-2"
|
||||
/>
|
||||
<EntityEditorTextArea
|
||||
contentHook={{
|
||||
state: postContentState,
|
||||
setState: setPostContentState
|
||||
}}
|
||||
className={ "w-[100%] min-h-auto h-content align-top text-start text-base line-clamp-6 m-2" }
|
||||
>
|
||||
</EntityEditorTextArea>
|
||||
<h2 key="label-project" className="m-2">
|
||||
Project
|
||||
</h2>
|
||||
|
||||
@ -1,38 +1,28 @@
|
||||
"use client";
|
||||
import React, { ReactNode } from "react";
|
||||
import React from "react";
|
||||
import EntityManagementTable from "../EntityManagementTable";
|
||||
import toast from "react-hot-toast";
|
||||
import { EditorRenderer, EditorState, PostTableCallbacks } from "./PostEditor";
|
||||
import { Attributes } from "@sequelize/core";
|
||||
import { useState } from "react";
|
||||
import { Project, Post, Bucket } from "@/models";
|
||||
import { ActionResult } from "@/app/lib/actions/ActionResult";
|
||||
import { Attributes, InferAttributes } from "@sequelize/core";
|
||||
import { Project, Post, Bucket, User, PostAttributesWithBuckets } from "@/models";
|
||||
import { handleActionResult } from "@/app/lib/actions/clientActionHandler";
|
||||
|
||||
import {
|
||||
getPostsWithBucketsAndProject,
|
||||
GetPostsAttributes,
|
||||
PostServerActions,
|
||||
} from "@/app/lib/actions/entityManagement/postActions";
|
||||
import { PostViewProps } from "@/views/admin/ClientPostView";
|
||||
import { aifa } from "@/util/Utils";
|
||||
import { StateHook } from "../../../util/types/StateHook";
|
||||
|
||||
export type PostTableServerActions = {
|
||||
deletePost: (id: number) => Promise<ActionResult<boolean>>;
|
||||
getPosts: () => Promise<ActionResult<GetPostsAttributes[]>>;
|
||||
getProjects: () => Promise<ActionResult<Attributes<Project>[]>>;
|
||||
savePost: (
|
||||
data: Partial<Attributes<Post>>
|
||||
) => Promise<ActionResult<Attributes<Post>[]>>;
|
||||
// uploadAttachment: ()=> Promise<ActionResult<any>>
|
||||
};
|
||||
export type PostTableStateProps = {
|
||||
posts:StateHook<GetPostsAttributes[]>,
|
||||
editor:StateHook<EditorState>
|
||||
}
|
||||
|
||||
type PostTableProps = {
|
||||
children?: ReactNode;
|
||||
headings: Array<string>;
|
||||
posts: GetPostsAttributes[];
|
||||
projects: Attributes<Project>[];
|
||||
actions: PostTableServerActions;
|
||||
};
|
||||
export type PostTableProps = PostViewProps & {state:PostTableStateProps};
|
||||
|
||||
const aifa = (a: ReactNode, b: ReactNode) => (a ? a : b);
|
||||
|
||||
export default function PostTable({
|
||||
children,
|
||||
@ -40,26 +30,20 @@ export default function PostTable({
|
||||
posts,
|
||||
projects,
|
||||
actions,
|
||||
state,
|
||||
}: PostTableProps) {
|
||||
// Init editor state. Make sure it is not opened by default
|
||||
const initEditorState: EditorState = {
|
||||
isEditorOpen: false,
|
||||
editorPost: posts[0],
|
||||
};
|
||||
// Set up required state hooks
|
||||
const [postsState, setPostsState] = useState(posts);
|
||||
const [editorState, setEditorState] = useState(initEditorState);
|
||||
|
||||
|
||||
// Define editor controls
|
||||
const editorControls = {
|
||||
closeEditor: () => {
|
||||
setEditorState({
|
||||
state.editor.setState({
|
||||
isEditorOpen: false,
|
||||
editorPost: posts[0],
|
||||
});
|
||||
},
|
||||
showEditor: (entry: GetPostsAttributes) => {
|
||||
setEditorState({
|
||||
state.editor.setState({
|
||||
isEditorOpen: true,
|
||||
editorPost: entry,
|
||||
});
|
||||
@ -72,8 +56,8 @@ export default function PostTable({
|
||||
actions.deletePost(entry.id).then((actionResult) => {
|
||||
const result = handleActionResult(actionResult);
|
||||
if (!result) return;
|
||||
postsState.splice(postsState.indexOf(entry), 1);
|
||||
setPostsState([...postsState]);
|
||||
state.posts.state.splice(state.posts.state.indexOf(entry), 1);
|
||||
state.posts.setState([...state.posts.state]);
|
||||
toast.success("Removed Post:" + entry.id);
|
||||
});
|
||||
},
|
||||
@ -86,7 +70,7 @@ export default function PostTable({
|
||||
getPostsServerActionResult
|
||||
);
|
||||
// Set Posts state
|
||||
if (result) setPostsState(result);
|
||||
if (result) state.posts.setState(result);
|
||||
});
|
||||
},
|
||||
savePost: (e: Partial<Attributes<Post>>) => {
|
||||
@ -101,26 +85,19 @@ export default function PostTable({
|
||||
.then(getPostsWithBucketsAndProject)
|
||||
.then((res) => {
|
||||
const result = handleActionResult(res);
|
||||
if (result) setPostsState(result);
|
||||
if (result) state.posts.setState(result);
|
||||
})
|
||||
.then(editorControls.closeEditor)
|
||||
.then(postActions.refetch);
|
||||
},
|
||||
};
|
||||
|
||||
const callbacks: PostTableCallbacks = {
|
||||
savePost: postActions.savePost,
|
||||
closeEditor: editorControls.closeEditor,
|
||||
refetch: postActions.refetch,
|
||||
uploadAttachment: () => {},
|
||||
};
|
||||
|
||||
return (
|
||||
<EntityManagementTable
|
||||
entityName="Post"
|
||||
headings={headings}
|
||||
>
|
||||
{postsState.map((post: GetPostsAttributes) => (
|
||||
{state.posts.state.map((post: GetPostsAttributes) => (
|
||||
<React.Fragment key={`postrow-${post.id}`}>
|
||||
<tr>
|
||||
<th key={`rowheading-post-${post.id}`} scope="row">
|
||||
@ -177,8 +154,13 @@ export default function PostTable({
|
||||
headings={headings}
|
||||
editorPost={post}
|
||||
editorControls={editorControls}
|
||||
editorState={editorState}
|
||||
callbacks={callbacks}
|
||||
editorState={state.editor.state}
|
||||
callbacks={{
|
||||
savePost: postActions.savePost,
|
||||
closeEditor: editorControls.closeEditor,
|
||||
refetch: postActions.refetch,
|
||||
uploadAttachment: () => {},
|
||||
}}
|
||||
projects={projects}
|
||||
/>
|
||||
</React.Fragment>
|
||||
|
||||
34
src/components/client/input/EntityEditorTextArea.tsx
Normal file
34
src/components/client/input/EntityEditorTextArea.tsx
Normal file
@ -0,0 +1,34 @@
|
||||
'use client'
|
||||
|
||||
import { useRef, MutableRefObject, useLayoutEffect, ChangeEventHandler, useState } from "react";
|
||||
import { StateHook } from '../../../util/types/StateHook';
|
||||
|
||||
export function EntityEditorTextArea({contentHook, className}: {contentHook:StateHook<string>, className:string}){
|
||||
|
||||
let textbox: any = useRef(undefined);
|
||||
|
||||
// Autosize the text area
|
||||
function textAreaAutoSize(
|
||||
textbox: MutableRefObject<HTMLTextAreaElement>
|
||||
): void {
|
||||
if (!textbox.current || !textbox.current.style) return;
|
||||
textbox.current.style.height = "fit-content";
|
||||
textbox.current.style.height = `${textbox.current.scrollHeight}px`;
|
||||
}
|
||||
useLayoutEffect(() => textAreaAutoSize(textbox));
|
||||
|
||||
// Handle user input on the text area by updating state and autosizing the textfield
|
||||
const onTextAreaChange: ChangeEventHandler<HTMLTextAreaElement> = (e) => {
|
||||
contentHook?.setState(e.target.value); // Update State
|
||||
textAreaAutoSize(textbox); // Autosize the text area
|
||||
};
|
||||
|
||||
return <textarea
|
||||
key="input-content"
|
||||
onChange={onTextAreaChange}
|
||||
ref={textbox}
|
||||
value={contentHook?.state}
|
||||
style={{ height: "100%" }}
|
||||
className={className}
|
||||
/>
|
||||
}
|
||||
@ -29,6 +29,7 @@ export class User extends Model<InferAttributes<User>, InferCreationAttributes<U
|
||||
@Unique
|
||||
declare id: CreationOptional<number>;
|
||||
@Attribute(DataTypes.STRING)
|
||||
@Unique()
|
||||
declare username: string;
|
||||
@Attribute(DataTypes.STRING)
|
||||
declare password: string;
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
'server only'
|
||||
import { ReactNode } from "react";
|
||||
import Gens from "./gens";
|
||||
// import Auth from "./Auth";
|
||||
|
||||
@ -29,3 +30,4 @@ function truncateString(str:string = '', num:number = 255) {
|
||||
|
||||
|
||||
export { Gens, constructAPIUrl, constructUrl, truncateString }
|
||||
export const aifa = (a: ReactNode, b: ReactNode) => (a ? a : b);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
import { validatePassword } from "@/util/Auth";
|
||||
import { APIError } from "@/util/api/error";
|
||||
import { User } from "@/model/User";
|
||||
import { User } from "@/models";
|
||||
|
||||
export function parseBasicAuth(authb64:string):UserAuth
|
||||
{
|
||||
|
||||
9
src/util/types/StateHook.tsx
Normal file
9
src/util/types/StateHook.tsx
Normal file
@ -0,0 +1,9 @@
|
||||
import { Dispatch, SetStateAction } from "react";
|
||||
|
||||
export type StateHook<T> = {
|
||||
state: T;
|
||||
setState: Dispatch<SetStateAction<T>>;
|
||||
};
|
||||
export type StateHookArray<T> = [
|
||||
T,Dispatch<SetStateAction<T>>
|
||||
]
|
||||
62
src/views/admin/ClientPostView.tsx
Normal file
62
src/views/admin/ClientPostView.tsx
Normal file
@ -0,0 +1,62 @@
|
||||
"use client";
|
||||
|
||||
import PostTable, {
|
||||
PostTableStateProps,
|
||||
} from "@/components/client/admin/PostTable";
|
||||
import { PostTableProps } from "../../components/client/admin/PostTable";
|
||||
import {
|
||||
GetPostsAttributes,
|
||||
PostServerActions,
|
||||
} from "@/app/lib/actions/entityManagement/postActions";
|
||||
import { EditorState } from "@/components/client/admin/PostEditor";
|
||||
import { Project } from "@/models";
|
||||
import { Dispatch, ReactNode, SetStateAction, useState } from "react";
|
||||
import { Attributes } from "@sequelize/core";
|
||||
import { StateHookArray } from "@/util/types/StateHook";
|
||||
|
||||
export type PostViewProps = {
|
||||
children?: ReactNode;
|
||||
headings: Array<string>;
|
||||
posts: GetPostsAttributes[];
|
||||
projects: Attributes<Project>[];
|
||||
actions: PostServerActions;
|
||||
};
|
||||
|
||||
export function ClientPostView({
|
||||
children,
|
||||
headings,
|
||||
posts,
|
||||
projects,
|
||||
actions,
|
||||
}: PostViewProps) {
|
||||
// Init editor state. Make sure it is not opened by default
|
||||
const initEditorState: EditorState = {
|
||||
isEditorOpen: false,
|
||||
editorPost: posts[0],
|
||||
};
|
||||
// Set up required state hooks
|
||||
const [postsState, setPostsState]: StateHookArray<GetPostsAttributes[]> = useState(posts);
|
||||
const [editorState, setEditorState]: StateHookArray<EditorState> = useState(initEditorState);
|
||||
const state: PostTableStateProps = {
|
||||
posts: {
|
||||
state: postsState,
|
||||
setState: setPostsState,
|
||||
},
|
||||
editor: {
|
||||
state: editorState,
|
||||
setState: setEditorState,
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<PostTable
|
||||
headings={headings}
|
||||
posts={posts}
|
||||
projects={projects}
|
||||
actions={actions}
|
||||
state={state}
|
||||
></PostTable>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@ -2,25 +2,29 @@
|
||||
cache: "no-store";
|
||||
|
||||
import { ReactNode, useEffect } from "react";
|
||||
import PostTable, {
|
||||
PostTableServerActions,
|
||||
} from "@/components/client/admin/PostTable";
|
||||
import PostTable from "@/components/client/admin/PostTable";
|
||||
import {
|
||||
deletePost,
|
||||
getPostsWithBucketsAndProject,
|
||||
GetPostsAttributes,
|
||||
updatePost,
|
||||
GetPostsAttributes,
|
||||
PostServerActions,
|
||||
} from "@/app/lib/actions/entityManagement/postActions";
|
||||
import { getProjects } from "@/app/lib/actions/entityManagement/projectActions";
|
||||
import { Bucket, Project, Post, dbSync, Attachment } from "@/models";
|
||||
import { handleActionResult } from "../../app/lib/actions/clientActionHandler";
|
||||
import { ClientPostView } from "./ClientPostView";
|
||||
import { readFileSync } from "fs";
|
||||
import path from "path";
|
||||
|
||||
type Props = {
|
||||
children?: ReactNode;
|
||||
};
|
||||
|
||||
async function getHeadings() {
|
||||
let headings: string[] = [
|
||||
export default async function PostView(props: Props) {
|
||||
const sync = await dbSync;
|
||||
|
||||
const headings:string[] = [
|
||||
"#",
|
||||
"Title",
|
||||
"Content",
|
||||
@ -29,15 +33,7 @@ async function getHeadings() {
|
||||
"UpdatedAt",
|
||||
];
|
||||
|
||||
return headings;
|
||||
}
|
||||
|
||||
export default async function PostView(props: Props) {
|
||||
const sync = await dbSync;
|
||||
|
||||
const headings = await getHeadings();
|
||||
|
||||
const actions: PostTableServerActions = {
|
||||
const actions: PostServerActions = {
|
||||
deletePost: deletePost,
|
||||
getPosts: getPostsWithBucketsAndProject,
|
||||
getProjects: getProjects,
|
||||
@ -55,12 +51,12 @@ export default async function PostView(props: Props) {
|
||||
return (
|
||||
<div className="w-[100%] min-h-fit bg-gray-100 overflow-scroll">
|
||||
<div className="w-[100%] m-auto">
|
||||
<PostTable
|
||||
<ClientPostView
|
||||
posts={posts ? posts : []}
|
||||
projects={projects}
|
||||
headings={headings}
|
||||
actions={actions}
|
||||
></PostTable>
|
||||
></ClientPostView>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -1,64 +1,70 @@
|
||||
cache: 'no-store'
|
||||
cache: "no-store";
|
||||
|
||||
import { tryFetchPosts } from "@/app/api/post/route";
|
||||
import { constructAPIUrl } from "@/util/Utils";
|
||||
import { ReactNode, useEffect } from "react";
|
||||
import EntityManagementTable from "../../components/client/EntityManagementTable";
|
||||
import PostTable from "@/components/client/admin/PostTable";
|
||||
import { deletePost, getPostsWithBucketsAndProject, updatePost } from "@/app/lib/actions/entityManagement/postActions";
|
||||
import {
|
||||
deletePost,
|
||||
getPostsWithBucketsAndProject,
|
||||
updatePost,
|
||||
} from "@/app/lib/actions/entityManagement/postActions";
|
||||
import { getProjects } from "@/app/lib/actions/entityManagement/projectActions";
|
||||
import { Bucket, Project, Post, dbSync, Attachment } from "@/models";
|
||||
import { tryCreateAttachment } from "@/app/api/attachment/route";
|
||||
import { Attributes } from '@sequelize/core';
|
||||
import * as util from 'util'
|
||||
import { Attributes } from "@sequelize/core";
|
||||
import * as util from "util";
|
||||
|
||||
type Props = {
|
||||
children?:ReactNode
|
||||
children?: ReactNode;
|
||||
};
|
||||
|
||||
async function getHeadings() {
|
||||
let headings: string[] = [];
|
||||
for (const key in Project.getAttributes()) {
|
||||
headings.push(key);
|
||||
}
|
||||
return headings;
|
||||
}
|
||||
|
||||
async function getHeadings(){
|
||||
let headings:string[] = []
|
||||
for (const key in Project.getAttributes())
|
||||
{
|
||||
headings.push(key)
|
||||
}
|
||||
return headings
|
||||
}
|
||||
export default async function ProjectView(props: Props) {
|
||||
const sync = await dbSync;
|
||||
|
||||
export default async function ProjectView(props:Props){
|
||||
const sync = await dbSync;
|
||||
|
||||
// const headings = [
|
||||
// '#',
|
||||
// 'Title',
|
||||
// 'Content',
|
||||
// 'Project',
|
||||
// 'Date Created',
|
||||
// 'Date Modified',
|
||||
// 'Edit',
|
||||
// 'Delete',
|
||||
// ]
|
||||
// const actions = {
|
||||
// deletePost: deletePost,
|
||||
// getPosts:getPostsWithBuckets,
|
||||
// getProjects:getProjects,
|
||||
// savePost:updatePost,
|
||||
// // uploadAttachment:tryCreateAttachment
|
||||
// };
|
||||
|
||||
const posts:Post[] = await Post.findAll({include: {model: Bucket, include: {model: Attachment}}}).then(posts=>posts.map((e)=>JSON.parse(JSON.stringify(e))));
|
||||
const projects = await Project.findAll().then(projects=>projects.map((e)=>JSON.parse(JSON.stringify(e))));
|
||||
const headings = await getHeadings();
|
||||
return <>
|
||||
<div className="w-[100%] min-h-fit bg-gray-100 overflow-scroll">
|
||||
<div className="w-[100%] m-auto">
|
||||
<EntityManagementTable entityName="Project" headings={headings}><></></EntityManagementTable>
|
||||
{/* <PostTable data={posts}
|
||||
const actions = {
|
||||
deletePost: deletePost,
|
||||
getProjects:getProjects,
|
||||
savePost:updatePost,
|
||||
// uploadAttachment:tryCreateAttachment
|
||||
};
|
||||
const projects: Project[] = await Project.findAll().then((projects) =>
|
||||
projects.map((e) => JSON.parse(JSON.stringify(e)))
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<div className="w-[100%] min-h-fit bg-gray-100 overflow-scroll">
|
||||
<div className="w-[100%] m-auto">
|
||||
<EntityManagementTable
|
||||
entityName="Project"
|
||||
headings={[
|
||||
'#',
|
||||
'Title',
|
||||
'Content',
|
||||
'Project',
|
||||
'Date Created',
|
||||
'Date Modified',
|
||||
'Edit',
|
||||
'Delete',
|
||||
]}>
|
||||
{""}
|
||||
</EntityManagementTable>
|
||||
{/* <PostTable data={posts}
|
||||
projects={projects}
|
||||
headings={headings}
|
||||
actions={actions}>
|
||||
</PostTable> */}
|
||||
</div>
|
||||
</div>
|
||||
</>;
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user