Initial commit: Personal Dashboard
Next.js 16 dashboard with configurable widgets (favorites, notes, calendar, clock, calculator, search, domain-check), multi-tab support, user auth, dark mode, and Docker deployment. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+106
@@ -0,0 +1,106 @@
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import bcrypt from "bcryptjs";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
function normalizeEmail(value) {
|
||||
const email = String(value ?? "").trim().toLowerCase();
|
||||
|
||||
if (!email) {
|
||||
return "admin@example.local";
|
||||
}
|
||||
|
||||
return email;
|
||||
}
|
||||
|
||||
function normalizePassword(value) {
|
||||
const password = String(value ?? "").trim();
|
||||
|
||||
if (!password) {
|
||||
return "BitteEinLangesSicheresPasswortSetzen";
|
||||
}
|
||||
|
||||
return password;
|
||||
}
|
||||
|
||||
async function ensureUserSettings(userId, email) {
|
||||
const existingSettings = await prisma.settings.findUnique({
|
||||
where: {
|
||||
userId
|
||||
}
|
||||
});
|
||||
|
||||
if (existingSettings) {
|
||||
return existingSettings;
|
||||
}
|
||||
|
||||
return prisma.settings.create({
|
||||
data: {
|
||||
userId,
|
||||
darkMode: false,
|
||||
calendarIcsUrl: null,
|
||||
calendarMaxEvents: 8,
|
||||
calendarLookaheadDays: 60,
|
||||
dashboardTitle: "Personal Dashboard",
|
||||
dashboardSubtitle: email,
|
||||
logoUrl: "/logo.svg",
|
||||
backgroundImageUrl: "/background-fancy.svg",
|
||||
backgroundImageOpacity: 32,
|
||||
primaryColor: "#2563eb",
|
||||
secondaryColor: "#dbeafe"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const initialAdminEmail = normalizeEmail(process.env.INITIAL_ADMIN_EMAIL);
|
||||
const initialAdminPassword = normalizePassword(process.env.INITIAL_ADMIN_PASSWORD);
|
||||
|
||||
const existingAdmin = await prisma.user.findUnique({
|
||||
where: {
|
||||
email: initialAdminEmail
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
email: true,
|
||||
role: true
|
||||
}
|
||||
});
|
||||
|
||||
if (existingAdmin) {
|
||||
await ensureUserSettings(existingAdmin.id, existingAdmin.email);
|
||||
console.log("Initialer Admin existiert bereits. Seed übersprungen.");
|
||||
return;
|
||||
}
|
||||
|
||||
const passwordHash = await bcrypt.hash(initialAdminPassword, 12);
|
||||
|
||||
const admin = await prisma.user.create({
|
||||
data: {
|
||||
email: initialAdminEmail,
|
||||
passwordHash,
|
||||
displayName: "Admin",
|
||||
profileImageUrl: null,
|
||||
role: "ADMIN"
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
email: true
|
||||
}
|
||||
});
|
||||
|
||||
await ensureUserSettings(admin.id, admin.email);
|
||||
|
||||
console.log("Initialer Admin wurde erstellt.");
|
||||
console.log(`E-Mail: ${admin.email}`);
|
||||
console.log("Dashboard startet leer. Es wurden keine Widgets und keine Favoriten angelegt.");
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
})
|
||||
.finally(async () => {
|
||||
await prisma.$disconnect();
|
||||
});
|
||||
Reference in New Issue
Block a user