refactors, specific day playtime controls
This commit is contained in:
@@ -1,176 +0,0 @@
|
||||
import Database from 'better-sqlite3';
|
||||
import bcrypt from 'bcryptjs';
|
||||
|
||||
async function setupDatabase() {
|
||||
const db = new Database('sqlite.db');
|
||||
|
||||
// Enable foreign keys
|
||||
db.pragma('foreign_keys = ON');
|
||||
|
||||
// Create tables
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id TEXT PRIMARY KEY,
|
||||
email TEXT NOT NULL UNIQUE,
|
||||
name TEXT NOT NULL,
|
||||
surname TEXT NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
role TEXT NOT NULL DEFAULT 'user' CHECK (role IN ('user', 'admin')),
|
||||
created_at INTEGER NOT NULL,
|
||||
updated_at INTEGER NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS courts (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
is_active INTEGER NOT NULL DEFAULT 1,
|
||||
created_at INTEGER NOT NULL,
|
||||
updated_at INTEGER NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS settings (
|
||||
id TEXT PRIMARY KEY,
|
||||
key TEXT NOT NULL UNIQUE,
|
||||
value TEXT NOT NULL,
|
||||
description TEXT,
|
||||
created_at INTEGER NOT NULL,
|
||||
updated_at INTEGER NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS time_slots (
|
||||
id TEXT PRIMARY KEY,
|
||||
start_time TEXT NOT NULL,
|
||||
end_time TEXT NOT NULL,
|
||||
is_active INTEGER NOT NULL DEFAULT 1,
|
||||
created_at INTEGER NOT NULL,
|
||||
updated_at INTEGER NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS bookings (
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT NOT NULL,
|
||||
court_id TEXT NOT NULL,
|
||||
date TEXT NOT NULL,
|
||||
time_slot_id TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'confirmed' CHECK (status IN ('confirmed', 'cancelled', 'pending')),
|
||||
created_at INTEGER NOT NULL,
|
||||
updated_at INTEGER NOT NULL,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id),
|
||||
FOREIGN KEY (court_id) REFERENCES courts(id),
|
||||
FOREIGN KEY (time_slot_id) REFERENCES time_slots(id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS announcements (
|
||||
id TEXT PRIMARY KEY,
|
||||
title TEXT NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
is_active INTEGER NOT NULL DEFAULT 1,
|
||||
created_at INTEGER NOT NULL,
|
||||
updated_at INTEGER NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS activity_logs (
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT NOT NULL,
|
||||
action TEXT NOT NULL,
|
||||
details TEXT,
|
||||
created_at INTEGER NOT NULL,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
`);
|
||||
|
||||
console.log('Tables created successfully!');
|
||||
|
||||
// Insert default admin user
|
||||
const now = Date.now();
|
||||
const adminPassword = await bcrypt.hash('admin123', 10);
|
||||
|
||||
try {
|
||||
const stmt = db.prepare(`
|
||||
INSERT OR IGNORE INTO users (id, email, name, surname, password, role, created_at, updated_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`);
|
||||
|
||||
stmt.run(
|
||||
'admin-' + crypto.randomUUID(),
|
||||
'admin@ttbooking.com',
|
||||
'Admin',
|
||||
'User',
|
||||
adminPassword,
|
||||
'admin',
|
||||
now,
|
||||
now
|
||||
);
|
||||
|
||||
console.log('Admin user created: admin@ttbooking.com / admin123');
|
||||
} catch (error) {
|
||||
console.log('Admin user might already exist');
|
||||
}
|
||||
|
||||
// Insert default courts
|
||||
try {
|
||||
const courtStmt = db.prepare(`
|
||||
INSERT OR IGNORE INTO courts (id, name, is_active, created_at, updated_at)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
`);
|
||||
|
||||
courtStmt.run('court-1', 'Court 1', 1, now, now);
|
||||
courtStmt.run('court-2', 'Court 2', 1, now, now);
|
||||
|
||||
console.log('Default courts created');
|
||||
} catch (error) {
|
||||
console.log('Courts might already exist');
|
||||
}
|
||||
|
||||
// Insert time slots
|
||||
try {
|
||||
const timeSlotStmt = db.prepare(`
|
||||
INSERT OR IGNORE INTO time_slots (id, start_time, end_time, is_active, created_at, updated_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
`);
|
||||
|
||||
const timeSlots = [
|
||||
['09:00', '10:00'],
|
||||
['10:00', '11:00'],
|
||||
['11:00', '12:00'],
|
||||
['12:00', '13:00'],
|
||||
['13:00', '14:00'],
|
||||
['14:00', '15:00'],
|
||||
['15:00', '16:00'],
|
||||
['16:00', '17:00'],
|
||||
['17:00', '18:00'],
|
||||
['18:00', '19:00'],
|
||||
['19:00', '20:00'],
|
||||
['20:00', '21:00'],
|
||||
];
|
||||
|
||||
timeSlots.forEach(([start, end], index) => {
|
||||
timeSlotStmt.run(`slot-${index + 1}`, start, end, 1, now, now);
|
||||
});
|
||||
|
||||
console.log('Time slots created');
|
||||
} catch (error) {
|
||||
console.log('Time slots might already exist');
|
||||
}
|
||||
|
||||
// Insert default settings
|
||||
try {
|
||||
const settingsStmt = db.prepare(`
|
||||
INSERT OR IGNORE INTO settings (id, key, value, description, created_at, updated_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
`);
|
||||
|
||||
settingsStmt.run('setting-1', 'booking_advance_days', '7', 'Days in advance users can book', now, now);
|
||||
settingsStmt.run('setting-2', 'max_bookings_per_user', '3', 'Maximum bookings per user per week', now, now);
|
||||
settingsStmt.run('setting-3', 'booking_duration', '60', 'Booking duration in minutes', now, now);
|
||||
|
||||
console.log('Default settings created');
|
||||
} catch (error) {
|
||||
console.log('Settings might already exist');
|
||||
}
|
||||
|
||||
db.close();
|
||||
console.log('Database setup completed!');
|
||||
}
|
||||
|
||||
setupDatabase().catch(console.error);
|
||||
@@ -0,0 +1,55 @@
|
||||
import { db } from '../lib/db';
|
||||
import { timeSlots } from '../lib/db/schema';
|
||||
|
||||
async function seedTimeSlots() {
|
||||
console.log('🌱 Seeding time slots...');
|
||||
|
||||
// Example time slots for different days
|
||||
const timeSlotData = [
|
||||
// Sunday: 12:00 - 17:00
|
||||
{ dayOfWeek: 0, startTime: '12:00', endTime: '17:00' },
|
||||
|
||||
// Monday: 19:00 - 23:00
|
||||
{ dayOfWeek: 1, startTime: '19:00', endTime: '23:00' },
|
||||
|
||||
// Tuesday: 19:00 - 23:00
|
||||
{ dayOfWeek: 2, startTime: '19:00', endTime: '23:00' },
|
||||
|
||||
// Wednesday: NO SLOTS (facility closed)
|
||||
// { dayOfWeek: 3, startTime: '18:00', endTime: '22:00' },
|
||||
|
||||
// Thursday: NO SLOTS (facility closed)
|
||||
// { dayOfWeek: 4, startTime: '19:00', endTime: '23:00' },
|
||||
|
||||
// Friday: 18:00 - 22:00
|
||||
{ dayOfWeek: 5, startTime: '18:00', endTime: '22:00' },
|
||||
|
||||
// Saturday: 10:00 - 18:00
|
||||
{ dayOfWeek: 6, startTime: '10:00', endTime: '18:00' },
|
||||
];
|
||||
|
||||
for (const slot of timeSlotData) {
|
||||
await db.insert(timeSlots).values({
|
||||
id: crypto.randomUUID(),
|
||||
dayOfWeek: slot.dayOfWeek,
|
||||
startTime: slot.startTime,
|
||||
endTime: slot.endTime,
|
||||
isActive: true,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
});
|
||||
}
|
||||
|
||||
console.log('✅ Time slots seeding completed');
|
||||
}
|
||||
|
||||
// Run the seeding function
|
||||
seedTimeSlots()
|
||||
.then(() => {
|
||||
console.log('Time slots seeding process completed');
|
||||
process.exit(0);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error during time slots seeding:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -1,133 +0,0 @@
|
||||
import { db } from '@/lib/db';
|
||||
import { users, courts, timeSlots, settings } from '@/lib/db/schema';
|
||||
import { hashPassword } from '@/lib/auth';
|
||||
import { generateId } from '@/lib/utils';
|
||||
|
||||
async function setupDatabase() {
|
||||
try {
|
||||
console.log('Setting up database...');
|
||||
|
||||
// Create admin user
|
||||
const adminEmail = process.env.ADMIN_EMAIL || 'admin@example.com';
|
||||
const adminPassword = process.env.ADMIN_PASSWORD || 'admin123';
|
||||
|
||||
const hashedAdminPassword = await hashPassword(adminPassword);
|
||||
const now = new Date();
|
||||
|
||||
await db
|
||||
.insert(users)
|
||||
.values({
|
||||
id: generateId(),
|
||||
email: adminEmail,
|
||||
name: 'Admin',
|
||||
surname: 'User',
|
||||
password: hashedAdminPassword,
|
||||
role: 'admin',
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
})
|
||||
.onConflictDoNothing();
|
||||
|
||||
// Create default courts
|
||||
await db
|
||||
.insert(courts)
|
||||
.values([
|
||||
{
|
||||
id: generateId(),
|
||||
name: 'Court 1',
|
||||
isActive: true,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
},
|
||||
{
|
||||
id: generateId(),
|
||||
name: 'Court 2',
|
||||
isActive: true,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
},
|
||||
])
|
||||
.onConflictDoNothing();
|
||||
|
||||
// Create default time slots
|
||||
// Monday (1) and Tuesday (2): 19:00-23:00
|
||||
const mondayTuesdaySlots = [];
|
||||
for (let day of [1, 2]) {
|
||||
for (let hour = 19; hour < 23; hour++) {
|
||||
const hourStr = hour < 10 ? '0' + hour : hour.toString();
|
||||
const nextHourStr = hour + 1 < 10 ? '0' + (hour + 1) : (hour + 1).toString();
|
||||
mondayTuesdaySlots.push({
|
||||
id: generateId(),
|
||||
dayOfWeek: day,
|
||||
startTime: `${hourStr}:00`,
|
||||
endTime: `${nextHourStr}:00`,
|
||||
isActive: true,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Sunday (0): 12:00-17:00
|
||||
const sundaySlots = [];
|
||||
for (let hour = 12; hour < 17; hour++) {
|
||||
const hourStr = hour < 10 ? '0' + hour : hour.toString();
|
||||
const nextHourStr = hour + 1 < 10 ? '0' + (hour + 1) : (hour + 1).toString();
|
||||
sundaySlots.push({
|
||||
id: generateId(),
|
||||
dayOfWeek: 0,
|
||||
startTime: `${hourStr}:00`,
|
||||
endTime: `${nextHourStr}:00`,
|
||||
isActive: true,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
});
|
||||
}
|
||||
|
||||
await db
|
||||
.insert(timeSlots)
|
||||
.values([...mondayTuesdaySlots, ...sundaySlots])
|
||||
.onConflictDoNothing();
|
||||
|
||||
// Create default settings
|
||||
await db
|
||||
.insert(settings)
|
||||
.values([
|
||||
{
|
||||
id: generateId(),
|
||||
key: 'booking_window_days',
|
||||
value: '7',
|
||||
updatedAt: now,
|
||||
},
|
||||
{
|
||||
id: generateId(),
|
||||
key: 'max_bookings_per_user',
|
||||
value: '3',
|
||||
updatedAt: now,
|
||||
},
|
||||
{
|
||||
id: generateId(),
|
||||
key: 'booking_cancellation_hours',
|
||||
value: '2',
|
||||
updatedAt: now,
|
||||
},
|
||||
])
|
||||
.onConflictDoNothing();
|
||||
|
||||
console.log('Database setup completed successfully!');
|
||||
console.log(`Admin user created: ${adminEmail}`);
|
||||
console.log(`Admin password: ${adminPassword}`);
|
||||
} catch (error) {
|
||||
console.error('Database setup error:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Run setup if this file is executed directly
|
||||
if (require.main === module) {
|
||||
setupDatabase()
|
||||
.then(() => process.exit(0))
|
||||
.catch(() => process.exit(1));
|
||||
}
|
||||
|
||||
export { setupDatabase };
|
||||
Reference in New Issue
Block a user