'use client';
import { ChevronLeft, ChevronRight, Loader2, Send } from 'lucide-react';
import { useRouter } from 'next/navigation';
import * as React from 'react';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import {
type TransferCategory,
type TransferCondition,
CATEGORY_ICONS,
CATEGORY_LABELS,
CONDITION_LABELS,
transferApi,
} from '@/lib/chuyen-nhuong-api';
import { cn } from '@/lib/utils';
import {
type TransferItemDraft,
useTransferWizardStore,
} from '@/lib/transfer-wizard-store';
const STEPS = [
'Danh mục',
'Sản phẩm',
'Định giá AI',
'Thông tin & Gửi',
] as const;
// ─── Step 1: Category Selection ────────────────────────
function StepCategory() {
const { category, setCategory, setStep } = useTransferWizardStore();
const categories = Object.entries(CATEGORY_LABELS) as [TransferCategory, string][];
return (
Chọn danh mục chuyển nhượng:
{categories.map(([value, label]) => (
))}
);
}
// ─── Step 2: Items ─────────────────────────────────────
function StepItems() {
const { items, addItem, removeItem, category } = useTransferWizardStore();
const [name, setName] = React.useState('');
const [condition, setCondition] = React.useState('GOOD');
const [askingPrice, setAskingPrice] = React.useState('');
const handleAdd = () => {
if (!name || !askingPrice || !category) return;
addItem({
name,
condition,
askingPriceVND: Number(askingPrice),
quantity: 1,
});
setName('');
setAskingPrice('');
};
return (
{items.length > 0 && (
{items.map((item) => (
{item.name} — {CONDITION_LABELS[item.condition]}
{new Intl.NumberFormat('vi-VN').format(item.askingPriceVND)} VND
))}
)}
);
}
// ─── Step 3: AI Estimate ───────────────────────────────
function StepAiEstimate() {
const { items, category, aiEstimate, isEstimating, setAiEstimate, setIsEstimating } = useTransferWizardStore();
const handleEstimate = async () => {
if (!category || items.length === 0) return;
setIsEstimating(true);
try {
const payload = items.map((item) => ({
category,
condition: item.condition,
originalPriceVND: item.askingPriceVND,
purchaseYear: new Date().getFullYear(),
}));
const result = await transferApi.estimate(payload);
setAiEstimate(result);
} catch {
setAiEstimate(null);
} finally {
setIsEstimating(false);
}
};
return (
Sử dụng AI để ước tính giá trị chuyển nhượng dựa trên danh mục, tình trạng và giá gốc.
{aiEstimate && (
Tổng ước tính: {new Intl.NumberFormat('vi-VN').format(Number(aiEstimate.totalEstimateVND))} VND
Độ tin cậy: {Math.round(aiEstimate.avgConfidence * 100)}%
)}
);
}
// ─── Step 4: Details & Submit ──────────────────────────
function StepDetails() {
const store = useTransferWizardStore();
const router = useRouter();
const [submitting, setSubmitting] = React.useState(false);
const handleSubmit = async () => {
if (!store.category) return;
setSubmitting(true);
try {
const payload = {
category: store.category,
title: store.title,
description: store.description || undefined,
address: store.address,
district: store.district,
city: store.city,
latitude: 0,
longitude: 0,
askingPriceVND: store.askingPriceVND || store.items.reduce((sum, i) => sum + i.askingPriceVND * i.quantity, 0),
pricingSource: store.pricingSource,
isNegotiable: store.isNegotiable,
items: store.items.map((i) => ({
name: i.name,
brand: i.brand,
modelName: i.modelName,
category: store.category!,
condition: i.condition,
purchaseYear: i.purchaseYear,
originalPriceVND: i.askingPriceVND,
askingPriceVND: i.askingPriceVND,
quantity: i.quantity,
notes: i.notes,
})),
};
await transferApi.create(payload);
store.reset();
router.push('/chuyen-nhuong');
} catch {
// Error handling deferred to toast integration
} finally {
setSubmitting(false);
}
};
return (
);
}
// ─── Main Wizard ───────────────────────────────────────
export function TransferWizardClient() {
const { currentStep, setStep, items, category } = useTransferWizardStore();
const canNext = () => {
if (currentStep === 0) return !!category;
if (currentStep === 1) return items.length > 0;
return true;
};
return (
Đăng tin chuyển nhượng
{/* Step indicator */}
{STEPS.map((label, i) => (
{i > 0 && }
))}
{STEPS[currentStep]}
{currentStep === 0 && }
{currentStep === 1 && }
{currentStep === 2 && }
{currentStep === 3 && }
{/* Navigation */}
{currentStep < 3 && (
)}
);
}