Chang-Store is a modern Single Page Application (SPA) built with React 19, TypeScript, and Vite. It serves as a virtual fashion studio powered by Google Gemini for advanced image editing and generative fashion features.
- Virtual Try-on: Seamlessly try out clothes on models using generative AI integration.
- Lookbook Generation: Automatically curate and generate fashion lookbooks.
- Background Replacement: Easily swap image backgrounds for varied aesthetics.
- Pose Changing: Control and change the poses of subjects in fashion shots.
- Upscaling & Editing: AI-powered upscaling and diverse image editing tools.
- Frontend: React 19, Vite 6, TypeScript
- Styling: Tailwind CSS v4, PostCSS
- State Management: React Context & Hooks
- AI Integration: Google Gemini SDK (
@google/genai) - Testing: Vitest, React Testing Library
- Tooling: ESLint, TSX
To run the application locally, start by copying the example environment file:
cp .env.example .env.localMake sure to populate the .env.local file with the following keys:
GEMINI_API_KEY: Google Gemini API key used for the main AI generative features.GOOGLE_CLIENT_ID: Google OAuth client ID required for Google Drive synchronization.
The project follows a Gemini-first service architecture:
Component (Thin UI) → Hook (State + Logic) → Service Facade → Gemini API
Dependencies are managed strictly by the tree order:
LanguageProvider → ApiProvider → GoogleDriveProvider → ImageGalleryProvider → ImageViewerProvider → AppContent
Generative image features go through src/services/imageEditingService.ts, which delegates to the Gemini service layer in src/services/gemini/*.
# Install dependencies
npm install
# Start the development server
npm run dev
# Run automated tests
npm run test
# Build for production
npm run buildThe canonical UI source of truth is docs/design-guidelines.md; follow its Runway-inspired redesign contract for visual styling and interaction patterns.
Localization (i18n) is managed via src/locales/en.ts functioning as the main source of truth. Always use const { t } = useLanguage(); t('key.path') inside components for text representation.