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
|
||||
DISCORD_CLIENT_ID=""
|
||||
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/react-query": "^10.9.0",
|
||||
"@trpc/server": "^10.9.0",
|
||||
"argon2": "^0.30.3",
|
||||
"dotenv": "^16.0.3",
|
||||
"next": "^13.2.1",
|
||||
"next-auth": "^4.19.0",
|
||||
"next-ssl-redirect-middleware": "^0.1.4",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"superjson": "1.9.1",
|
||||
"ts-node": "^10.9.1",
|
||||
"zod": "^3.20.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/eslint": "^8.21.1",
|
||||
"@types/node": "^18.14.0",
|
||||
"@types/node": "^18.16.6",
|
||||
"@types/prettier": "^2.7.2",
|
||||
"@types/react": "^18.0.28",
|
||||
"@types/react-dom": "^18.0.11",
|
||||
@ -46,13 +47,14 @@
|
||||
"eslint-config-next": "^13.2.1",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"husky": "^8.0.0",
|
||||
"postcss": "^8.4.14",
|
||||
"prettier": "^2.8.1",
|
||||
"prettier-plugin-tailwindcss": "^0.2.1",
|
||||
"prisma": "^4.9.0",
|
||||
"tailwindcss": "^3.2.0",
|
||||
"typescript": "^4.9.5",
|
||||
"husky": "^8.0.0"
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.9.5"
|
||||
},
|
||||
"ct3aMetadata": {
|
||||
"initVersion": "7.7.0"
|
||||
|
@ -72,25 +72,6 @@ model AuditoryResource {
|
||||
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 {
|
||||
id String @id @default(auto()) @map("_id") @db.ObjectId
|
||||
sessionToken String @unique
|
||||
@ -100,13 +81,11 @@ model Session {
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(auto()) @map("_id") @db.ObjectId
|
||||
name String?
|
||||
email String? @unique
|
||||
emailVerified DateTime?
|
||||
image String?
|
||||
accounts Account[]
|
||||
sessions Session[]
|
||||
id String @id @default(auto()) @map("_id") @db.ObjectId
|
||||
name String?
|
||||
username String? @unique
|
||||
password String
|
||||
sessions Session[]
|
||||
}
|
||||
|
||||
model VerificationToken {
|
||||
|
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 (
|
||||
<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}
|
||||
</div>
|
||||
);
|
||||
|
@ -48,7 +48,7 @@ const GreetingPage = ({
|
||||
</p>
|
||||
<button
|
||||
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!
|
||||
</button>
|
||||
@ -177,13 +177,13 @@ const QuestionPage = ({
|
||||
<div className="space-x-4">
|
||||
<button
|
||||
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
|
||||
</button>
|
||||
<button
|
||||
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
|
||||
</button>
|
||||
@ -192,14 +192,14 @@ const QuestionPage = ({
|
||||
<div className="mt-4 flex flex-col space-y-2">
|
||||
<button
|
||||
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
|
||||
</button>
|
||||
<button
|
||||
form="search-form"
|
||||
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
|
||||
</button>
|
||||
|
@ -105,7 +105,7 @@ const About: NextPage = () => {
|
||||
</h1>
|
||||
</div>
|
||||
{/** 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">
|
||||
Meet the Team
|
||||
<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 (
|
||||
<Link
|
||||
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}
|
||||
<ArrowUpRightIcon className="inline-block w-4" />
|
||||
@ -58,7 +58,7 @@ const Home: NextPage = () => {
|
||||
</div>
|
||||
<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">
|
||||
<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">
|
||||
<p className="pt-2">
|
||||
You can use the <TextLink href="/resources">Resources</TextLink>{" "}
|
||||
@ -81,7 +81,7 @@ const Home: NextPage = () => {
|
||||
</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">
|
||||
<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">
|
||||
Our Purpose
|
||||
</h1>
|
||||
|
@ -150,7 +150,7 @@ const ResourceViewPage = (
|
||||
description={resourceQuery.data.description}
|
||||
/>
|
||||
</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">
|
||||
Ages {resourceQuery.data.ages.min}
|
||||
{resourceQuery.data.ages.max >= 100
|
||||
|
@ -31,7 +31,7 @@ const Resources = () => {
|
||||
return (
|
||||
<>
|
||||
<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">
|
||||
<h1 className="text-3xl font-bold">All Resources</h1>
|
||||
<div className="">
|
||||
|
@ -113,7 +113,7 @@ const SearchPage = () => {
|
||||
<div className="snap-start snap-always">
|
||||
<Header />
|
||||
</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} />
|
||||
</div>
|
||||
<div className="snap-end snap-always">
|
||||
|
Loading…
x
Reference in New Issue
Block a user