Modern admin interface for the Mystira platform - A comprehensive content management system for scenarios, media, badges, and more.
- Overview
- Features
- Architecture
- Getting Started
- Development
- Project Structure
- Configuration
- Testing
- Deployment
- Contributing
- Troubleshooting
Mystira Admin UI is a modern single-page application (SPA) built with React, TypeScript, and Vite. It provides a comprehensive interface for managing content, users, and platform configuration for the Mystira platform.
- Content Management: Full CRUD operations for scenarios, media, badges, bundles, and avatars
- Validation: Client-side schema validation for scenario uploads with detailed error reporting
- Media Management: Bulk media uploads via ZIP files with metadata support
- Error Handling: Comprehensive error boundaries with stack traces and recovery options
- Responsive Design: Mobile-friendly interface built with Bootstrap 5
- Type Safety: Full TypeScript coverage with strict type checking
- Scenarios: Create, edit, import, and validate story scenarios with full schema validation
- Media: Upload single files or bulk import via ZIP with metadata
- Badges: Manage achievement badges with image assets
- Bundles: Create and manage content bundles
- Avatars: Configure avatars by age group
- Character Maps: Define character relationships and properties
- Master Data: Manage age groups, archetypes, compass axes, echo types, and fantasy themes
- Schema Validation: Client-side validation against JSON Schema before upload
- Media ZIP Upload: Bulk media upload with
media-metadata.jsonsupport - Scenario Validation: Check all media references in scenarios against database
- Error Boundaries: Graceful error handling with detailed stack traces
- 404 Handling: User-friendly not found pages with quick navigation
- Hot Module Replacement: Instant feedback during development
- TypeScript: Full type safety and IntelliSense support
- ESLint & Prettier: Consistent code style and quality
- React Query: Efficient data fetching and caching
- Form Validation: React Hook Form with Zod schemas
- Component Library: Reusable UI components (Alert, Card, FileInput, etc.)
- Frontend Framework: React 18.3
- Language: TypeScript 5.6
- Build Tool: Vite 5.4
- Styling: Bootstrap 5.3 + Custom CSS
- State Management: Zustand 5.0
- Data Fetching: TanStack React Query 5.60
- Form Handling: React Hook Form 7.53 + Zod 3.23
- Routing: React Router DOM 6.28
- HTTP Client: Axios 1.7
- Authentication: MSAL (Microsoft Authentication Library) for Azure AD / Entra ID
- Validation: Ajv 8.17 (JSON Schema validator)
- YAML Parsing: js-yaml 4.1
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Mystira Admin UI β
β (React + TypeScript) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Components Layer β
β βββ Pages (Scenarios, Media, Badges, etc.) β
β βββ Reusable Components (Alert, Card, FileInput) β
β βββ Error Boundaries & Error Pages β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Business Logic Layer β
β βββ Custom Hooks (useFileValidation, useFileUpload) β
β βββ API Clients (scenarios, media, badges, etc.) β
β βββ Utilities (errorHandler, schemaValidator) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β State Management β
β βββ Zustand Stores (auth, UI state) β
β βββ React Query Cache β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β REST API
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Mystira Admin API β
β (ASP.NET Core Backend) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Before you begin, ensure you have the following installed:
- Node.js: Version 18.x or higher (Download)
- pnpm: Version 9.x (specified in
package.jsonaspackageManager) (Install) - Git: For version control (Download)
- Mystira Admin API: Backend service must be running
- Clone the repository
git clone https://github.com/phoenixvc/Mystira.Admin.UI.git
cd Mystira.Admin.UI- Install dependencies
pnpm install- Configure environment variables
Create a .env.local file in the root directory:
# API Configuration
VITE_API_BASE_URL=http://localhost:5000
# Azure AD / Entra ID Authentication (Required)
VITE_AZURE_CLIENT_ID=your-client-id
VITE_AZURE_TENANT_ID=your-tenant-id
VITE_AZURE_REDIRECT_URI=http://localhost:7001
VITE_AZURE_API_SCOPE=api://your-backend-app-id/access_as_user
# Optional: Environment
VITE_ENV=development- Start the development server
pnpm devThe application will be available at http://localhost:7001
- Node.js 18+ installed
- pnpm installed
- Repository cloned
- Dependencies installed (
pnpm install) - Azure AD app registration configured (see Authentication Setup)
- Environment variables configured (
.env.local) - Admin API running on configured URL
- Development server started (
pnpm dev) - Browser opened to
http://localhost:7001
This application uses Microsoft Entra ID (Azure AD) for authentication via MSAL. To set up authentication:
- Register an application in Azure Portal > App Registrations
- Configure the application:
- Set the application type to Single-Page Application (SPA)
- Add redirect URI:
http://localhost:7001(for development) - Enable ID tokens and Access tokens in Authentication settings
- Set up API permissions for your backend API
- Copy the values to your
.env.local:VITE_AZURE_CLIENT_ID: Application (client) IDVITE_AZURE_TENANT_ID: Directory (tenant) IDVITE_AZURE_REDIRECT_URI: Your redirect URIVITE_AZURE_API_SCOPE: Your backend API scope
| Script | Description |
|---|---|
pnpm dev |
Start development server with HMR |
pnpm build |
Build for production |
pnpm preview |
Preview production build locally |
pnpm lint |
Run ESLint to check code quality |
pnpm lint:fix |
Fix ESLint errors automatically |
pnpm format |
Format code with Prettier |
pnpm test |
Run tests once |
pnpm test:watch |
Run tests in watch mode |
pnpm test:coverage |
Generate test coverage report |
pnpm typecheck |
Type check without building |
- Create a feature branch
git checkout -b feature/your-feature-name- Make your changes
Follow the project structure and coding conventions.
- Run tests and linting
pnpm typecheck
pnpm lint
pnpm test- Commit your changes
git add .
git commit -m "feat: add your feature description"- Push and create a pull request
git push origin feature/your-feature-name- TypeScript: Use strict mode, no
anytypes - Components: Functional components with hooks
- Naming: PascalCase for components, camelCase for functions/variables
- Files: One component per file, named exports preferred
- Styling: Bootstrap classes + custom CSS modules
- State: Use Zustand for global state, React Query for server state
- Forms: React Hook Form + Zod validation
- Error Handling: Use error boundaries and proper error types
When creating new components:
- Use TypeScript interfaces for props
interface MyComponentProps {
title: string;
onAction: () => void;
optional?: boolean;
}
function MyComponent({ title, onAction, optional = false }: MyComponentProps) {
// Component logic
}- Use reusable components from the library
import Alert from "../components/Alert";
import Card from "../components/Card";
import FileInput from "../components/FileInput";- Handle errors gracefully
import { handleApiError } from "../utils/errorHandler";
try {
await someOperation();
} catch (error) {
handleApiError(error, "Custom error message");
}- Add loading states
import LoadingSpinner from "../components/LoadingSpinner";
if (isLoading) return <LoadingSpinner text="Loading data..." />;mystira-admin-ui/
βββ public/ # Static assets
βββ src/
β βββ api/ # API client modules
β β βββ client.ts # Axios client with MSAL token injection
β β βββ scenarios.ts # Scenarios API
β β βββ media.ts # Media API
β β βββ badges.ts # Badges API
β β βββ bundles.ts # Bundles API
β β βββ avatars.ts # Avatars API
β β βββ ... # Other API modules
β βββ auth/ # MSAL Authentication
β β βββ AuthProvider.tsx # React context provider for MSAL
β β βββ msalConfig.ts # MSAL configuration
β β βββ msalInstance.ts # PublicClientApplication instance
β β βββ useAuth.ts # Custom hook for auth operations
β β βββ index.ts # Barrel export
β βββ components/ # Reusable UI components
β β βββ Alert.tsx # Alert component
β β βββ Card.tsx # Card wrapper
β β βββ Checkbox.tsx # Checkbox input
β β βββ ErrorBoundary.tsx # Error boundary
β β βββ ErrorDisplay.tsx # Error display
β β βββ FileInput.tsx # File input
β β βββ LoadingSpinner.tsx # Loading indicator
β β βββ Pagination.tsx # Pagination controls
β β βββ SearchBar.tsx # Search input
β β βββ ValidationResults.tsx # Validation display
β β βββ ... # Other components
β βββ hooks/ # Custom React hooks
β β βββ useFileValidation.ts # File validation hook
β β βββ useFileUpload.ts # File upload hook
β β βββ ... # Other hooks
β βββ pages/ # Page components
β β βββ DashboardPage.tsx # Dashboard
β β βββ ScenariosPage.tsx # Scenarios list
β β βββ CreateScenarioPage.tsx # Create scenario
β β βββ EditScenarioPage.tsx # Edit scenario
β β βββ ImportScenarioPage.tsx # Import scenario
β β βββ ValidateScenariosPage.tsx # Validate scenarios
β β βββ MediaPage.tsx # Media list
β β βββ ImportMediaZipPage.tsx # Bulk media import
β β βββ BadgesPage.tsx # Badges list
β β βββ BundlesPage.tsx # Bundles list
β β βββ AvatarsPage.tsx # Avatars management
β β βββ NotFoundPage.tsx # 404 page
β β βββ ErrorPage.tsx # Error page
β β βββ ... # Other pages
β βββ schemas/ # JSON schemas
β β βββ story-schema.json # Scenario validation schema
β βββ state/ # State management
β β βββ authStore.ts # Authentication store
β βββ styles/ # CSS files
β β βββ index.css # Global styles
β βββ utils/ # Utility functions
β β βββ errorHandler.ts # Error handling utilities
β β βββ schemaValidator.ts # Schema validation
β β βββ toast.ts # Toast notifications
β βββ App.tsx # Main app component
β βββ Layout.tsx # Layout wrapper
β βββ main.tsx # Entry point
β βββ ProtectedRoute.tsx # Route guard
βββ .env.local # Local environment variables (not in git)
βββ .eslintrc.cjs # ESLint configuration
βββ .gitignore # Git ignore rules
βββ .prettierrc # Prettier configuration
βββ index.html # HTML template
βββ package.json # Dependencies and scripts
βββ pnpm-lock.yaml # Lock file
βββ tsconfig.json # TypeScript configuration
βββ tsconfig.node.json # TypeScript config for Node
βββ vite.config.ts # Vite configuration
βββ README.md # This file
src/api/: API client modules using Axios for HTTP requestssrc/auth/: MSAL authentication (AuthProvider, useAuth hook, config)src/components/: Reusable UI components (Alert, Card, FileInput, etc.)src/hooks/: Custom React hooks for business logicsrc/pages/: Page-level components for routingsrc/schemas/: JSON schemas for validationsrc/state/: Zustand stores for global statesrc/utils/: Utility functions and helpers
Create a .env.local file for local development:
# Required: API base URL
VITE_API_BASE_URL=http://localhost:5000
# Required: Azure AD / Entra ID Authentication
VITE_AZURE_CLIENT_ID=your-client-id
VITE_AZURE_TENANT_ID=your-tenant-id
VITE_AZURE_REDIRECT_URI=http://localhost:7001
VITE_AZURE_API_SCOPE=api://your-backend-app-id/access_as_user
# Optional: Environment identifier
VITE_ENV=development
# Optional: Enable debug logging
VITE_DEBUG=trueAvailable Variables:
| Variable | Description | Default | Required |
|---|---|---|---|
VITE_API_BASE_URL |
Backend API URL | - | Yes |
VITE_AZURE_CLIENT_ID |
Azure AD Application (client) ID | - | Yes |
VITE_AZURE_TENANT_ID |
Azure AD Directory (tenant) ID | common |
Yes |
VITE_AZURE_REDIRECT_URI |
OAuth redirect URI | window.location.origin |
No |
VITE_AZURE_API_SCOPE |
API scope for backend access | User.Read |
Yes |
VITE_ENV |
Environment name | development |
No |
VITE_DEBUG |
Enable debug logs | false |
No |
The vite.config.ts file configures:
- Port: Development server runs on port 7001
- Proxy: API requests are proxied to avoid CORS issues
- Build: Output directory and optimization settings
- Plugins: React plugin with Fast Refresh
The tsconfig.json file enables:
- Strict Mode: Full type checking
- Path Aliases: Import shortcuts (e.g.,
@/components) - JSON Imports: Import JSON files as modules
- JSX: React JSX support
Code quality rules include:
- TypeScript ESLint recommended rules
- React Hooks rules
- React Refresh rules
- Custom rules for consistency
Code formatting settings:
- 2 spaces indentation
- Single quotes
- Trailing commas
- 100 character line width
# Run all tests once
pnpm test
# Run tests in watch mode
pnpm test:watch
# Generate coverage report
pnpm test:coverageTests are located next to the files they test:
src/
βββ components/
β βββ Alert.tsx
β βββ Alert.test.tsx
βββ utils/
β βββ errorHandler.ts
β βββ errorHandler.test.ts
Use React Testing Library and Vitest:
import { render, screen } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import Alert from './Alert';
describe('Alert', () => {
it('renders success alert', () => {
render(<Alert variant="success">Success message</Alert>);
expect(screen.getByText('Success message')).toBeInTheDocument();
});
});# Build the application
pnpm build
# Preview the build locally
pnpm previewThe build output will be in the dist/ directory.
- Update environment variables for production
- Run
pnpm typecheckto ensure no type errors - Run
pnpm lintto ensure code quality - Run
pnpm testto ensure all tests pass - Run
pnpm buildto create production build - Test the production build with
pnpm preview - Deploy
dist/directory to hosting service - Verify API connectivity in production
- Test critical user flows
The application can be deployed to:
- Vercel: Automatic deployments from Git
- Netlify: Continuous deployment
- AWS S3 + CloudFront: Static hosting with CDN
- Azure Static Web Apps: Integrated with Azure services
- Docker: Containerized deployment
Create environment-specific .env files:
.env.development- Development settings.env.staging- Staging settings.env.production- Production settings
- Fork the repository and create a feature branch
- Follow coding standards and conventions
- Write tests for new features
- Update documentation as needed
- Submit a pull request to the
devbranch
- Ensure all tests pass
- Update README if needed
- Add description of changes
- Request review from maintainers
- Address review feedback
- Merge after approval
- Code follows project conventions
- TypeScript types are properly defined
- Components are properly tested
- No console errors or warnings
- Accessibility considerations addressed
- Performance implications considered
- Documentation updated
# Error: Port 7001 is already in use
# Solution: Kill the process or use a different port
lsof -ti:7001 | xargs kill -9
# Or change the port in vite.config.ts# Error: Network Error or CORS issues
# Solution: Verify API is running and VITE_API_BASE_URL is correct
curl http://localhost:5000/api/health# Error: Type errors during build
# Solution: Run type check and fix errors
pnpm typecheck# Error: Cannot find module
# Solution: Clear cache and reinstall
rm -rf node_modules pnpm-lock.yaml
pnpm installEnable debug logging:
VITE_DEBUG=trueCheck browser console for detailed logs.
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Documentation: Check the
/docsdirectory
This project is private and proprietary. All rights reserved.
- Mystira.Admin.Api: Backend API service
- Mystira.App: Main application
See CHANGELOG.md for a list of changes.
Maintained by the Mystira development team.
Built with β€οΈ using React, TypeScript, and Vite