feat: Integrate Stripe payment processing and enhance admin settings management
- Removed the previous demo payment system and implemented a real integration with Stripe for handling payments. - Added new API routes for creating payment intents and handling webhooks from Stripe. - Updated the database schema to include an Order model for storing payment details. - Enhanced the admin page to manage pricing items, including the ability to upload 3D models. - Introduced a settings management feature for the admin panel, allowing for dynamic key-value pairs. - Improved the RobotModel component to support dynamic attire based on uploaded models. - Added error handling and validation for file uploads and settings management.
This commit is contained in:
@@ -5,15 +5,25 @@ import { useGLTF } from '@react-three/drei';
|
||||
import { useFrame } from '@react-three/fiber';
|
||||
import * as THREE from 'three';
|
||||
import { useConfigStore } from '@/store/useConfigStore';
|
||||
import { personaStore, usePersonaStore } from '@/store/usePersonaStore';
|
||||
|
||||
const ATTIRE_GLB: Record<string, string> = {
|
||||
const STATIC_ATTIRE_GLB: Record<string, string> = {
|
||||
'emarati-kandura': '/Kandoura.glb',
|
||||
'industrial-vest': '/Vest.glb',
|
||||
'business-suit': '/Suit.glb',
|
||||
};
|
||||
|
||||
// Preload all attire models so they're cached before user clicks
|
||||
Object.values(ATTIRE_GLB).forEach((path) => useGLTF.preload(path));
|
||||
// Preload static attire models so they're cached before user clicks
|
||||
Object.values(STATIC_ATTIRE_GLB).forEach((p) => useGLTF.preload(p));
|
||||
|
||||
/** Merge static map with any custom GLBs stored in the persona store */
|
||||
function buildAttireGlbMap(personas: { id: string; modelPath?: string }[]): Record<string, string> {
|
||||
const dynamic: Record<string, string> = {};
|
||||
personas.forEach((p) => {
|
||||
if (p.modelPath && p.id !== 'none') dynamic[p.id] = p.modelPath;
|
||||
});
|
||||
return { ...dynamic, ...STATIC_ATTIRE_GLB }; // static takes priority
|
||||
}
|
||||
|
||||
function easeInOutCubic(t: number): number {
|
||||
return t < 0.5
|
||||
@@ -78,6 +88,8 @@ export function RobotModel({ onError }: RobotModelProps) {
|
||||
|
||||
const activeColors = useConfigStore((state) => state.activeColors);
|
||||
const activePersonaAttire = useConfigStore((state) => state.activePersonaAttire);
|
||||
// Subscribe to persona store so custom GLB paths are reactive
|
||||
const personas = usePersonaStore((s) => s.personas);
|
||||
|
||||
// Detect attire change and trigger spin
|
||||
useEffect(() => {
|
||||
@@ -174,7 +186,7 @@ export function RobotModel({ onError }: RobotModelProps) {
|
||||
});
|
||||
}, [activeColors]);
|
||||
|
||||
const attireGlbPath = ATTIRE_GLB[displayedAttire] || null;
|
||||
const attireGlbPath = buildAttireGlbMap(personas)[displayedAttire] || null;
|
||||
|
||||
const handleAttireLoaded = () => {
|
||||
setAttireReady(true);
|
||||
|
||||
Reference in New Issue
Block a user