[admin] feat: initial commit
(cherry picked from commit fe7a9f9dd3abe2bba351ce58435b5c4bd2d97f8a)
This commit is contained in:
parent
b013d54ef5
commit
611dbc37e9
|
|
@ -0,0 +1,20 @@
|
|||
REDDIT_CLIENT_ID=your_client_id
|
||||
REDDIT_CLIENT_SECRET=your_client_secret
|
||||
REDDIT_USER_AGENT=your_user_agent
|
||||
|
||||
GOOGLE_GENERATIVE_AI_API_KEY=your_api_key
|
||||
|
||||
DATABASE_URL=postgresql://postgres:[YOUR-PASSWORD]@db.[SUPABASE_REFERENCE_ID].supabase.co:6543/postgres?pgbouncer=true&connection_limit=30&pool_timeout=600
|
||||
DIRECT_URL=postgresql://postgres:[YOUR-PASSWORD]@db.[SUPABASE_REFERENCE_ID].supabase.com:5432/postgres
|
||||
|
||||
NEXTAUTH_SECRET=secret_key
|
||||
NEXTAUTH_URL=http://localhost:3000
|
||||
|
||||
AUTH_GOOGLE_ID=google_id
|
||||
AUTH_GOOGLE_SECRET=google_secret
|
||||
|
||||
PASSWORD_KEY=some_random_value
|
||||
|
||||
GOOGLE_CHAT_WEBHOOK_URL=google_chat_webhook_url
|
||||
|
||||
CRON_SECRET=some_random_value
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
.yarn/*
|
||||
|
||||
!.yarn/patches
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
# primsa
|
||||
/prisma/generated/*
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# local env files
|
||||
.env
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
tsconfig.tsbuildinfo
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
src/__generated__
|
||||
src/supabase/database.types.ts
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"typescript.enablePromptUseWorkspaceTsdk": true
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
## Getting Started
|
||||
|
||||
First, run the development server:
|
||||
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
|
||||
You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
|
||||
|
||||
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
|
||||
|
||||
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
|
||||
|
||||
## Learn More
|
||||
|
||||
To learn more about Next.js, take a look at the following resources:
|
||||
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||
- [Learn Next.js](https://nextjs.org/learn/foundations/about-nextjs) - an interactive Next.js tutorial.
|
||||
|
||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
|
||||
|
||||
## Deploy on Vercel
|
||||
|
||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_source=github.com&utm_medium=referral&utm_campaign=turborepo-readme) from the creators of Next.js.
|
||||
|
||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
import nextConfig from '@gfe/eslint-config/next';
|
||||
|
||||
/** @type {import("eslint").Linter.Config} */
|
||||
export default nextConfig;
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
// @ts-check
|
||||
|
||||
import { PrismaPlugin } from '@prisma/nextjs-monorepo-workaround-plugin';
|
||||
/**
|
||||
* @type {import('next').NextConfig}
|
||||
**/
|
||||
const nextConfig = {
|
||||
pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'md', 'mdx'],
|
||||
reactStrictMode: true,
|
||||
experimental: {
|
||||
optimizePackageImports: ['@mantine/core', '@mantine/hooks'],
|
||||
},
|
||||
webpack: (config, { isServer }) => {
|
||||
if (isServer) {
|
||||
config.plugins = [...config.plugins, new PrismaPlugin()];
|
||||
}
|
||||
|
||||
return config;
|
||||
},
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"name": "@gfe/admin",
|
||||
"version": "0.0.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"check": "npm run tsc && npm run lint",
|
||||
"build": "next build",
|
||||
"dev": "next dev",
|
||||
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,md,mdx}\"",
|
||||
"start": "next start",
|
||||
"lint": "eslint src --fix",
|
||||
"tsc": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"clsx": "^2.1.1",
|
||||
"next": "14.2.15",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@gfe/eslint-config": "workspace:*",
|
||||
"@gfe/typescript-config": "workspace:*",
|
||||
"@next/eslint-plugin-next": "14.2.15",
|
||||
"@tailwindcss/aspect-ratio": "^0.4.2",
|
||||
"@tailwindcss/container-queries": "^0.1.1",
|
||||
"@tailwindcss/forms": "^0.5.10",
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"@types/react": "18.0.28",
|
||||
"@types/react-dom": "18.0.11",
|
||||
"eslint": "^9.26.0",
|
||||
"postcss": "^8.4.32",
|
||||
"prettier": "3.5.3",
|
||||
"prettier-plugin-tailwindcss": "0.6.11",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "5.8.3"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 763 B |
|
|
@ -0,0 +1,25 @@
|
|||
import clsx from 'clsx';
|
||||
import type { Metadata } from 'next';
|
||||
|
||||
import '~/styles/globals.css';
|
||||
|
||||
import RootLayout from '../components/RootLayout';
|
||||
|
||||
type Props = Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>;
|
||||
|
||||
export const metadata: Metadata = {
|
||||
description: 'Admin dashboard',
|
||||
title: 'GreatFrontEnd Admin',
|
||||
};
|
||||
|
||||
export default function Layout({ children }: Props) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className={clsx('antialiased', 'bg-white')}>
|
||||
<RootLayout>{children}</RootLayout>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
export default function Page() {
|
||||
return (
|
||||
<div className="flex h-screen items-center justify-center">
|
||||
<h1 className="text-2xl font-bold">Admin Dashboard</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
'use client';
|
||||
|
||||
type Props = Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>;
|
||||
|
||||
export default function RootLayout({ children }: Props) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,36 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@font-face {
|
||||
font-family: 'Inter var';
|
||||
font-weight: 100 900;
|
||||
font-display: swap;
|
||||
font-style: normal;
|
||||
font-named-instance: 'Regular';
|
||||
src: url('./fonts/Inter-roman-latin.var.woff2') format('woff2');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Inter var';
|
||||
font-weight: 100 900;
|
||||
font-display: swap;
|
||||
font-style: italic;
|
||||
font-named-instance: 'Italic';
|
||||
src: url('./fonts/Inter-italic-latin.var.woff2') format('woff2');
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
// @ts-check
|
||||
|
||||
const defaultTheme = require('tailwindcss/defaultTheme');
|
||||
|
||||
const neutral = {
|
||||
100: '#f4f4f5',
|
||||
200: '#e4e4e7',
|
||||
300: '#d4d4d8',
|
||||
400: '#a1a1aa',
|
||||
50: '#fafafa',
|
||||
500: '#71717a',
|
||||
600: '#52525b',
|
||||
700: '#484851',
|
||||
800: '#303036',
|
||||
900: '#252429',
|
||||
950: '#18181b',
|
||||
};
|
||||
|
||||
const indigo = {
|
||||
dark: '#7063f3',
|
||||
darker: '#5133cf',
|
||||
darkest: '#3a2888',
|
||||
DEFAULT: '#948cf9',
|
||||
light: '#bab5fd',
|
||||
lighter: '#d6d5fe',
|
||||
lightest: '#f3f0ff',
|
||||
};
|
||||
|
||||
const green = {
|
||||
dark: '#1a6a22',
|
||||
darker: '#0c3310',
|
||||
darkest: '#071c09',
|
||||
DEFAULT: '#28a635',
|
||||
light: '#39ea4a',
|
||||
lighter: '#97ffa2',
|
||||
lightest: '#ebffed',
|
||||
};
|
||||
|
||||
const orange = {
|
||||
dark: '#aa6729',
|
||||
darker: '#3f260f',
|
||||
darkest: '#221508',
|
||||
DEFAULT: '#f8963c',
|
||||
light: '#ffbf85',
|
||||
lighter: '#ffe3ca',
|
||||
lightest: '#fff9f3',
|
||||
};
|
||||
|
||||
const red = {
|
||||
dark: '#ad2a2a',
|
||||
darker: '#551515',
|
||||
darkest: '#2f0b0b',
|
||||
DEFAULT: '#ff5353',
|
||||
light: '#ff8d8d',
|
||||
lighter: '#ffe1e1',
|
||||
lightest: '#fff8f8',
|
||||
};
|
||||
|
||||
const blue = {
|
||||
dark: '#1d6379',
|
||||
darker: '#0e303b',
|
||||
darkest: '#081a20',
|
||||
DEFAULT: '#2e9cbe',
|
||||
light: '#47c5ee',
|
||||
lighter: '#c0f0ff',
|
||||
lightest: '#f1fcff',
|
||||
};
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: [
|
||||
'./app/**/*.{js,jsx,ts,tsx,md,mdx}',
|
||||
'./src/**/*.{js,jsx,ts,tsx,md,mdx}',
|
||||
'./questions/**/*.{js,jsx,ts,tsx,md,mdx}',
|
||||
],
|
||||
darkMode: ['class', '[data-mode="dark"]'],
|
||||
plugins: [
|
||||
require('@tailwindcss/aspect-ratio'),
|
||||
require('@tailwindcss/container-queries'),
|
||||
require('@tailwindcss/forms'),
|
||||
require('@tailwindcss/typography'),
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
animation: {
|
||||
marquee: 'marquee linear infinite',
|
||||
marquee2: 'marquee2 linear infinite',
|
||||
'slide-up': 'slide-up 0.3s ease-out',
|
||||
},
|
||||
boxShadow: {
|
||||
glow: '0 0 4px rgb(0 0 0 / 0.1)',
|
||||
},
|
||||
colors: {
|
||||
blue,
|
||||
brand: indigo,
|
||||
danger: red,
|
||||
gray: neutral,
|
||||
green,
|
||||
indigo,
|
||||
info: blue,
|
||||
neutral,
|
||||
orange,
|
||||
red,
|
||||
success: green,
|
||||
warning: orange,
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ['Inter var', ...defaultTheme.fontFamily.sans],
|
||||
},
|
||||
fontSize: {
|
||||
'2xs': ['0.625rem', { lineHeight: '0.875rem' }],
|
||||
},
|
||||
keyframes: {
|
||||
marquee: {
|
||||
'0%': { transform: 'translateX(0%)' },
|
||||
'100%': { transform: 'translateX(-100%)' },
|
||||
},
|
||||
marquee2: {
|
||||
'0%': { transform: 'translateX(100%)' },
|
||||
'100%': { transform: 'translateX(0%)' },
|
||||
},
|
||||
'slide-up': {
|
||||
'0%': { transform: 'translateY(100%)' },
|
||||
'100%': { transform: 'translateY(0%)' },
|
||||
},
|
||||
},
|
||||
letterSpacing: {
|
||||
1: '.015625em',
|
||||
2: '.03125em',
|
||||
3: '.046875em',
|
||||
4: '.0625em',
|
||||
},
|
||||
opacity: {
|
||||
1: '0.01',
|
||||
15: '0.15',
|
||||
2.5: '0.025',
|
||||
7.5: '0.075',
|
||||
},
|
||||
zIndex: {
|
||||
// Modified from: https://github.com/twbs/bootstrap/blob/main/scss/_variables.scss#L1133
|
||||
fixed: 30,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"extends": "@gfe/typescript-config/nextjs.json",
|
||||
"compilerOptions": {
|
||||
"plugins": [
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
],
|
||||
"baseUrl": "./src",
|
||||
"paths": {
|
||||
"~/*": ["*"],
|
||||
"~/prisma/client": ["../prisma/generated/client"]
|
||||
},
|
||||
"strictNullChecks": true
|
||||
},
|
||||
"include": ["next-env.d.ts", "src", ".next/types/**/*.ts", "types.d.ts"]
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
import type { DefaultUser } from 'next-auth';
|
||||
|
||||
declare module 'next-auth' {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
|
||||
interface Session {
|
||||
user: DefaultUser & {
|
||||
id: string;
|
||||
isAdmin?: boolean;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"github": {
|
||||
"silent": true
|
||||
},
|
||||
"crons": [
|
||||
{
|
||||
"path": "/api/reddit/crawl",
|
||||
"schedule": "0 */3 * * *"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -5,7 +5,8 @@
|
|||
"private": true,
|
||||
"exports": {
|
||||
".": "./index.js",
|
||||
"./next": "./next.js"
|
||||
"./next": "./next.js",
|
||||
"./react": "./react.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.26.0",
|
||||
|
|
|
|||
746
pnpm-lock.yaml
746
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue