mirror of
https://github.com/jorgev259/soc_site-astro.git
synced 2025-06-29 07:57:41 +00:00
Implement requests page
This commit is contained in:
parent
75eaf17346
commit
d3439321ba
14 changed files with 10333 additions and 7522 deletions
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
|
|
@ -13,7 +13,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"command": "yarn prisma generate --watch",
|
||||
"command": "yarn prisma generate --sql --watch",
|
||||
"name": "Prisma",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
|
|
|
|||
|
|
@ -90,5 +90,10 @@
|
|||
"variousGames": "Various Games",
|
||||
"searchResultsFor": "Search results for",
|
||||
"firstResults": "Showing first {take} results",
|
||||
"moreResults": "Showing {start}-{end} results"
|
||||
"moreResults": "Showing {start}-{end} results",
|
||||
"requestID": "Request ID",
|
||||
"userID": "userID",
|
||||
"state": "State",
|
||||
"createdAt": "Created At",
|
||||
"updatedAt": "Updated At"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,9 +5,11 @@
|
|||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"build": "yarn run prisma:build && astro build",
|
||||
"prisma:build": "prisma migrate deploy && prisma generate --sql && tsx ./prisma/migrate.ts"
|
||||
"prisma:migrate": "prisma migrate deploy && tsx ./prisma/migrate.ts",
|
||||
"prisma:build": "yarn prisma:migrate && prisma generate --sql && "
|
||||
},
|
||||
"dependencies": {
|
||||
"@ag-grid-community/locale": "^33.3.2",
|
||||
"@astrojs/node": "9.0.0",
|
||||
"@astrojs/react": "4.1.3",
|
||||
"@astrojs/rss": "4.0.11",
|
||||
|
|
@ -15,6 +17,8 @@
|
|||
"@tailwindcss/vite": "^4.0.7",
|
||||
"@types/react": "^18.3.12",
|
||||
"@types/react-dom": "^18.3.1",
|
||||
"ag-grid-community": "^33.3.1",
|
||||
"ag-grid-react": "^33.3.1",
|
||||
"astro": "^5.3.0",
|
||||
"astro-icon": "^1.1.1",
|
||||
"astro-seo": "^0.8.4",
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ const LIMIT_PENDING = 5
|
|||
|
||||
export default async function MigrationFn(tx: Prisma.TransactionClient) {
|
||||
const donatorRequests = await tx.requests.findMany({
|
||||
where: { donator: true, state: RequestState.PENDING, userID: { not: null } }
|
||||
where: { donator: true, state: RequestState.PENDING }
|
||||
})
|
||||
const donatorMap = new Map<string, typeof donatorRequests>()
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `user` on the `requests` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `createdAt` on the `roles` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `updatedAt` on the `roles` table. All the data in the column will be lost.
|
||||
- Made the column `userID` on table `requests` required. This step will fail if there are existing NULL values in that column.
|
||||
|
||||
*/
|
||||
|
||||
DELETE FROM `requests` WHERE `userId` IS NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `requests` DROP COLUMN `user`,
|
||||
MODIFY `userID` VARCHAR(255) NOT NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `roles` DROP COLUMN `createdAt`,
|
||||
DROP COLUMN `updatedAt`;
|
||||
|
|
@ -344,8 +344,7 @@ model requests {
|
|||
id Int @id @default(autoincrement())
|
||||
title String? @db.VarChar(255)
|
||||
link String? @db.VarChar(255)
|
||||
user String? @db.VarChar(255)
|
||||
userID String? @db.VarChar(255)
|
||||
userID String @db.VarChar(255)
|
||||
state RequestState
|
||||
donator Boolean
|
||||
reason String? @db.VarChar(255)
|
||||
|
|
@ -359,8 +358,6 @@ model requests {
|
|||
model roles {
|
||||
name String @id @db.VarChar(255)
|
||||
permissions Json?
|
||||
createdAt DateTime @db.DateTime(0)
|
||||
updatedAt DateTime @db.DateTime(0)
|
||||
users User_Role[]
|
||||
}
|
||||
|
||||
|
|
|
|||
45
src/components/AgGrid/AgGridTheme.tsx
Normal file
45
src/components/AgGrid/AgGridTheme.tsx
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import {
|
||||
ModuleRegistry,
|
||||
ColumnAutoSizeModule,
|
||||
ColumnHoverModule,
|
||||
TextFilterModule,
|
||||
NumberFilterModule,
|
||||
DateFilterModule,
|
||||
QuickFilterModule,
|
||||
TextEditorModule,
|
||||
LargeTextEditorModule,
|
||||
SelectEditorModule,
|
||||
NumberEditorModule,
|
||||
DateEditorModule,
|
||||
CheckboxEditorModule,
|
||||
LocaleModule,
|
||||
ClientSideRowModelModule,
|
||||
colorSchemeDark,
|
||||
themeQuartz
|
||||
} from 'ag-grid-community'
|
||||
|
||||
ModuleRegistry.registerModules([
|
||||
ColumnAutoSizeModule,
|
||||
ColumnHoverModule,
|
||||
TextFilterModule,
|
||||
NumberFilterModule,
|
||||
DateFilterModule,
|
||||
QuickFilterModule,
|
||||
TextEditorModule,
|
||||
LargeTextEditorModule,
|
||||
SelectEditorModule,
|
||||
NumberEditorModule,
|
||||
DateEditorModule,
|
||||
CheckboxEditorModule,
|
||||
LocaleModule,
|
||||
ClientSideRowModelModule
|
||||
])
|
||||
|
||||
const AgGridTheme = themeQuartz.withPart(colorSchemeDark)
|
||||
export default AgGridTheme
|
||||
|
||||
import { AG_GRID_LOCALE_EN } from '@ag-grid-community/locale'
|
||||
|
||||
export const AgGridLocales = {
|
||||
en: { AG_GRID_LOCALE_EN }
|
||||
}
|
||||
|
|
@ -54,7 +54,6 @@ const { session } = Astro.locals
|
|||
<a href='/'><NavButton>{m.home()}</NavButton></a>
|
||||
<a href='/last-added'><NavButton>{m.lastaddednav()}</NavButton></a>
|
||||
<a href='/album/list'><NavButton>{m.albumlist()}</NavButton></a>
|
||||
|
||||
<Dropdown>
|
||||
{m.games()}
|
||||
<Fragment slot='items'>
|
||||
|
|
@ -65,7 +64,6 @@ const { session } = Astro.locals
|
|||
<DropdownItem href='/platform/list'>{m.platforms()}</DropdownItem>
|
||||
</Fragment>
|
||||
</Dropdown>
|
||||
|
||||
<Dropdown>
|
||||
{m.animation()}
|
||||
<Fragment slot='items'>
|
||||
|
|
@ -74,13 +72,13 @@ const { session } = Astro.locals
|
|||
<DropdownItem href='/studio/list'>{m.studios()}</DropdownItem>
|
||||
</Fragment>
|
||||
</Dropdown>
|
||||
<a href='/requests'>
|
||||
<NavButton>{m.requests()}</NavButton>
|
||||
</a>
|
||||
|
||||
{
|
||||
session ? (
|
||||
<>
|
||||
<a href='/requests'>
|
||||
<NavButton>{m.requests()}</NavButton>
|
||||
</a>
|
||||
<NavButton>{m.submitalbum()}</NavButton>
|
||||
<Dropdown>
|
||||
{m.adminGrounds()}
|
||||
|
|
|
|||
36
src/components/requests/RequestsTable.tsx
Normal file
36
src/components/requests/RequestsTable.tsx
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
import { type ColDef, type GridOptions } from 'ag-grid-community'
|
||||
import { AgGridReact } from 'ag-grid-react'
|
||||
import type { Prisma } from '@prisma/client'
|
||||
import { m } from 'paraglide/messages.js'
|
||||
|
||||
import AgGridTheme from 'components/AgGrid/AgGridTheme'
|
||||
|
||||
const gridOptions: GridOptions = {
|
||||
ensureDomOrder: true,
|
||||
enableCellTextSelection: true
|
||||
}
|
||||
|
||||
const colDefs: ColDef[] = [
|
||||
{ field: 'id', headerName: m.requestID(), filter: true },
|
||||
{ field: 'title', headerName: m.requests(), filter: true },
|
||||
{ field: 'userID', headerName: m.userID(), filter: true },
|
||||
{ field: 'state', headerName: m.state(), filter: true },
|
||||
{ field: 'createdAt', headerName: m.createdAt() },
|
||||
{ field: 'updatedAt', headerName: m.updatedAt() }
|
||||
]
|
||||
|
||||
export default function RequestsTable(props: { initial: Prisma.requestsGetPayload<{}>[] }) {
|
||||
const { initial } = props
|
||||
|
||||
return (
|
||||
<div className='w-full px-4 py-4'>
|
||||
<AgGridReact
|
||||
gridOptions={gridOptions}
|
||||
rowData={initial}
|
||||
columnDefs={colDefs}
|
||||
theme={AgGridTheme}
|
||||
autoSizeStrategy={{ type: 'fitCellContents' }}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
27
src/pages/api/request/update.ts
Normal file
27
src/pages/api/request/update.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import type { APIRoute } from 'astro'
|
||||
import * as s from 'superstruct'
|
||||
import prismaClient from 'utils/prisma-client'
|
||||
|
||||
import { Status, parseForm } from 'utils/form'
|
||||
import { EditRequest } from 'schemas/requests'
|
||||
|
||||
export const POST: APIRoute = async ({ request, locals }) => {
|
||||
const { permissions, user } = locals
|
||||
if (!user || !permissions.includes('REQUESTS')) return Status(403)
|
||||
|
||||
let body
|
||||
try {
|
||||
const formData = await parseForm(await request.formData())
|
||||
body = s.create(formData, EditRequest)
|
||||
} catch (err) {
|
||||
return Status(422, (err as Error).message)
|
||||
}
|
||||
|
||||
try {
|
||||
await prismaClient.requests.update({ where: { id: body.id }, data: { ...body, updatedAt: new Date() } })
|
||||
return Status(200, body.id.toString())
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
return Status(500, (err as Error).message)
|
||||
}
|
||||
}
|
||||
14
src/pages/requests.astro
Normal file
14
src/pages/requests.astro
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
import BaseLayout from 'layouts/base.astro'
|
||||
import DefaultSEO from 'components/DefaultSEO.astro'
|
||||
import RequestsTable from 'components/requests/RequestsTable'
|
||||
|
||||
import prismaClient from 'utils/prisma-client'
|
||||
|
||||
const initialRequests = await prismaClient.requests.findMany({ orderBy: { createdAt: 'desc' } })
|
||||
---
|
||||
|
||||
<DefaultSEO />
|
||||
<BaseLayout>
|
||||
<RequestsTable client:only='react' initial={initialRequests} />
|
||||
</BaseLayout>
|
||||
12
src/schemas/requests.ts
Normal file
12
src/schemas/requests.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import { RequestState } from '@prisma/client'
|
||||
import { object, string, number, optional, enums } from 'superstruct'
|
||||
|
||||
export const EditRequest = object({
|
||||
id: number(),
|
||||
title: optional(string()),
|
||||
link: optional(string()),
|
||||
state: enums(Object.values(RequestState)),
|
||||
reason: optional(string()),
|
||||
comments: optional(string()),
|
||||
message: optional(string())
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue