import { useState, useEffect } from 'react'; // Import useEffect
import { router, usePage } from '@inertiajs/react';
import { route } from 'ziggy-js';
import { ArrowLeft, ArrowRight, Save, PlusCircle, Rocket, Upload } from 'lucide-react';
import ReceptionLayout from '@/Layouts/ReceptionLayout';
import { Card, Button, TextInput, Select, Field } from '@/Components/Ui';
import { useTheme } from '@/Contexts/ThemeContext';
import type { SetupStepData, RoomTypeOption, UnitPreview } from '@/types/Reception';
interface Props {
setup: SetupStepData;
errors?: Record;
}
export default function SetupStep({ setup, errors = {} }: Props) {
const { flash } = usePage().props as any;
const { isDark } = useTheme();
const [step, setStep] = useState(setup.step);
// Sync local step with server-provided step when it changes
useEffect(() => {
setStep(setup.step);
}, [setup.step]);
const [form, setForm] = useState({});
const [brandForm, setBrandForm] = useState({
site_name: setup.site_name,
whatsapp_number: setup.whatsapp_number,
contact_phone: setup.contact_phone,
contact_email: setup.contact_email,
});
const [logoFile, setLogoFile] = useState(null);
const [faviconFile, setFaviconFile] = useState(null);
const [heroFiles, setHeroFiles] = useState([]);
const [galleryFiles, setGalleryFiles] = useState([]);
const [typeForm, setTypeForm] = useState({
name: '',
price_tzs: '',
price_usd: '',
capacity: '2',
online_quota: '0',
cover_image: null as File | null,
gallery: [] as File[],
});
const [unitForm, setUnitForm] = useState({
room_type_id: '',
unit_numbers: '',
});
const [isLive, setIsLive] = useState(setup.is_live);
const [submitting, setSubmitting] = useState(false);
const submitStep = (e: React.FormEvent) => {
e.preventDefault();
setSubmitting(true);
const fd = new FormData();
if (step === 1) {
Object.entries(brandForm).forEach(([k,v]) => fd.append(k, String(v)));
if (logoFile) fd.append('logo', logoFile);
if (faviconFile) fd.append('favicon', faviconFile);
heroFiles.forEach(f => fd.append('hero_images[]', f));
galleryFiles.forEach(f => fd.append('home_gallery_images[]', f));
} else if (step === 2) {
Object.entries(typeForm).forEach(([k,v]) => {
if (k === 'cover_image' && v) fd.append('cover_image', v as File);
else if (k === 'gallery') (v as File[]).forEach(f => fd.append('gallery[]', f));
else fd.append(k, String(v));
});
} else if (step === 3) {
Object.entries(unitForm).forEach(([k,v]) => fd.append(k, String(v)));
} else if (step === 4) {
fd.append('is_live', '1');
}
router.post(route('reception.admin.setup.save', step), fd, {
forceFormData: true,
onFinish: () => setSubmitting(false),
onSuccess: () => {},
});
};
const goToStep = (s: number) => {
router.get(route('reception.admin.setup.step', s), {}, { preserveState: true });
};
const progress = Math.round((step / 4) * 100);
const textareaClass = isDark
? 'w-full rounded-lg border border-white/10 bg-white/[0.04] px-3 py-2 text-sm text-white placeholder:text-zinc-500 focus:border-amber-400/50 focus:outline-none focus:ring-1 focus:ring-amber-400/40'
: 'w-full rounded-lg border border-[#E2DCD2] bg-white px-3 py-2 text-sm text-[#2C2A29] placeholder:text-stone-500 focus:border-amber-600/60 focus:outline-none focus:ring-1 focus:ring-amber-600/30';
const fileInputClass = isDark
? 'block w-full text-sm text-zinc-400 file:mr-4 file:rounded-lg file:border-0 file:bg-white/10 file:px-4 file:py-2 file:text-sm file:font-medium file:text-white hover:file:bg-white/20'
: 'block w-full text-sm text-stone-600 file:mr-4 file:rounded-lg file:border-0 file:bg-black/5 file:px-4 file:py-2 file:text-sm file:font-medium file:text-stone-800 hover:file:bg-black/10';
return (
Finish once, then your system is ready to demo & sell.
{/* Progress */}
Step {step} of 4
{progress}%
{/* Step indicators */}
{[1,2,3,4].map(s => (
))}
{flash?.success && (
{flash.success}
)}
{/* Error banner */}
{Object.keys(errors).length > 0 && (
Please fix the following errors:
{Object.entries(errors).map(([key, msg]) => (
- {msg}
))}
)}
);
}import { useState, useEffect } from 'react'; // Import useEffect
import { router, usePage } from '@inertiajs/react';
import { route } from 'ziggy-js';
import { ArrowLeft, ArrowRight, Save, PlusCircle, Rocket, Upload } from 'lucide-react';
import ReceptionLayout from '@/Layouts/ReceptionLayout';
import { Card, Button, TextInput, Select, Field } from '@/Components/Ui';
import { useTheme } from '@/Contexts/ThemeContext';
import type { SetupStepData, RoomTypeOption, UnitPreview } from '@/types/Reception';
interface Props {
setup: SetupStepData;
errors?: Record;
}
export default function SetupStep({ setup, errors = {} }: Props) {
const { flash } = usePage().props as any;
const { isDark } = useTheme();
const [step, setStep] = useState(setup.step);
// Sync local step with server-provided step when it changes
useEffect(() => {
setStep(setup.step);
}, [setup.step]);
const [form, setForm] = useState({});
const [brandForm, setBrandForm] = useState({
site_name: setup.site_name,
whatsapp_number: setup.whatsapp_number,
contact_phone: setup.contact_phone,
contact_email: setup.contact_email,
});
const [logoFile, setLogoFile] = useState(null);
const [faviconFile, setFaviconFile] = useState(null);
const [heroFiles, setHeroFiles] = useState([]);
const [galleryFiles, setGalleryFiles] = useState([]);
const [typeForm, setTypeForm] = useState({
name: '',
price_tzs: '',
price_usd: '',
capacity: '2',
online_quota: '0',
cover_image: null as File | null,
gallery: [] as File[],
});
const [unitForm, setUnitForm] = useState({
room_type_id: '',
unit_numbers: '',
});
const [isLive, setIsLive] = useState(setup.is_live);
const [submitting, setSubmitting] = useState(false);
const submitStep = (e: React.FormEvent) => {
e.preventDefault();
setSubmitting(true);
const fd = new FormData();
if (step === 1) {
Object.entries(brandForm).forEach(([k,v]) => fd.append(k, String(v)));
if (logoFile) fd.append('logo', logoFile);
if (faviconFile) fd.append('favicon', faviconFile);
heroFiles.forEach(f => fd.append('hero_images[]', f));
galleryFiles.forEach(f => fd.append('home_gallery_images[]', f));
} else if (step === 2) {
Object.entries(typeForm).forEach(([k,v]) => {
if (k === 'cover_image' && v) fd.append('cover_image', v as File);
else if (k === 'gallery') (v as File[]).forEach(f => fd.append('gallery[]', f));
else fd.append(k, String(v));
});
} else if (step === 3) {
Object.entries(unitForm).forEach(([k,v]) => fd.append(k, String(v)));
} else if (step === 4) {
fd.append('is_live', '1');
}
router.post(route('reception.admin.setup.save', step), fd, {
forceFormData: true,
onFinish: () => setSubmitting(false),
onSuccess: () => {},
});
};
const goToStep = (s: number) => {
router.get(route('reception.admin.setup.step', s), {}, { preserveState: true });
};
const progress = Math.round((step / 4) * 100);
const textareaClass = isDark
? 'w-full rounded-lg border border-white/10 bg-white/[0.04] px-3 py-2 text-sm text-white placeholder:text-zinc-500 focus:border-amber-400/50 focus:outline-none focus:ring-1 focus:ring-amber-400/40'
: 'w-full rounded-lg border border-[#E2DCD2] bg-white px-3 py-2 text-sm text-[#2C2A29] placeholder:text-stone-500 focus:border-amber-600/60 focus:outline-none focus:ring-1 focus:ring-amber-600/30';
const fileInputClass = isDark
? 'block w-full text-sm text-zinc-400 file:mr-4 file:rounded-lg file:border-0 file:bg-white/10 file:px-4 file:py-2 file:text-sm file:font-medium file:text-white hover:file:bg-white/20'
: 'block w-full text-sm text-stone-600 file:mr-4 file:rounded-lg file:border-0 file:bg-black/5 file:px-4 file:py-2 file:text-sm file:font-medium file:text-stone-800 hover:file:bg-black/10';
return (
Finish once, then your system is ready to demo & sell.
{/* Progress */}
Step {step} of 4
{progress}%
{/* Step indicators */}
{[1,2,3,4].map(s => (
))}
{flash?.success && (
{flash.success}
)}
{/* Error banner */}
{Object.keys(errors).length > 0 && (
Please fix the following errors:
{Object.entries(errors).map(([key, msg]) => (
- {msg}
))}
)}
);
}