Merges ac-helper (PHP Activation Calendar) and brief-extractor (Python AI) into a single Docker app with React/TypeScript frontend. Features: - Brief upload → AI extraction → review → Activation Calendar import - Handsontable v17 spreadsheet with dependent dropdowns (148 categories) - AI natural language commands via Gemini (YOLO mode, voice input) - Azure AD MSAL SPA PKCE authentication, user roles (user/admin) - CSV Activation Calendar export - Real-time WebSocket job progress - Admin: user management, dropdown Excel upload - Multi-stage Dockerfile, docker-compose, nginx proxy instructions Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
30 lines
774 B
TypeScript
30 lines
774 B
TypeScript
import { create } from 'zustand'
|
|
import type { CategoryData } from '../types'
|
|
import { getCategories } from '../api/dropdowns'
|
|
|
|
interface DropdownStore {
|
|
categories: CategoryData[]
|
|
loaded: boolean
|
|
fetch: () => Promise<void>
|
|
getMediaTypes: (categoryName: string) => string[]
|
|
}
|
|
|
|
export const useDropdownStore = create<DropdownStore>((set, get) => ({
|
|
categories: [],
|
|
loaded: false,
|
|
|
|
fetch: async () => {
|
|
if (get().loaded) return
|
|
try {
|
|
const categories = await getCategories(true)
|
|
set({ categories, loaded: true })
|
|
} catch {
|
|
// fall through — will use empty arrays
|
|
}
|
|
},
|
|
|
|
getMediaTypes: (categoryName: string) => {
|
|
const cat = get().categories.find(c => c.name === categoryName)
|
|
return cat?.mediaTypes ?? []
|
|
},
|
|
}))
|