Create the admin interface for workshop and student management with TypeScript, SQLite database, and server-side JSX.
Val Name: workshopTypes
Type: Script Val
Purpose: Define all TypeScript interfaces and types for the entire application
// Export all interfaces that will be used across vals
export interface Workshop {
id: number;
name: string;
description: string;
age_groups: string;
capacity: number;
day: 'monday' | 'tuesday';
time_slot: 1 | 2 | 3;
created_at: string;
}
export interface Kid {
id: number;
name: string;
grade: string;
created_at: string;
}
export interface Preference {
id: number;
kid_id: number;
workshop_id: number;
rank: 1 | 2 | 3;
day: 'monday' | 'tuesday';
time_slot: 1 | 2 | 3;
created_at: string;
}
export type Day = 'monday' | 'tuesday';
export type TimeSlot = 1 | 2 | 3;
export type PreferenceRank = 1 | 2 | 3;
Val Name: workshopDatabase
Type: Script Val
Purpose: Database initialization, connection utilities, and setup functions
import { sqlite } from "https://esm.sh/@valtown/sdk";
export async function initDatabase() {
// Create all tables with proper schema
// Include helper functions for common database operations
}
export async function resetDatabase() {
// For development - drop and recreate tables
}
export { sqlite };
Tasks:
Val Name: workshopAuth
Type: Script Val
Purpose: Simple admin authentication system
const ADMIN_PASSWORD = "workshop2025admin"; // Hardcoded password
export function requireAuth(request: Request): boolean {
// Check for auth parameter or session
}
export function getAuthUrl(baseUrl: string): string {
// Return URL with auth parameter
}
export function isAuthenticated(request: Request): boolean {
// Validate authentication
}
Tasks:
Val Name: workshopComponents
Type: Script Val
Purpose: Reusable JSX components and layouts
/** @jsxImportSource https://esm.sh/preact */
export function AdminLayout({
children,
title,
currentPage
}: {
children: any;
title: string;
currentPage?: string;
}) {
// Main admin layout with navigation
}
export function WorkshopCard({ workshop }: { workshop: Workshop }) {
// Workshop display component
}
export function ErrorMessage({ message }: { message: string }) {
// Error display component
}
Tasks:
Val Name: workshopManager
Type: HTTP Handler Val
Purpose: CRUD operations for workshops
/** @jsxImportSource https://esm.sh/preact */
import { render } from "https://esm.sh/preact-render-to-string";
export default async function(req: Request): Promise<Response> {
// Handle GET: Display workshop management interface
// Handle POST: Process workshop creation/updates
// Handle DELETE: Remove workshops
}
Routes to handle:
GET / - Workshop management dashboardGET /?action=new - New workshop formGET /?action=edit&id=123 - Edit workshop formPOST / - Create/update workshopPOST /?action=delete&id=123 - Delete workshopTasks:
Val Name: studentManager
Type: HTTP Handler Val
Purpose: CRUD operations for students
/** @jsxImportSource https://esm.sh/preact */
import { render } from "https://esm.sh/preact-render-to-string";
export default async function(req: Request): Promise<Response> {
// Handle GET: Display student management interface
// Handle POST: Process student creation/updates/bulk import
}
Routes to handle:
GET / - Student management interfaceGET /?action=new - New student formGET /?action=edit&id=123 - Edit student formGET /?action=bulk - Bulk import formPOST / - Create/update studentPOST /?action=bulk - Bulk import studentsTasks:
Val Name: adminDashboard
Type: HTTP Handler Val
Purpose: Main admin landing page with overview
/** @jsxImportSource https://esm.sh/preact */
import { render } from "https://esm.sh/preact-render-to-string";
export default async function(req: Request): Promise<Response> {
// Show overview statistics
// Display workshop grid by day/time
// Show student count
// Navigation to other admin functions
}
Tasks:
Val Name: workshopAdmin
Type: HTTP Handler Val
Purpose: Main admin entry point with authentication
/** @jsxImportSource https://esm.sh/preact */
import { render } from "https://esm.sh/preact-render-to-string";
export default async function(req: Request): Promise<Response> {
// Check authentication
// Show login form if not authenticated
// Redirect to dashboard if authenticated
}
Tasks:
Val Name: setupDatabase
Type: Script Val
Purpose: One-time database setup
import { initDatabase } from "./workshopDatabase";
// Run this once to set up the database
export default async function() {
await initDatabase();
return "Database initialized successfully";
}
Tasks:
Val Name: workshopStyles
Type: Script Val
Purpose: Centralized CSS styles
export const adminStyles = `
/* Complete CSS for admin interface */
/* Grid layouts for workshop overview */
/* Form styling */
/* Navigation styling */
/* Responsive design */
`;
Tasks:
After completion, the admin interface will be accessible at:
https://username-workshopAdmin.web.val.run/?auth=workshop2025adminhttps://username-workshopManager.web.val.run/?auth=workshop2025adminhttps://username-studentManager.web.val.run/?auth=workshop2025admin