add database seeding for admin user
This commit is contained in:
parent
23cf2d3e01
commit
6cef945bdf
@ -19,3 +19,6 @@ DATABASE_URL=
|
|||||||
# Next Auth Discord Provider
|
# Next Auth Discord Provider
|
||||||
DISCORD_CLIENT_ID=""
|
DISCORD_CLIENT_ID=""
|
||||||
DISCORD_CLIENT_SECRET=""
|
DISCORD_CLIENT_SECRET=""
|
||||||
|
|
||||||
|
# Admin account details
|
||||||
|
ADMIN_PASSWORD="password"
|
3507
package-lock.json
generated
3507
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@ -24,18 +24,19 @@
|
|||||||
"@trpc/next": "^10.9.0",
|
"@trpc/next": "^10.9.0",
|
||||||
"@trpc/react-query": "^10.9.0",
|
"@trpc/react-query": "^10.9.0",
|
||||||
"@trpc/server": "^10.9.0",
|
"@trpc/server": "^10.9.0",
|
||||||
|
"argon2": "^0.30.3",
|
||||||
|
"dotenv": "^16.0.3",
|
||||||
"next": "^13.2.1",
|
"next": "^13.2.1",
|
||||||
"next-auth": "^4.19.0",
|
"next-auth": "^4.19.0",
|
||||||
"next-ssl-redirect-middleware": "^0.1.4",
|
"next-ssl-redirect-middleware": "^0.1.4",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"superjson": "1.9.1",
|
"superjson": "1.9.1",
|
||||||
"ts-node": "^10.9.1",
|
|
||||||
"zod": "^3.20.6"
|
"zod": "^3.20.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/eslint": "^8.21.1",
|
"@types/eslint": "^8.21.1",
|
||||||
"@types/node": "^18.14.0",
|
"@types/node": "^18.16.6",
|
||||||
"@types/prettier": "^2.7.2",
|
"@types/prettier": "^2.7.2",
|
||||||
"@types/react": "^18.0.28",
|
"@types/react": "^18.0.28",
|
||||||
"@types/react-dom": "^18.0.11",
|
"@types/react-dom": "^18.0.11",
|
||||||
@ -46,13 +47,14 @@
|
|||||||
"eslint-config-next": "^13.2.1",
|
"eslint-config-next": "^13.2.1",
|
||||||
"eslint-config-prettier": "^8.8.0",
|
"eslint-config-prettier": "^8.8.0",
|
||||||
"eslint-plugin-prettier": "^4.2.1",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
|
"husky": "^8.0.0",
|
||||||
"postcss": "^8.4.14",
|
"postcss": "^8.4.14",
|
||||||
"prettier": "^2.8.1",
|
"prettier": "^2.8.1",
|
||||||
"prettier-plugin-tailwindcss": "^0.2.1",
|
"prettier-plugin-tailwindcss": "^0.2.1",
|
||||||
"prisma": "^4.9.0",
|
"prisma": "^4.9.0",
|
||||||
"tailwindcss": "^3.2.0",
|
"tailwindcss": "^3.2.0",
|
||||||
"typescript": "^4.9.5",
|
"ts-node": "^10.9.1",
|
||||||
"husky": "^8.0.0"
|
"typescript": "^4.9.5"
|
||||||
},
|
},
|
||||||
"ct3aMetadata": {
|
"ct3aMetadata": {
|
||||||
"initVersion": "7.7.0"
|
"initVersion": "7.7.0"
|
||||||
|
@ -72,25 +72,6 @@ model AuditoryResource {
|
|||||||
platform_links PlatformLink[]
|
platform_links PlatformLink[]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Necessary for Next auth
|
|
||||||
model Account {
|
|
||||||
id String @id @default(auto()) @map("_id") @db.ObjectId
|
|
||||||
userId String @db.ObjectId
|
|
||||||
type String
|
|
||||||
provider String
|
|
||||||
providerAccountId String
|
|
||||||
refresh_token String? // @db.Text
|
|
||||||
access_token String? // @db.Text
|
|
||||||
expires_at Int?
|
|
||||||
token_type String?
|
|
||||||
scope String?
|
|
||||||
id_token String? // @db.Text
|
|
||||||
session_state String?
|
|
||||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
||||||
|
|
||||||
@@unique([provider, providerAccountId])
|
|
||||||
}
|
|
||||||
|
|
||||||
model Session {
|
model Session {
|
||||||
id String @id @default(auto()) @map("_id") @db.ObjectId
|
id String @id @default(auto()) @map("_id") @db.ObjectId
|
||||||
sessionToken String @unique
|
sessionToken String @unique
|
||||||
@ -102,10 +83,8 @@ model Session {
|
|||||||
model User {
|
model User {
|
||||||
id String @id @default(auto()) @map("_id") @db.ObjectId
|
id String @id @default(auto()) @map("_id") @db.ObjectId
|
||||||
name String?
|
name String?
|
||||||
email String? @unique
|
username String? @unique
|
||||||
emailVerified DateTime?
|
password String
|
||||||
image String?
|
|
||||||
accounts Account[]
|
|
||||||
sessions Session[]
|
sessions Session[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
35
prisma/seed.ts
Normal file
35
prisma/seed.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { PrismaClient } from "@prisma/client";
|
||||||
|
import * as argon2 from "argon2";
|
||||||
|
import * as dotenv from "dotenv";
|
||||||
|
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
|
const prisma = new PrismaClient(); // Prisma client instance
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Seed the database with admin user
|
||||||
|
*/
|
||||||
|
async function main() {
|
||||||
|
const hashedPassword = await argon2.hash(
|
||||||
|
process.env.ADMIN_PASSWORD as string
|
||||||
|
);
|
||||||
|
|
||||||
|
await prisma.user.upsert({
|
||||||
|
where: { username: "admin" },
|
||||||
|
update: {},
|
||||||
|
create: {
|
||||||
|
name: "Admin User",
|
||||||
|
username: "admin",
|
||||||
|
password: hashedPassword,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
|
.then(async () => {
|
||||||
|
await prisma.$disconnect();
|
||||||
|
})
|
||||||
|
.catch(async (e) => {
|
||||||
|
console.error(e);
|
||||||
|
await prisma.$disconnect();
|
||||||
|
});
|
@ -31,7 +31,7 @@ const NavBarLink = ({ href, label, dropdown }: NavBarLinkProps) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="absolute right-0 left-0 top-full hidden w-full flex-col rounded-b border-l-2 border-r-2 border-b-2 border-neutral-900 group-hover:flex">
|
<div className="absolute left-0 right-0 top-full hidden w-full flex-col rounded-b border-b-2 border-l-2 border-r-2 border-neutral-900 group-hover:flex">
|
||||||
{options}
|
{options}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -48,7 +48,7 @@ const GreetingPage = ({
|
|||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
onClick={getStartedClick}
|
onClick={getStartedClick}
|
||||||
className="bottom-0 mx-auto mt-8 rounded-md border border-neutral-900 bg-yellow-100 py-2 px-4 shadow-lg duration-200 ease-out hover:bg-yellow-300 hover:shadow-md"
|
className="bottom-0 mx-auto mt-8 rounded-md border border-neutral-900 bg-yellow-100 px-4 py-2 shadow-lg duration-200 ease-out hover:bg-yellow-300 hover:shadow-md"
|
||||||
>
|
>
|
||||||
Get Started!
|
Get Started!
|
||||||
</button>
|
</button>
|
||||||
@ -177,13 +177,13 @@ const QuestionPage = ({
|
|||||||
<div className="space-x-4">
|
<div className="space-x-4">
|
||||||
<button
|
<button
|
||||||
onClick={backClick}
|
onClick={backClick}
|
||||||
className="bottom-0 mx-auto mx-auto inline rounded-md border border-neutral-900 bg-yellow-100 py-2 px-4 shadow-lg duration-200 ease-out hover:bg-yellow-300 hover:shadow-md"
|
className="bottom-0 mx-auto mx-auto inline rounded-md border border-neutral-900 bg-yellow-100 px-4 py-2 shadow-lg duration-200 ease-out hover:bg-yellow-300 hover:shadow-md"
|
||||||
>
|
>
|
||||||
back
|
back
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={nextClick}
|
onClick={nextClick}
|
||||||
className="bottom-0 mx-auto mx-auto inline rounded-md border border-neutral-900 bg-yellow-100 py-2 px-4 shadow-lg duration-200 ease-out hover:bg-yellow-300 hover:shadow-md"
|
className="bottom-0 mx-auto mx-auto inline rounded-md border border-neutral-900 bg-yellow-100 px-4 py-2 shadow-lg duration-200 ease-out hover:bg-yellow-300 hover:shadow-md"
|
||||||
>
|
>
|
||||||
next
|
next
|
||||||
</button>
|
</button>
|
||||||
@ -192,14 +192,14 @@ const QuestionPage = ({
|
|||||||
<div className="mt-4 flex flex-col space-y-2">
|
<div className="mt-4 flex flex-col space-y-2">
|
||||||
<button
|
<button
|
||||||
onClick={backClick}
|
onClick={backClick}
|
||||||
className="bottom-0 mx-auto mx-auto rounded-md border border-neutral-900 bg-yellow-100 py-2 px-4 shadow-lg duration-200 ease-out hover:bg-yellow-300 hover:shadow-md"
|
className="bottom-0 mx-auto mx-auto rounded-md border border-neutral-900 bg-yellow-100 px-4 py-2 shadow-lg duration-200 ease-out hover:bg-yellow-300 hover:shadow-md"
|
||||||
>
|
>
|
||||||
back
|
back
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
form="search-form"
|
form="search-form"
|
||||||
type="submit"
|
type="submit"
|
||||||
className="bottom-0 mx-auto mx-auto rounded-md border border-neutral-900 bg-yellow-100 py-2 px-4 shadow-lg duration-200 ease-out hover:bg-yellow-300 hover:shadow-md"
|
className="bottom-0 mx-auto mx-auto rounded-md border border-neutral-900 bg-yellow-100 px-4 py-2 shadow-lg duration-200 ease-out hover:bg-yellow-300 hover:shadow-md"
|
||||||
>
|
>
|
||||||
submit
|
submit
|
||||||
</button>
|
</button>
|
||||||
|
@ -105,7 +105,7 @@ const About: NextPage = () => {
|
|||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
{/** Large screens */}
|
{/** Large screens */}
|
||||||
<div className="mx-auto mx-auto mt-8 mb-20 hidden w-max rounded-xl border-2 border-neutral-300 bg-neutral-900 p-4 shadow-xl sm:block">
|
<div className="mx-auto mx-auto mb-20 mt-8 hidden w-max rounded-xl border-2 border-neutral-300 bg-neutral-900 p-4 shadow-xl sm:block">
|
||||||
<h1 className="text-center text-4xl font-bold text-white">
|
<h1 className="text-center text-4xl font-bold text-white">
|
||||||
Meet the Team
|
Meet the Team
|
||||||
<HandRaisedIcon className="ml-4 inline w-12 rotate-12 animate-hand_wave text-yellow-200" />
|
<HandRaisedIcon className="ml-4 inline w-12 rotate-12 animate-hand_wave text-yellow-200" />
|
||||||
|
@ -8,7 +8,7 @@ const TextLink = ({ href, children }: { href: string; children: string }) => {
|
|||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
href={href}
|
href={href}
|
||||||
className="align-items-center inline-block rounded-md border border-neutral-900 py-[2px] px-[4px] text-sm hover:bg-neutral-900 hover:text-white"
|
className="align-items-center inline-block rounded-md border border-neutral-900 px-[4px] py-[2px] text-sm hover:bg-neutral-900 hover:text-white"
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
<ArrowUpRightIcon className="inline-block w-4" />
|
<ArrowUpRightIcon className="inline-block w-4" />
|
||||||
@ -58,7 +58,7 @@ const Home: NextPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
<main>
|
<main>
|
||||||
<section className="grid min-h-[300px] place-items-center border border-b border-neutral-400 bg-yellow-100 p-4 text-white drop-shadow-md sm:p-12">
|
<section className="grid min-h-[300px] place-items-center border border-b border-neutral-400 bg-yellow-100 p-4 text-white drop-shadow-md sm:p-12">
|
||||||
<div className="flex max-w-5xl flex-col-reverse justify-center divide-neutral-700 md:flex-row md:divide-y-0 md:divide-x">
|
<div className="flex max-w-5xl flex-col-reverse justify-center divide-neutral-700 md:flex-row md:divide-x md:divide-y-0">
|
||||||
<section className="px-4 text-neutral-800">
|
<section className="px-4 text-neutral-800">
|
||||||
<p className="pt-2">
|
<p className="pt-2">
|
||||||
You can use the <TextLink href="/resources">Resources</TextLink>{" "}
|
You can use the <TextLink href="/resources">Resources</TextLink>{" "}
|
||||||
@ -81,7 +81,7 @@ const Home: NextPage = () => {
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section className="grid min-h-[300px] place-items-center border-y border-t border-yellow-200 bg-neutral-900 p-4 text-white sm:p-12">
|
<section className="grid min-h-[300px] place-items-center border-y border-t border-yellow-200 bg-neutral-900 p-4 text-white sm:p-12">
|
||||||
<div className="my-auto mx-auto flex max-w-5xl flex-col divide-y divide-white md:flex-row md:divide-y-0 md:divide-x">
|
<div className="mx-auto my-auto flex max-w-5xl flex-col divide-y divide-white md:flex-row md:divide-x md:divide-y-0">
|
||||||
<h1 className="pr-auto my-auto h-full grow p-4 text-center text-4xl font-bold text-yellow-200">
|
<h1 className="pr-auto my-auto h-full grow p-4 text-center text-4xl font-bold text-yellow-200">
|
||||||
Our Purpose
|
Our Purpose
|
||||||
</h1>
|
</h1>
|
||||||
|
@ -150,7 +150,7 @@ const ResourceViewPage = (
|
|||||||
description={resourceQuery.data.description}
|
description={resourceQuery.data.description}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="ml-4 mt-4 mr-auto rounded-lg border-2 border-neutral-900 bg-neutral-600">
|
<div className="ml-4 mr-auto mt-4 rounded-lg border-2 border-neutral-900 bg-neutral-600">
|
||||||
<span className="px-2 py-2 text-sm text-neutral-200">
|
<span className="px-2 py-2 text-sm text-neutral-200">
|
||||||
Ages {resourceQuery.data.ages.min}
|
Ages {resourceQuery.data.ages.min}
|
||||||
{resourceQuery.data.ages.max >= 100
|
{resourceQuery.data.ages.max >= 100
|
||||||
|
@ -31,7 +31,7 @@ const Resources = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Header />
|
<Header />
|
||||||
<main className="my-6 mx-auto max-w-6xl md:px-4">
|
<main className="mx-auto my-6 max-w-6xl md:px-4">
|
||||||
<div className="mb-2 space-y-2 p-2 sm:mb-4 sm:p-4">
|
<div className="mb-2 space-y-2 p-2 sm:mb-4 sm:p-4">
|
||||||
<h1 className="text-3xl font-bold">All Resources</h1>
|
<h1 className="text-3xl font-bold">All Resources</h1>
|
||||||
<div className="">
|
<div className="">
|
||||||
|
@ -113,7 +113,7 @@ const SearchPage = () => {
|
|||||||
<div className="snap-start snap-always">
|
<div className="snap-start snap-always">
|
||||||
<Header />
|
<Header />
|
||||||
</div>
|
</div>
|
||||||
<div className="mx-auto mt-4 mb-4 w-full max-w-xl snap-center snap-always overflow-hidden rounded-xl border border-neutral-400 bg-neutral-200 drop-shadow-md">
|
<div className="mx-auto mb-4 mt-4 w-full max-w-xl snap-center snap-always overflow-hidden rounded-xl border border-neutral-400 bg-neutral-200 drop-shadow-md">
|
||||||
<GuidedSearch questions={questions} />
|
<GuidedSearch questions={questions} />
|
||||||
</div>
|
</div>
|
||||||
<div className="snap-end snap-always">
|
<div className="snap-end snap-always">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user