Nicholai 98a4c8f7db
Some checks failed
Build and Push to Docker Hub / Push Docker image to Docker Hub (push) Has been cancelled
Build and Push Docker Image / build-and-push (push) Has been cancelled
Fixed uploading and database integration, slightly updated NAV and made admin functionality live
2025-08-16 11:46:04 -06:00

345 lines
9.2 KiB
TypeScript

import { PrismaClient, Size, AssetType } from '@prisma/client'
import bcrypt from 'bcryptjs'
// @ts-ignore
import blogPosts from '../public/blog/blog-posts.json'
const prisma = new PrismaClient()
async function main() {
// Create initial admin user
const hashedPassword = await bcrypt.hash('@Biohazard12', 10)
const adminUser = await prisma.user.upsert({
where: { email: 'admin@biohazardvfx.com' },
update: {
// Ensure admin password matches the expected value
password: hashedPassword,
},
create: {
email: 'admin@biohazardvfx.com',
name: 'Biohazard Admin',
password: hashedPassword,
role: 'ADMIN',
},
})
// Seed team members
const teamMembers = [
{
name: 'Nicholai Vogel',
title: 'Founder & CEO',
quote: '"I just work here."',
image: '/images/nicholai.jpg',
instagram: 'https://www.instagram.com/nicholai.exe/',
},
{
name: 'DAVANÉ',
title: 'Co-Founder',
quote: '"The Executive"',
image: '/images/davane.jpg',
instagram: 'https://www.instagram.com/davaneh/',
},
{
name: 'Parth Gupta',
title: 'Co-Founder',
quote: '"Hates Matchmove"',
image: '/images/parth.jpg',
instagram: 'https://www.instagram.com/nuke_fx/',
},
]
for (const member of teamMembers) {
// Check if team member exists by name
const existingMember = await prisma.teamMember.findFirst({
where: { name: member.name },
})
if (existingMember) {
// Update existing member
await prisma.teamMember.update({
where: { id: existingMember.id },
data: member,
})
} else {
// Create new member
await prisma.teamMember.create({
data: member,
})
}
}
// Seed initial FAQs
const faqs = [
{
question: 'What services do you offer?',
answer:
'We provide comprehensive VFX services including supervision, 3D animation, compositing, and post-production finishing.',
},
{
question: 'How long have you been in business?',
answer:
'Biohazard VFX was founded in 2023, bringing together experienced VFX artists from around the world.',
},
]
for (const faq of faqs) {
// Check if FAQ exists by question
const existingFaq = await prisma.fAQ.findFirst({
where: { question: faq.question },
})
if (existingFaq) {
// Update existing FAQ
await prisma.fAQ.update({
where: { id: existingFaq.id },
data: faq,
})
} else {
// Create new FAQ
await prisma.fAQ.create({
data: faq,
})
}
}
// Seed blog posts
for (const post of blogPosts) {
// Find or create author
let author = await prisma.user.findFirst({
where: { name: post.author },
})
if (!author) {
// Create user if doesn't exist
const authorEmail = `${post.author.toLowerCase().replace(/\s+/g, '.')}@biohazardvfx.com`
author = await prisma.user.create({
data: {
email: authorEmail,
name: post.author,
password: await bcrypt.hash('biohazardblog2025!', 10),
role: 'EDITOR',
},
})
}
// Check if blog post exists by slug
const existingPost = await prisma.blogPost.findFirst({
where: { slug: post.slug },
})
if (existingPost) {
// Update existing post
await prisma.blogPost.update({
where: { id: existingPost.id },
data: {
title: post.title,
content: post.content,
excerpt: post.excerpt,
featuredImage: post.featuredImage,
category: post.tags?.[0] || null,
tags: post.tags ? JSON.stringify(post.tags) : null,
published: true,
publishedAt: new Date(post.date),
authorId: author.id,
},
})
} else {
// Create new post
await prisma.blogPost.create({
data: {
title: post.title,
slug: post.slug,
content: post.content,
excerpt: post.excerpt,
featuredImage: post.featuredImage,
category: post.tags?.[0] || null,
tags: post.tags ? JSON.stringify(post.tags) : null,
published: true,
publishedAt: new Date(post.date),
authorId: author.id,
},
})
}
}
// Seed projects
const projects = [
{
id: 'Reel',
title: 'Biohazard VFX Showreel',
thumbnail: '/projects/Reel/thumbnail.jpg',
size: Size.BIG,
embed: 'https://f.io/2bfzI989',
credits: '/projects/Reel/credits.txt',
info: '/projects/Reel/info.txt',
category: 'Showreel',
featured: true,
published: true,
},
{
id: 'HDSH',
title: 'Post Malone Ft. Morgan Wallen - "I Had Some Help"',
thumbnail: '/projects/Reel/thumbnail.jpg',
size: Size.SMALL,
embed: 'https://www.youtube.com/embed/4QIZE708gJ4?si=jYPjgJaMB-OksuYL',
credits: '/projects/HDSH/credits.txt',
info: '/projects/HDSH/info.txt',
category: 'Music Video',
published: true,
},
{
id: 'J305',
title: '"305" Jordan Adetunji ft Bryson Tiller',
thumbnail: '/projects/J305/thumbnail.jpg',
size: Size.SMALL,
embed: 'https://www.youtube.com/embed/aeliAWeQoYA?si=lKAjxXV8NciGzxpU',
credits: '/projects/J305/credits.txt',
info: '/projects/J305/info.txt',
category: 'Music Video',
published: true,
},
{
id: 'ARSD',
title: 'The Temper Trap - Sweet Disposition (ARTBAT Remix)',
thumbnail: '/projects/ARSD/thumbnail.jpg',
size: Size.SMALL,
embed: 'https://www.youtube.com/embed/4OeprBdP3hY?si=BgiJ-75Jf039evq3',
credits: '/projects/ARSD/credits.txt',
info: '/projects/ARSD/info.txt',
category: 'Music Video',
published: true,
},
{
id: 'HLLS',
title: '2Hollis "Album Trailer"',
thumbnail: '/projects/HLLS/thumbnail.jpg',
size: Size.SMALL,
video: '/projects/HLLS/video.mp4',
credits: '/projects/HLLS/credits.txt',
info: '/projects/HLLS/info.txt',
category: 'Trailer',
published: true,
},
{
id: 'ENBD',
title: 'Enhypen "Bad Desire"',
thumbnail: '/projects/ENBD/thumbnail.jpg',
size: Size.SMALL,
embed: 'https://www.youtube.com/embed/a2Zqdo9RbNs?si=eybihPJFXvoCFcNK',
credits: '/projects/ENBD/credits.txt',
info: '/projects/ENBD/info.txt',
category: 'Music Video',
published: true,
},
{
id: 'APTS',
title: 'SNIPES x Adidas — 2024 Holiday Campaign',
thumbnail: '/projects/APTS/thumbnail.jpg',
size: Size.SMALL,
embed:
'https://player.vimeo.com/video/1065352037?badge=0&autopause=0&player_id=0&app_id=58479',
credits: '/projects/APTS/credits.txt',
info: '/projects/APTS/info.txt',
category: 'Commercial',
published: true,
},
{
id: '01_OTFR',
title: '1900Rugrat "One Take Freestyle"',
thumbnail: '/projects/01_OTFR/thumbnail.jpg',
size: Size.SMALL,
embed: 'https://nextcloud.biohazardvfx.com/s/58mKn3q5ePzN88t',
credits: '/projects/01_OTFR/credits.txt',
info: '/projects/01_OTFR/info.txt',
category: 'Music Video',
published: true,
},
]
for (const project of projects) {
await prisma.project.upsert({
where: { id: project.id },
update: project,
create: project,
})
}
// Seed site assets (backgrounds, hero media)
const siteAssets: {
key: string
label: string
type: AssetType
url: string
alt?: string
}[] = [
{
key: 'home.hero.image',
label: 'Home Hero Background',
type: AssetType.IMAGE,
url: '/images/Splash.jpg',
alt: 'Biohazard VFX hero background',
},
{
key: 'projects.hero.image',
label: 'Projects Header Background',
type: AssetType.IMAGE,
url: '/images/projects-header.jpg',
alt: 'Projects header background',
},
{
key: 'blog.hero.image',
label: 'Blog Header Background',
type: AssetType.IMAGE,
url: '/images/blog-header.jpg',
alt: 'Blog header background',
},
{
key: 'crew.hero.image',
label: 'Crew/Team Header Background',
type: AssetType.IMAGE,
url: '/images/team-collaboration.jpg',
alt: 'Crew header background',
},
{
key: 'contact.hero.image',
label: 'Contact Header Background',
type: AssetType.IMAGE,
url: '/images/contact-studio.jpg',
alt: 'Contact header background',
},
{
key: 'about.hero.image',
label: 'About/Studio Header Background',
type: AssetType.IMAGE,
url: '/images/about-studio.jpg',
alt: 'Studio header background',
},
{
key: 'home.showreel.video',
label: 'Home Showreel Video',
type: AssetType.VIDEO,
url: '/videos/reel.mp4',
alt: 'Showreel video',
},
]
for (const asset of siteAssets) {
await prisma.siteAsset.upsert({
where: { key: asset.key },
update: asset,
create: asset,
})
}
console.log('Seed data created successfully')
}
main()
.catch((e) => {
console.error(e)
process.exit(1)
})
.finally(async () => {
await prisma.$disconnect()
})