fix: tags không có trong csdl gây nên lỗi crash backend
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Trash2, Users } from 'lucide-react';
|
||||
import { Trash2, Users, Tag as TagIcon } from 'lucide-react';
|
||||
import { useTourStore } from '@/store/useTourStore';
|
||||
|
||||
export const CreateTourModal = ({ isOpen, onClose, onSuccess }: { isOpen: boolean, onClose: () => void, onSuccess: (tour: any) => void }) => {
|
||||
@@ -12,6 +12,10 @@ export const CreateTourModal = ({ isOpen, onClose, onSuccess }: { isOpen: boolea
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const createTour = useTourStore((state) => state.createTour);
|
||||
|
||||
const availableTags = ['Văn hóa', 'Mạo hiểm', 'Nghỉ dưỡng', 'Thư giãn', 'Ẩm thực', 'Khám phá', 'Gia đình'];
|
||||
const [selectedTags, setSelectedTags] = useState<string[]>([]);
|
||||
const [customTag, setCustomTag] = useState('');
|
||||
|
||||
const [members, setMembers] = useState<any[]>([]);
|
||||
const [query, setQuery] = useState('');
|
||||
const [results, setResults] = useState<any[]>([]);
|
||||
@@ -49,6 +53,20 @@ export const CreateTourModal = ({ isOpen, onClose, onSuccess }: { isOpen: boolea
|
||||
setMembers((prev) => prev.filter((m) => m.id !== userId));
|
||||
};
|
||||
|
||||
const toggleTag = (tag: string) => {
|
||||
setSelectedTags(prev =>
|
||||
prev.includes(tag) ? prev.filter(t => t !== tag) : [...prev, tag]
|
||||
);
|
||||
};
|
||||
|
||||
const addCustomTag = () => {
|
||||
const tag = customTag.trim();
|
||||
if (tag && !selectedTags.includes(tag)) {
|
||||
setSelectedTags([...selectedTags, tag]);
|
||||
setCustomTag('');
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
setIsLoading(true);
|
||||
@@ -62,7 +80,8 @@ export const CreateTourModal = ({ isOpen, onClose, onSuccess }: { isOpen: boolea
|
||||
memberIds,
|
||||
adultCount,
|
||||
childCount,
|
||||
childDiscount
|
||||
childDiscount,
|
||||
tags: selectedTags
|
||||
});
|
||||
onSuccess(tour);
|
||||
onClose();
|
||||
@@ -140,6 +159,45 @@ export const CreateTourModal = ({ isOpen, onClose, onSuccess }: { isOpen: boolea
|
||||
<p className="text-[10px] text-blue-400 italic font-medium">* Dùng để tính toán đơn giá bình quân trong báo cáo chi phí.</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-bold text-gray-700 mb-2 flex items-center gap-2">
|
||||
<TagIcon className="w-4 h-4" /> Phân loại Tour
|
||||
</label>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{availableTags.map(tag => (
|
||||
<button
|
||||
key={tag}
|
||||
type="button"
|
||||
onClick={() => toggleTag(tag)}
|
||||
className={`px-3 py-1.5 rounded-full text-xs font-bold transition-all border ${
|
||||
selectedTags.includes(tag)
|
||||
? 'bg-blue-600 text-white border-blue-600 shadow-md shadow-blue-100'
|
||||
: 'bg-white text-gray-500 border-gray-200 hover:border-blue-300'
|
||||
}`}
|
||||
>
|
||||
{tag}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex gap-2 mt-3">
|
||||
<input
|
||||
type="text"
|
||||
value={customTag}
|
||||
onChange={(e) => setCustomTag(e.target.value)}
|
||||
onKeyDown={(e) => e.key === 'Enter' && (e.preventDefault(), addCustomTag())}
|
||||
placeholder="Thêm nhãn tùy chỉnh..."
|
||||
className="flex-1 px-3 py-2 bg-gray-50 border border-gray-100 rounded-xl text-xs outline-none focus:ring-2 focus:ring-blue-500"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={addCustomTag}
|
||||
className="px-4 py-2 bg-blue-50 text-blue-600 rounded-xl text-xs font-bold hover:bg-blue-100 transition-all"
|
||||
>
|
||||
Thêm
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-bold text-gray-700 mb-2">Thành viên tham gia</label>
|
||||
<div className="flex flex-wrap gap-3">
|
||||
|
||||
Reference in New Issue
Block a user