+ {getModelLabelPlural(currentModel)} +
++ Manage {getModelLabel(currentModel).toLowerCase()} records +
+Select a model from the sidebar
+diff --git a/.spark-initial-sha b/.spark-initial-sha new file mode 100644 index 000000000..165eaccc1 --- /dev/null +++ b/.spark-initial-sha @@ -0,0 +1 @@ +a024526c87d7b9829fc5f702d15e3d3dec2b4557 diff --git a/PRD.md b/PRD.md new file mode 100644 index 000000000..f82887586 --- /dev/null +++ b/PRD.md @@ -0,0 +1,119 @@ +# Planning Guide + +A declarative admin panel generator that allows developers to define data models and UI configuration through JSON schemas, automatically generating a complete CRUD interface similar to Django's admin panel. + +**Experience Qualities**: +1. **Declarative** - Configuration-driven development where JSON schemas define the entire admin interface without manual component creation +2. **Intuitive** - Familiar Django-admin-style patterns that feel immediately recognizable to developers who've worked with backend admin panels +3. **Powerful** - Full-featured CRUD operations with filtering, sorting, validation, and relationships handled automatically from schema definitions + +**Complexity Level**: Complex Application (advanced functionality, likely with multiple views) +This is a code generation and admin panel system that dynamically creates fully functional interfaces from JSON schemas, including list views, detail views, forms, validation, and data persistence - requiring sophisticated state management and dynamic rendering. + +## Essential Features + +### Schema Definition System +- **Functionality**: Parse JSON schema files that define data models with fields, types, validation rules, and UI hints +- **Purpose**: Enable developers to define entire admin panels declaratively without writing component code +- **Trigger**: JSON schema files loaded at application startup or hot-reloaded during development +- **Progression**: Load JSON schema → Parse model definitions → Validate schema structure → Generate TypeScript types → Initialize data stores → Render admin interface +- **Success criteria**: Valid JSON schemas produce working admin panels; invalid schemas show clear error messages with schema validation feedback + +### Dynamic Model List View +- **Functionality**: Auto-generated table/list view showing all records for a model with sortable columns, filters, search, and pagination +- **Purpose**: Provide quick overview and management of all records in a data model +- **Trigger**: User selects a model from the navigation sidebar +- **Progression**: Select model → Load records from KV store → Render table with columns from schema → Apply filters/search/sort → Click row for detail view +- **Success criteria**: All defined fields display correctly; sorting, filtering, and search work; pagination handles large datasets; empty states guide users to create first record + +### Dynamic Form Generation +- **Functionality**: Automatically generate create/edit forms based on field types and validation rules in the schema +- **Purpose**: Eliminate boilerplate form code while ensuring data integrity through schema-defined validation +- **Trigger**: User clicks "Create New" button or "Edit" on existing record +- **Progression**: Open form dialog → Render fields based on schema → User inputs data → Validate on blur/submit → Save to KV store → Update list view → Show success toast +- **Success criteria**: All field types render appropriate inputs; validation rules enforced; error messages clear; optimistic updates feel instant + +### Relationship Management +- **Functionality**: Handle foreign keys and many-to-many relationships with select dropdowns and relationship tables +- **Purpose**: Support relational data models common in admin panels +- **Trigger**: Form fields defined with relationship types in schema +- **Progression**: Render relationship field → Load related model records → Display searchable select → Save relationship IDs → Update related records view +- **Success criteria**: Related records load and display; cascade operations work correctly; relationship changes persist + +### Field Type System +- **Functionality**: Support common field types (text, number, boolean, date, email, URL, select, textarea, rich text, file reference, relationship) +- **Purpose**: Cover the majority of admin panel use cases with appropriate input controls +- **Trigger**: Field type specified in schema +- **Progression**: Parse field type → Select appropriate input component → Apply type-specific validation → Render with schema-defined options +- **Success criteria**: Each field type has appropriate UI control; validation matches type; special types (date, color) use enhanced inputs + +## Edge Case Handling +- **Invalid Schema Structure**: Display detailed validation errors in a dev-friendly overlay with line numbers and suggestions +- **Missing Required Fields**: Prevent form submission and highlight missing fields with clear error messages +- **Circular Relationships**: Detect and warn about circular dependencies in schema definitions +- **Large Datasets**: Implement virtual scrolling and pagination for tables with 1000+ records +- **Concurrent Edits**: Show warnings when data has been modified since form opened +- **Migration Scenarios**: Handle schema changes gracefully with field mapping suggestions + +## Design Direction +The design should evoke efficiency, clarity, and developer familiarity - similar to the no-nonsense utility of Django admin but with modern polish and visual refinement. Think "power tool" rather than "pretty toy" - dense information displays, keyboard shortcuts, and rapid workflows prioritized over decorative elements. + +## Color Selection +A technical, code-editor-inspired palette with high contrast for data clarity and professional development tool aesthetic. + +- **Primary Color**: Deep indigo `oklch(0.45 0.15 265)` - Communicates technical sophistication and authority, used for primary actions and active states +- **Secondary Colors**: Cool gray `oklch(0.65 0.02 250)` for secondary UI elements and subtle backgrounds; Slate `oklch(0.25 0.03 250)` for sidebar and chrome +- **Accent Color**: Bright cyan `oklch(0.75 0.15 195)` - High-visibility color for CTAs, links, and "create new" actions that demand attention +- **Foreground/Background Pairings**: + - Primary (Deep Indigo): White text `oklch(0.98 0 0)` - Ratio 7.8:1 ✓ + - Background (Near White `oklch(0.98 0 0)`): Charcoal text `oklch(0.25 0 0)` - Ratio 14.2:1 ✓ + - Accent (Bright Cyan): Dark slate text `oklch(0.2 0.05 250)` - Ratio 8.1:1 ✓ + - Sidebar (Slate): Light gray text `oklch(0.85 0.01 250)` - Ratio 9.4:1 ✓ + +## Font Selection +Technical clarity with a code-adjacent aesthetic that reinforces the developer tool positioning while maintaining readability for dense data tables. + +- **Typographic Hierarchy**: + - H1 (Panel Title): Space Grotesk Bold/32px/tight letter spacing + - H2 (Section Headers): Space Grotesk Semibold/24px/normal spacing + - H3 (Field Labels): Space Grotesk Medium/14px/uppercase/wide letter spacing + - Body (Table Data): IBM Plex Sans Regular/15px/1.5 line height + - Code (IDs, Technical Values): JetBrains Mono Regular/14px/1.4 line height + - Small (Hints, Metadata): IBM Plex Sans Regular/13px/muted color + +## Animations +Animations should prioritize immediate feedback for data operations and subtle spatial awareness during navigation - instant response to clicks/inputs with 150ms micro-animations for state changes, 250ms smooth transitions between list/detail views, and purposeful loading states that communicate progress. + +## Component Selection +- **Components**: + - Table with Select, Checkbox, and Badge for list views + - Dialog for create/edit forms with Form, Input, Textarea, Select, Switch, Calendar components + - Sidebar for model navigation with collapsible groups + - Command palette (cmdk) for quick model/record search + - Breadcrumb for navigation context + - Tabs for organizing related model groups + - Sheet for sliding detail panels + - Sonner for success/error toasts + - Skeleton for loading states +- **Customizations**: + - Custom JSON schema editor with syntax highlighting + - Dynamic field renderer component that maps schema types to inputs + - Virtualized table component for large datasets + - Relationship selector with async search +- **States**: + - Tables: hover highlights entire row with subtle background shift, selected rows show accent border + - Buttons: primary actions use filled accent color with slight scale on press, secondary use outline + - Inputs: focused state shows accent border with subtle glow, error state shows destructive color + - Forms: dirty state indicators on modified fields +- **Icon Selection**: + - Phosphor icons throughout: List/Table for views, Plus for create, Pencil for edit, Trash for delete, MagnifyingGlass for search, Funnel for filters, ArrowsDownUp for sort, Database for models, FloppyDisk for save +- **Spacing**: + - Dense mode: p-2 for cells, p-4 for cards, gap-2 for tight groups + - Standard: p-4 for containers, p-6 for dialogs, gap-4 for form fields, gap-6 for sections + - Generous whitespace in sidebar (p-6) and around primary actions +- **Mobile**: + - Sidebar collapses to hamburger menu, stacks on small screens with slide-out drawer + - Tables switch to card-based layout with key fields only, expandable for full details + - Forms switch to full-screen sheets on mobile + - Touch-friendly 44px minimum tap targets on all interactive elements + - Bottom navigation bar for primary actions on mobile diff --git a/README.md b/README.md index 358beecf2..6dc46e959 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,222 @@ -# ✨ Welcome to Your Spark Template! -You've just launched your brand-new Spark Template Codespace — everything’s fired up and ready for you to explore, build, and create with Spark! +# Django-Style React Admin Panel Generator -This template is your blank canvas. It comes with a minimal setup to help you get started quickly with Spark development. +A declarative admin panel generator that creates full-featured CRUD interfaces from JSON schema definitions. Inspired by Django's admin panel, this tool lets you define data models and UI configuration declaratively without writing component code. -🚀 What's Inside? -- A clean, minimal Spark environment -- Pre-configured for local development -- Ready to scale with your ideas - -🧠 What Can You Do? +## Features -Right now, this is just a starting point — the perfect place to begin building and testing your Spark applications. +- **Declarative Schema Definition** - Define your entire data model in JSON +- **Automatic CRUD Generation** - List views, forms, validation automatically generated +- **Field Types** - String, text, number, boolean, date, datetime, email, URL, select, relations, JSON +- **Advanced Features** - Sorting, filtering, search, validation, relationships +- **Persistent Storage** - Data automatically saved using Spark KV storage +- **Live Schema Editing** - Edit schemas in real-time through the UI -🧹 Just Exploring? -No problem! If you were just checking things out and don’t need to keep this code: +## Quick Start -- Simply delete your Spark. -- Everything will be cleaned up — no traces left behind. +1. Launch the app +2. Use the sidebar to navigate between models +3. Click "Create New" to add records +4. Edit or delete records using the action buttons +5. Click "Edit Schema" to customize your data models -📄 License For Spark Template Resources +## Schema Structure -The Spark Template files and resources from GitHub are licensed under the terms of the MIT license, Copyright GitHub, Inc. +The schema is a JSON object with the following structure: + +```json +{ + "apps": [ + { + "name": "app_name", + "label": "App Label", + "models": [ + { + "name": "model_name", + "label": "Model Label", + "labelPlural": "Models", + "icon": "IconName", + "listDisplay": ["field1", "field2"], + "listFilter": ["field3"], + "searchFields": ["field1", "field2"], + "ordering": ["-field2"], + "fields": [ + { + "name": "field_name", + "type": "string", + "label": "Field Label", + "required": true, + "unique": false, + "default": "value", + "helpText": "Help text or array of strings", + "validation": { + "min": 0, + "max": 100, + "minLength": 3, + "maxLength": 200, + "pattern": "^[a-z]+$" + }, + "listDisplay": true, + "searchable": true, + "sortable": true, + "editable": true + } + ] + } + ] + } + ] +} +``` + +## Field Types + +### Basic Types +- **string** - Single-line text input +- **text** - Multi-line textarea +- **number** - Numeric input with min/max validation +- **boolean** - Switch/toggle control +- **email** - Email input with validation +- **url** - URL input with validation + +### Date/Time +- **date** - Date picker +- **datetime** - Date and time picker + +### Advanced Types +- **select** - Dropdown with predefined choices +- **relation** - Foreign key to another model +- **json** - JSON editor for complex data + +## Select Field Choices + +For select fields, define choices as an array: + +```json +{ + "name": "status", + "type": "select", + "choices": [ + { "value": "draft", "label": "Draft" }, + { "value": "published", "label": "Published" }, + { "value": "archived", "label": "Archived" } + ] +} +``` + +## Relationships + +Define relationships between models using the relation type: + +```json +{ + "name": "author", + "type": "relation", + "relatedModel": "author", + "required": true +} +``` + +The related model must exist in the same app. + +## Validation + +Add validation rules to fields: + +```json +{ + "validation": { + "min": 0, + "max": 100, + "minLength": 3, + "maxLength": 200, + "pattern": "^[a-z0-9-]+$" + } +} +``` + +## Help Text + +Provide help text as a string or array of strings: + +```json +{ + "helpText": "Single line help text" +} +``` + +Or for multi-line help: + +```json +{ + "helpText": [ + "First line of help", + "Second line of help" + ] +} +``` + +## List View Configuration + +Control which fields appear in the list view: + +```json +{ + "listDisplay": ["title", "author", "status", "publishedAt"], + "listFilter": ["status", "author"], + "searchFields": ["title", "content"], + "ordering": ["-publishedAt"] +} +``` + +- **listDisplay** - Fields to show in the table +- **listFilter** - Fields to offer as filters (select/boolean only) +- **searchFields** - Fields to search when using the search box +- **ordering** - Default sort order (prefix with `-` for descending) + +## Example Schemas + +See `example-schemas.json` for complete examples including: +- Blog with posts and authors +- Task manager with projects and tasks +- E-commerce with products and categories + +## Tips + +1. **Start Simple** - Begin with basic string and text fields, add complexity later +2. **Use Relations** - Connect related data with relation fields +3. **Add Validation** - Prevent bad data with field validation rules +4. **Leverage Defaults** - Set sensible defaults for better UX +5. **Help Text** - Guide users with helpful field descriptions +6. **Test Incrementally** - Edit and test schema changes one model at a time + +## Technical Details + +- Built with React, TypeScript, and Tailwind CSS +- Uses shadcn/ui components for consistent design +- Data persisted with Spark KV storage +- Framer Motion for smooth animations +- Full type safety with TypeScript + +## Keyboard Shortcuts + +- Click table headers to sort +- Use search box for quick filtering +- Forms validate on blur and submit + +## Limitations + +- Relations only work within the same app +- No many-to-many relationships (use JSON arrays) +- No file uploads (use URL fields to reference external files) +- Maximum recommended records per model: 1000 + +## Architecture + +The system consists of: +1. **Schema Parser** - Validates and processes JSON schemas +2. **Field Renderer** - Dynamically renders form inputs based on field types +3. **Model List View** - Table view with sorting, filtering, search +4. **Record Form** - Auto-generated create/edit forms with validation +5. **Schema Editor** - Live JSON editor for schema modifications + +All data is stored in the Spark KV store with keys like `records_appname_modelname`. diff --git a/example-schemas.json b/example-schemas.json new file mode 100644 index 000000000..a60b0edd5 --- /dev/null +++ b/example-schemas.json @@ -0,0 +1,290 @@ +{ + "description": "Example schema configurations for the Admin Panel Generator", + "examples": [ + { + "name": "Simple Blog", + "description": "Basic blog with posts and authors", + "schema": { + "apps": [ + { + "name": "blog", + "label": "Blog", + "models": [ + { + "name": "post", + "label": "Post", + "labelPlural": "Posts", + "listDisplay": ["title", "author", "status", "publishedAt"], + "fields": [ + { + "name": "id", + "type": "string", + "required": true, + "unique": true, + "editable": false + }, + { + "name": "title", + "type": "string", + "label": "Title", + "required": true, + "validation": { + "minLength": 3, + "maxLength": 200 + } + }, + { + "name": "content", + "type": "text", + "label": "Content", + "required": true + }, + { + "name": "author", + "type": "relation", + "label": "Author", + "required": true, + "relatedModel": "author" + }, + { + "name": "status", + "type": "select", + "label": "Status", + "required": true, + "default": "draft", + "choices": [ + { "value": "draft", "label": "Draft" }, + { "value": "published", "label": "Published" } + ] + }, + { + "name": "publishedAt", + "type": "datetime", + "label": "Published At" + } + ] + }, + { + "name": "author", + "label": "Author", + "labelPlural": "Authors", + "listDisplay": ["name", "email"], + "fields": [ + { + "name": "id", + "type": "string", + "required": true, + "unique": true, + "editable": false + }, + { + "name": "name", + "type": "string", + "label": "Name", + "required": true + }, + { + "name": "email", + "type": "email", + "label": "Email", + "required": true, + "unique": true + } + ] + } + ] + } + ] + } + }, + { + "name": "Task Manager", + "description": "Task management system with projects and tasks", + "schema": { + "apps": [ + { + "name": "tasks", + "label": "Task Manager", + "models": [ + { + "name": "project", + "label": "Project", + "labelPlural": "Projects", + "listDisplay": ["name", "status", "dueDate"], + "fields": [ + { + "name": "id", + "type": "string", + "required": true, + "editable": false + }, + { + "name": "name", + "type": "string", + "required": true + }, + { + "name": "description", + "type": "text" + }, + { + "name": "status", + "type": "select", + "default": "planning", + "choices": [ + { "value": "planning", "label": "Planning" }, + { "value": "active", "label": "Active" }, + { "value": "completed", "label": "Completed" } + ] + }, + { + "name": "dueDate", + "type": "date" + } + ] + }, + { + "name": "task", + "label": "Task", + "labelPlural": "Tasks", + "listDisplay": ["title", "project", "priority", "completed"], + "fields": [ + { + "name": "id", + "type": "string", + "required": true, + "editable": false + }, + { + "name": "title", + "type": "string", + "required": true + }, + { + "name": "description", + "type": "text" + }, + { + "name": "project", + "type": "relation", + "required": true, + "relatedModel": "project" + }, + { + "name": "priority", + "type": "select", + "default": "medium", + "choices": [ + { "value": "low", "label": "Low" }, + { "value": "medium", "label": "Medium" }, + { "value": "high", "label": "High" } + ] + }, + { + "name": "completed", + "type": "boolean", + "default": false + } + ] + } + ] + } + ] + } + }, + { + "name": "E-Commerce", + "description": [ + "Product catalog with categories and inventory", + "Includes price and stock management" + ], + "schema": { + "apps": [ + { + "name": "store", + "label": "Store", + "models": [ + { + "name": "category", + "label": "Category", + "labelPlural": "Categories", + "fields": [ + { + "name": "id", + "type": "string", + "required": true, + "editable": false + }, + { + "name": "name", + "type": "string", + "required": true + }, + { + "name": "description", + "type": "text" + } + ] + }, + { + "name": "product", + "label": "Product", + "labelPlural": "Products", + "listDisplay": ["name", "category", "price", "stock", "available"], + "fields": [ + { + "name": "id", + "type": "string", + "required": true, + "editable": false + }, + { + "name": "name", + "type": "string", + "required": true, + "validation": { + "minLength": 3 + } + }, + { + "name": "description", + "type": "text" + }, + { + "name": "category", + "type": "relation", + "required": true, + "relatedModel": "category" + }, + { + "name": "price", + "type": "number", + "required": true, + "validation": { + "min": 0 + }, + "helpText": "Price in USD" + }, + { + "name": "stock", + "type": "number", + "required": true, + "default": 0, + "validation": { + "min": 0 + } + }, + { + "name": "available", + "type": "boolean", + "default": true + } + ] + } + ] + } + ] + } + } + ] +} diff --git a/index.html b/index.html index f62002d97..118680ba7 100644 --- a/index.html +++ b/index.html @@ -4,9 +4,10 @@
-+ Manage {getModelLabel(currentModel).toLowerCase()} records +
+Select a model from the sidebar
+