fix: cách các modals hiển thị trên browser điện thoại
This commit is contained in:
@@ -385,10 +385,10 @@ export const AddLocationModal = ({ isOpen, onClose, tourId, initialLegId, editin
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-[2000] flex items-center justify-center p-4">
|
||||
<div className="fixed inset-0 z-[2000] flex items-end sm:items-center justify-center p-0 sm:p-4">
|
||||
<div className="absolute inset-0 bg-gray-900/60 backdrop-blur-sm" onClick={onClose} />
|
||||
<div className="relative w-full max-w-lg bg-[var(--surface)] rounded-3xl shadow-2xl overflow-hidden p-8 max-h-[90vh] overflow-y-auto">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<div className="relative w-full h-full sm:max-w-lg bg-[var(--surface)] rounded-t-2xl sm:rounded-3xl shadow-2xl overflow-hidden flex flex-col sm:max-h-[85vh] animate-in zoom-in-95 duration-200">
|
||||
<div className="flex justify-between items-center mb-6 p-5 sm:p-8 pb-0 sm:pb-0 shrink-0">
|
||||
<h2 className="text-2xl font-bold text-[var(--text-primary)] flex items-center gap-2">
|
||||
<MapIcon className="w-6 h-6 text-blue-600" /> {titleText}
|
||||
</h2>
|
||||
@@ -473,7 +473,7 @@ export const AddLocationModal = ({ isOpen, onClose, tourId, initialLegId, editin
|
||||
</button>
|
||||
)}
|
||||
|
||||
<form onSubmit={handleSubmit} className="space-y-4">
|
||||
<form onSubmit={handleSubmit} className="space-y-4 overflow-y-auto flex-1 text-left">
|
||||
<div>
|
||||
<label className="block text-sm font-bold text-[var(--text-secondary)] mb-1">Tên địa điểm</label>
|
||||
<input
|
||||
|
||||
@@ -214,10 +214,10 @@ export const AddMemberModal: React.FC<AddMemberModalProps> = ({ isOpen, onClose,
|
||||
if (!isOpen || isPublicView) return null; // Do not render if public view
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-[2000] flex items-center justify-center p-4">
|
||||
<div className="fixed inset-0 z-[2000] flex items-end sm:items-center justify-center p-0 sm:p-4">
|
||||
<div className="absolute inset-0 bg-gray-900/60 backdrop-blur-sm" onClick={onClose} />
|
||||
<div className="relative w-full max-w-md bg-white rounded-3xl shadow-2xl overflow-hidden flex flex-col max-h-[90vh]">
|
||||
<div className="p-5 border-b border-gray-100 flex justify-between items-center bg-gray-50/50">
|
||||
<div className="relative w-full sm:max-w-md bg-white rounded-t-2xl sm:rounded-3xl shadow-2xl overflow-hidden flex flex-col h-full sm:h-auto sm:max-h-[85vh] animate-in zoom-in-95 duration-200">
|
||||
<div className="p-5 border-b border-gray-100 flex justify-between items-center bg-gray-50/50 shrink-0">
|
||||
<div>
|
||||
<h2 className="text-lg font-bold text-gray-900 flex items-center gap-2">
|
||||
<UserPlus className="w-5 h-5 text-blue-600" /> {canCreateDirectly ? 'Thành viên hành trình' : 'Mời tham gia tour'}
|
||||
@@ -392,10 +392,10 @@ export const AddMemberModal: React.FC<AddMemberModalProps> = ({ isOpen, onClose,
|
||||
{submitError}
|
||||
</div>
|
||||
)}
|
||||
{loading ? (
|
||||
<div className="flex justify-center py-10"><Loader2 className="w-8 h-8 animate-spin text-blue-600" /></div>
|
||||
) : (
|
||||
<div className="space-y-2 max-h-[30vh] overflow-y-auto pr-1">
|
||||
{loading ? (
|
||||
<div className="flex justify-center py-10"><Loader2 className="w-8 h-8 animate-spin text-blue-600" /></div>
|
||||
) : (
|
||||
<div className="space-y-2 max-h-[30vh] sm:max-h-[25vh] overflow-y-auto pr-1">
|
||||
{query.trim() && canCreateDirectly && (
|
||||
<button
|
||||
type="button"
|
||||
|
||||
@@ -172,10 +172,10 @@ export const AddPhotoModal: React.FC<AddPhotoModalProps> = ({ isOpen, onClose, t
|
||||
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-[2500] flex items-center justify-center p-4">
|
||||
<div className="fixed inset-0 z-[2500] flex items-end sm:items-center justify-center p-0 sm:p-4">
|
||||
<div className="absolute inset-0 bg-gray-900/60 backdrop-blur-sm" onClick={onClose} />
|
||||
<div className="relative w-full max-w-lg bg-[var(--surface)] rounded-3xl shadow-2xl overflow-hidden p-8 max-h-[90vh] flex flex-col animate-in zoom-in-95 duration-200">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<div className="relative w-full h-full sm:max-w-lg bg-[var(--surface)] rounded-t-2xl sm:rounded-3xl shadow-2xl overflow-hidden flex flex-col sm:max-h-[85vh] animate-in zoom-in-95 duration-200">
|
||||
<div className="flex justify-between items-center mb-6 p-5 sm:p-8 pb-0 sm:pb-0 shrink-0">
|
||||
<h2 className="text-2xl font-bold text-[var(--text-primary)] flex items-center gap-2">
|
||||
<ImageIcon className="w-6 h-6 text-blue-600" /> Tải ảnh lên
|
||||
</h2>
|
||||
@@ -184,7 +184,7 @@ export const AddPhotoModal: React.FC<AddPhotoModalProps> = ({ isOpen, onClose, t
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleSubmit} className="flex-1 flex flex-col min-h-0">
|
||||
<form onSubmit={handleSubmit} className="flex-1 flex flex-col min-h-0 p-5 sm:p-8 pt-0 sm:pt-0">
|
||||
<div
|
||||
onClick={() => fileInputRef.current?.click()}
|
||||
className="border-2 border-dashed border-[var(--border)] rounded-[32px] p-10 flex flex-col items-center justify-center cursor-pointer hover:bg-[var(--background)]/50 hover:border-blue-200 transition-all mb-6 group"
|
||||
|
||||
@@ -132,11 +132,11 @@ export const CommentModal: React.FC<CommentModalProps> = ({ isOpen, onClose, loc
|
||||
if (!isOpen) return null;
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-[5000] flex items-center justify-center p-4">
|
||||
<div className="fixed inset-0 z-[5000] flex items-end sm:items-center justify-center p-0 sm:p-4">
|
||||
<div className="absolute inset-0 bg-gray-900/60 backdrop-blur-sm animate-in fade-in duration-200" onClick={onClose} />
|
||||
<div className="relative w-full max-w-md bg-[var(--surface)] rounded-[32px] shadow-2xl overflow-hidden flex flex-col max-h-[80vh] animate-in zoom-in-95 duration-200">
|
||||
<div className="relative w-full h-full sm:max-w-md bg-[var(--surface)] rounded-t-2xl sm:rounded-[32px] shadow-2xl overflow-hidden flex flex-col sm:max-h-[85vh] animate-in zoom-in-95 duration-200">
|
||||
{/* Header */}
|
||||
<div className="p-6 border-b border-[var(--border)] flex justify-between items-center bg-[var(--surface)] sticky top-0 z-10">
|
||||
<div className="p-6 border-b border-[var(--border)] flex justify-between items-center bg-[var(--surface)] sticky top-0 z-10 shrink-0">
|
||||
<div>
|
||||
<h3 className="text-xl font-black text-[var(--text-primary)] flex items-center gap-2">
|
||||
<MessageSquare className="w-5 h-5 text-blue-600" />
|
||||
@@ -186,7 +186,7 @@ export const CommentModal: React.FC<CommentModalProps> = ({ isOpen, onClose, loc
|
||||
</div>
|
||||
|
||||
{/* Input Area */}
|
||||
<div className="p-4 bg-[var(--surface)] border-t border-[var(--border)]">
|
||||
<div className="p-4 bg-[var(--surface)] border-t border-[var(--border)] shrink-0">
|
||||
<div className="relative flex items-center gap-2">
|
||||
<input
|
||||
type="text"
|
||||
|
||||
@@ -13,13 +13,10 @@ export const ConfirmModal: React.FC<ConfirmModalProps> = ({ isOpen, title, messa
|
||||
if (!isOpen) return null;
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-[6000] flex items-center justify-center p-4">
|
||||
{/* Backdrop */}
|
||||
<div className="fixed inset-0 z-[6000] flex items-end sm:items-center justify-center p-0 sm:p-4">
|
||||
<div className="absolute inset-0 bg-gray-900/60 backdrop-blur-sm animate-in fade-in duration-200" onClick={onCancel} />
|
||||
|
||||
{/* Modal Content */}
|
||||
<div className="relative w-full max-w-sm bg-[var(--surface)] rounded-[32px] shadow-2xl p-8 animate-in zoom-in-95 duration-200">
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<div className="relative w-full sm:max-w-sm h-full sm:h-auto max-h-screen sm:max-h-[85vh] bg-[var(--surface)] rounded-t-2xl sm:rounded-2xl shadow-2xl p-6 sm:p-8 animate-in zoom-in-95 duration-200 flex flex-col">
|
||||
<div className="flex justify-between items-center mb-4 shrink-0">
|
||||
<div className="w-12 h-12 rounded-2xl bg-red-50 flex items-center justify-center text-red-500 shadow-inner">
|
||||
<AlertTriangle className="w-6 h-6" />
|
||||
</div>
|
||||
@@ -33,7 +30,7 @@ export const ConfirmModal: React.FC<ConfirmModalProps> = ({ isOpen, title, messa
|
||||
{message || 'Bạn có chắc chắn muốn thực hiện hành động này không?'}
|
||||
</p>
|
||||
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div className="grid grid-cols-2 gap-3 pt-2 mt-auto">
|
||||
<button
|
||||
onClick={onCancel}
|
||||
className="py-4 bg-[var(--background)] hover:bg-[var(--background)] text-[var(--text-secondary)] font-bold rounded-2xl transition-all active:scale-95"
|
||||
|
||||
@@ -118,7 +118,7 @@ export const CoordinateSelectModal: React.FC<CoordinateSelectModalProps> = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-[6000] flex items-center justify-center p-4 animate-in fade-in duration-200">
|
||||
<div className="fixed inset-0 z-[6000] flex items-end sm:items-center justify-center p-0 sm:p-4 animate-in fade-in duration-200">
|
||||
{/* Backdrop */}
|
||||
<div
|
||||
className="absolute inset-0 bg-slate-900/60 backdrop-blur-sm"
|
||||
@@ -126,7 +126,7 @@ export const CoordinateSelectModal: React.FC<CoordinateSelectModalProps> = ({
|
||||
/>
|
||||
|
||||
{/* Content */}
|
||||
<div className="relative w-full max-w-2xl h-[550px] bg-white dark:bg-slate-900 rounded-3xl shadow-2xl overflow-hidden flex flex-col border border-gray-100 dark:border-slate-800 animate-in zoom-in-95 duration-200">
|
||||
<div className="relative w-full h-full sm:w-auto sm:max-w-2xl sm:h-[85vh] bg-white dark:bg-slate-900 rounded-t-2xl sm:rounded-3xl shadow-2xl overflow-hidden flex flex-col border border-gray-100 dark:border-slate-800 animate-in zoom-in-95 duration-200">
|
||||
{/* Header */}
|
||||
<div className="p-4 border-b border-gray-100 dark:border-slate-800/80 flex items-center justify-between bg-white dark:bg-slate-900 shrink-0">
|
||||
<div className="flex items-center gap-2">
|
||||
@@ -145,7 +145,7 @@ export const CoordinateSelectModal: React.FC<CoordinateSelectModalProps> = ({
|
||||
</div>
|
||||
|
||||
{/* Map Body */}
|
||||
<div className="flex-1 bg-gray-50 dark:bg-slate-950 relative min-h-[300px]" style={{ zIndex: 10 }}>
|
||||
<div className="flex-1 bg-gray-50 dark:bg-slate-950 relative min-h-[300px] sm:min-h-0" style={{ zIndex: 10 }}>
|
||||
|
||||
{/* Floating Search Panel */}
|
||||
<div className="absolute top-4 left-4 right-4 sm:right-auto z-[1000] sm:w-80 bg-white/95 dark:bg-slate-900/95 backdrop-blur-md rounded-2xl border border-slate-150 dark:border-slate-800 shadow-xl p-2 flex flex-col gap-1.5">
|
||||
|
||||
@@ -101,10 +101,10 @@ export const CreateTourModal = ({ isOpen, onClose, onSuccess }: { isOpen: boolea
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-[2000] flex items-center justify-center p-4">
|
||||
<div className="fixed inset-0 z-[2000] flex items-end sm:items-center justify-center p-0 sm:p-4">
|
||||
<div className="absolute inset-0 bg-gray-900/60 backdrop-blur-sm" onClick={onClose} />
|
||||
<div className="relative w-full max-w-md bg-[var(--surface)] rounded-3xl shadow-2xl overflow-hidden flex flex-col max-h-[90vh]">
|
||||
<div className="p-5 border-b border-[var(--border)] flex justify-between items-center bg-[var(--background)]/50">
|
||||
<div className="relative w-full sm:max-w-md bg-[var(--surface)] rounded-t-2xl sm:rounded-3xl shadow-2xl overflow-hidden flex flex-col h-full sm:h-auto sm:max-h-[85vh] animate-in zoom-in-95 duration-200">
|
||||
<div className="p-5 border-b border-[var(--border)] flex justify-between items-center bg-[var(--background)]/50 shrink-0">
|
||||
<h2 className="text-xl font-bold text-[var(--text-primary)]">Tạo Tour mới</h2>
|
||||
<button onClick={onClose} className="p-2 hover:bg-[var(--background)] rounded-full transition-colors">✕</button>
|
||||
</div>
|
||||
|
||||
@@ -631,124 +631,124 @@ export const ItineraryTimeline = ({
|
||||
)}
|
||||
|
||||
{/* Modal Khai báo số chặng (Popover) */}
|
||||
{isLegCountModalOpen && (
|
||||
<div className="fixed inset-0 z-[4000] flex items-center justify-center p-4">
|
||||
<div className="absolute inset-0 bg-gray-900/60 dark:bg-slate-950/60 backdrop-blur-sm animate-in fade-in duration-200" onClick={() => setIsLegCountModalOpen(false)} />
|
||||
<div className="relative w-full max-w-sm bg-white dark:bg-slate-900 rounded-[32px] shadow-2xl p-8 animate-in zoom-in-95 duration-200">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h3 className="text-xl font-black text-gray-900 dark:text-white">Số chặng lộ trình</h3>
|
||||
<button onClick={() => setIsLegCountModalOpen(false)} className="p-2 hover:bg-gray-100 dark:hover:bg-slate-800 rounded-full transition-colors">
|
||||
<X className="w-5 h-5 text-gray-400 dark:text-slate-400" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p className="text-sm text-gray-500 dark:text-slate-400 mb-6 leading-relaxed">
|
||||
Bạn muốn chia chuyến đi này thành bao nhiêu chặng nhỏ? (Tối đa 20 chặng)
|
||||
</p>
|
||||
{isLegCountModalOpen && (
|
||||
<div className="fixed inset-0 z-[4000] flex items-end sm:items-center justify-center p-0 sm:p-4">
|
||||
<div className="absolute inset-0 bg-gray-900/60 dark:bg-slate-950/60 backdrop-blur-sm animate-in fade-in duration-200" onClick={() => setIsLegCountModalOpen(false)} />
|
||||
<div className="relative w-full sm:max-w-sm bg-white dark:bg-slate-900 rounded-t-2xl sm:rounded-[32px] shadow-2xl p-8 sm:p-8 h-full sm:h-auto sm:max-h-[85vh] animate-in zoom-in-95 duration-200 flex flex-col">
|
||||
<div className="flex justify-between items-center mb-6 shrink-0">
|
||||
<h3 className="text-xl font-black text-gray-900 dark:text-white">Số chặng lộ trình</h3>
|
||||
<button onClick={() => setIsLegCountModalOpen(false)} className="p-2 hover:bg-gray-100 dark:hover:bg-slate-800 rounded-full transition-colors">
|
||||
<X className="w-5 h-5 text-gray-400 dark:text-slate-400" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p className="text-sm text-gray-500 dark:text-slate-400 mb-6 leading-relaxed">
|
||||
Bạn muốn chia chuyến đi này thành bao nhiêu chặng nhỏ? (Tối đa 20 chặng)
|
||||
</p>
|
||||
|
||||
<div className="flex items-center justify-center gap-6 mb-8">
|
||||
<button
|
||||
onClick={() => setTempLegCount(Math.max(1, tempLegCount - 1))}
|
||||
className="w-12 h-12 rounded-2xl border-2 border-gray-100 dark:border-slate-700 flex items-center justify-center text-2xl font-bold text-gray-400 dark:text-slate-400 hover:border-blue-200 dark:hover:border-blue-500 hover:text-blue-600 dark:hover:text-blue-400 transition-all"
|
||||
>
|
||||
-
|
||||
</button>
|
||||
<span className="text-4xl font-black text-blue-600 dark:text-blue-400 w-12 text-center">{tempLegCount}</span>
|
||||
<button
|
||||
onClick={() => setTempLegCount(Math.min(20, tempLegCount + 1))}
|
||||
className="w-12 h-12 rounded-2xl border-2 border-gray-100 dark:border-slate-700 flex items-center justify-center text-2xl font-bold text-gray-400 dark:text-slate-400 hover:border-blue-200 dark:hover:border-blue-500 hover:text-blue-600 dark:hover:text-blue-400 transition-all"
|
||||
>
|
||||
+
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex items-center justify-center gap-6 mb-8">
|
||||
<button
|
||||
onClick={() => setTempLegCount(Math.max(1, tempLegCount - 1))}
|
||||
className="w-12 h-12 rounded-2xl border-2 border-gray-100 dark:border-slate-700 flex items-center justify-center text-2xl font-bold text-gray-400 dark:text-slate-400 hover:border-blue-200 dark:hover:border-blue-500 hover:text-blue-600 dark:hover:text-blue-400 transition-all"
|
||||
>
|
||||
-
|
||||
</button>
|
||||
<span className="text-4xl font-black text-blue-600 dark:text-blue-400 w-12 text-center">{tempLegCount}</span>
|
||||
<button
|
||||
onClick={() => setTempLegCount(Math.min(20, tempLegCount + 1))}
|
||||
className="w-12 h-12 rounded-2xl border-2 border-gray-100 dark:border-slate-700 flex items-center justify-center text-2xl font-bold text-gray-400 dark:text-slate-400 hover:border-blue-200 dark:hover:border-blue-500 hover:text-blue-600 dark:hover:text-blue-400 transition-all"
|
||||
>
|
||||
+
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={confirmDeclareLegs}
|
||||
className="w-full py-4 bg-blue-600 dark:bg-blue-700 hover:bg-blue-700 dark:hover:bg-blue-800 text-white font-bold rounded-2xl shadow-lg shadow-blue-100 dark:shadow-blue-950 transition-all active:scale-95"
|
||||
>
|
||||
Xác nhận
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<button
|
||||
onClick={confirmDeclareLegs}
|
||||
className="w-full py-4 bg-blue-600 dark:bg-blue-700 hover:bg-blue-700 dark:hover:bg-blue-800 text-white font-bold rounded-2xl shadow-lg shadow-blue-100 dark:shadow-blue-950 transition-all active:scale-95 mt-auto"
|
||||
>
|
||||
Xác nhận
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Modal Chỉnh sửa Chặng (Popover) */}
|
||||
{isEditModalOpen && (
|
||||
<div className="fixed inset-0 z-[4000] flex items-center justify-center p-4">
|
||||
<div className="absolute inset-0 bg-gray-900/60 dark:bg-slate-950/60 backdrop-blur-sm animate-in fade-in duration-200" onClick={() => setIsEditModalOpen(false)} />
|
||||
<div className="relative w-full max-w-md bg-white dark:bg-slate-900 rounded-[32px] shadow-2xl p-8 animate-in zoom-in-95 duration-200">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h3 className="text-xl font-black text-gray-900 dark:text-white">Chỉnh sửa Chặng</h3>
|
||||
<button onClick={() => setIsEditModalOpen(false)} className="p-2 hover:bg-gray-100 dark:hover:bg-slate-800 rounded-full transition-colors">
|
||||
<X className="w-5 h-5 text-gray-400 dark:text-slate-400" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="space-y-5">
|
||||
<div>
|
||||
<label className="block text-xs font-black text-gray-400 dark:text-slate-400 uppercase tracking-widest mb-2 ml-1">Tên chặng</label>
|
||||
<input
|
||||
type="text"
|
||||
value={editingLegData.note}
|
||||
onChange={(e) => setEditingLegData({ ...editingLegData, note: e.target.value })}
|
||||
placeholder="VD: Ngày 1: Khởi hành"
|
||||
className="w-full px-5 py-4 bg-gray-50 dark:bg-slate-800 border border-gray-100 dark:border-slate-700 rounded-2xl focus:ring-2 focus:ring-blue-500 outline-none transition-all text-sm text-gray-800 dark:text-white"
|
||||
/>
|
||||
</div>
|
||||
{isEditModalOpen && (
|
||||
<div className="fixed inset-0 z-[4000] flex items-end sm:items-center justify-center p-0 sm:p-4">
|
||||
<div className="absolute inset-0 bg-gray-900/60 dark:bg-slate-950/60 backdrop-blur-sm animate-in fade-in duration-200" onClick={() => setIsEditModalOpen(false)} />
|
||||
<div className="relative w-full sm:max-w-md bg-white dark:bg-slate-900 rounded-t-2xl sm:rounded-[32px] shadow-2xl p-8 sm:p-8 h-full sm:h-auto sm:max-h-[85vh] animate-in zoom-in-95 duration-200 flex flex-col">
|
||||
<div className="flex justify-between items-center mb-6 shrink-0">
|
||||
<h3 className="text-xl font-black text-gray-900 dark:text-white">Chỉnh sửa Chặng</h3>
|
||||
<button onClick={() => setIsEditModalOpen(false)} className="p-2 hover:bg-gray-100 dark:hover:bg-slate-800 rounded-full transition-colors">
|
||||
<X className="w-5 h-5 text-gray-400 dark:text-slate-400" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="space-y-5 overflow-y-auto flex-1">
|
||||
<div>
|
||||
<label className="block text-xs font-black text-gray-400 dark:text-slate-400 uppercase tracking-widest mb-2 ml-1">Tên chặng</label>
|
||||
<input
|
||||
type="text"
|
||||
value={editingLegData.note}
|
||||
onChange={(e) => setEditingLegData({ ...editingLegData, note: e.target.value })}
|
||||
placeholder="VD: Ngày 1: Khởi hành"
|
||||
className="w-full px-5 py-4 bg-gray-50 dark:bg-slate-800 border border-gray-100 dark:border-slate-700 rounded-2xl focus:ring-2 focus:ring-blue-500 outline-none transition-all text-sm text-gray-800 dark:text-white"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="flex items-center gap-2 text-xs font-black text-gray-400 dark:text-slate-400 uppercase tracking-widest mb-2 ml-1">
|
||||
<AlignLeft className="w-3 h-3" /> Mô tả chi tiết
|
||||
</label>
|
||||
<textarea
|
||||
value={editingLegData.description}
|
||||
onChange={(e) => setEditingLegData({ ...editingLegData, description: e.target.value })}
|
||||
placeholder="Mô tả các hoạt động chính trong chặng này..."
|
||||
className="w-full px-5 py-4 bg-gray-50 dark:bg-slate-800 border border-gray-100 dark:border-slate-700 rounded-2xl focus:ring-2 focus:ring-blue-500 outline-none transition-all text-sm min-h-[120px] resize-none text-gray-800 dark:text-white"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="flex items-center gap-2 text-xs font-black text-gray-400 dark:text-slate-400 uppercase tracking-widest mb-2 ml-1">
|
||||
<AlignLeft className="w-3 h-3" /> Mô tả chi tiết
|
||||
</label>
|
||||
<textarea
|
||||
value={editingLegData.description}
|
||||
onChange={(e) => setEditingLegData({ ...editingLegData, description: e.target.value })}
|
||||
placeholder="Mô tả các hoạt động chính trong chặng này..."
|
||||
className="w-full px-5 py-4 bg-gray-50 dark:bg-slate-800 border border-gray-100 dark:border-slate-700 rounded-2xl focus:ring-2 focus:ring-blue-500 outline-none transition-all text-sm min-h-[120px] resize-none text-gray-800 dark:text-white"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label className="flex items-center gap-2 text-xs font-black text-gray-400 dark:text-slate-400 uppercase tracking-widest mb-2 ml-1">
|
||||
<CalendarIcon className="w-3 h-3" /> Bắt đầu
|
||||
</label>
|
||||
<input
|
||||
type="date"
|
||||
value={editingLegData.startDate}
|
||||
onChange={(e) => setEditingLegData({ ...editingLegData, startDate: e.target.value })}
|
||||
className="w-full px-5 py-4 bg-gray-50 dark:bg-slate-800 border border-gray-100 dark:border-slate-700 rounded-2xl focus:ring-2 focus:ring-blue-500 outline-none transition-all text-sm text-gray-800 dark:text-white"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-xs font-black text-gray-400 dark:text-slate-400 uppercase tracking-widest mb-2 ml-1">Kết thúc</label>
|
||||
<input
|
||||
type="date"
|
||||
value={editingLegData.endDate}
|
||||
onChange={(e) => setEditingLegData({ ...editingLegData, endDate: e.target.value })}
|
||||
className="w-full px-5 py-4 bg-gray-50 dark:bg-slate-800 border border-gray-100 dark:border-slate-700 rounded-2xl focus:ring-2 focus:ring-blue-500 outline-none transition-all text-sm text-gray-800 dark:text-white"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label className="flex items-center gap-2 text-xs font-black text-gray-400 dark:text-slate-400 uppercase tracking-widest mb-2 ml-1">
|
||||
<CalendarIcon className="w-3 h-3" /> Bắt đầu
|
||||
</label>
|
||||
<input
|
||||
type="date"
|
||||
value={editingLegData.startDate}
|
||||
onChange={(e) => setEditingLegData({ ...editingLegData, startDate: e.target.value })}
|
||||
className="w-full px-5 py-4 bg-gray-50 dark:bg-slate-800 border border-gray-100 dark:border-slate-700 rounded-2xl focus:ring-2 focus:ring-blue-500 outline-none transition-all text-sm text-gray-800 dark:text-white"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-xs font-black text-gray-400 dark:text-slate-400 uppercase tracking-widest mb-2 ml-1">Kết thúc</label>
|
||||
<input
|
||||
type="date"
|
||||
value={editingLegData.endDate}
|
||||
onChange={(e) => setEditingLegData({ ...editingLegData, endDate: e.target.value })}
|
||||
className="w-full px-5 py-4 bg-gray-50 dark:bg-slate-800 border border-gray-100 dark:border-slate-700 rounded-2xl focus:ring-2 focus:ring-blue-500 outline-none transition-all text-sm text-gray-800 dark:text-white"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-3 mt-8">
|
||||
<button
|
||||
onClick={() => setIsEditModalOpen(false)}
|
||||
className="py-4 bg-gray-100 dark:bg-slate-800 hover:bg-gray-200 dark:hover:bg-slate-700 text-gray-600 dark:text-slate-300 font-bold rounded-2xl transition-all active:scale-95"
|
||||
>
|
||||
Hủy
|
||||
</button>
|
||||
<button
|
||||
onClick={saveLegEdit}
|
||||
className="py-4 bg-blue-600 dark:bg-blue-700 hover:bg-blue-700 dark:hover:bg-blue-800 text-white font-bold rounded-2xl shadow-lg shadow-blue-100 dark:shadow-blue-950 transition-all active:scale-95"
|
||||
>
|
||||
Lưu thay đổi
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="grid grid-cols-2 gap-3 mt-8 shrink-0">
|
||||
<button
|
||||
onClick={() => setIsEditModalOpen(false)}
|
||||
className="py-4 bg-gray-100 dark:bg-slate-800 hover:bg-gray-200 dark:hover:bg-slate-700 text-gray-600 dark:text-slate-300 font-bold rounded-2xl transition-all active:scale-95"
|
||||
>
|
||||
Hủy
|
||||
</button>
|
||||
<button
|
||||
onClick={saveLegEdit}
|
||||
className="py-4 bg-blue-600 dark:bg-blue-700 hover:bg-blue-700 dark:hover:bg-blue-800 text-white font-bold rounded-2xl shadow-lg shadow-blue-100 dark:shadow-blue-950 transition-all active:scale-95"
|
||||
>
|
||||
Lưu thay đổi
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<CommentModal
|
||||
isOpen={isCommentModalOpen}
|
||||
onClose={() => setIsCommentModalOpen(false)}
|
||||
|
||||
@@ -208,10 +208,10 @@ export const JoinTourLoginModal: React.FC<JoinTourLoginModalProps> = ({
|
||||
if (!isOpen) return null;
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-[3000] flex items-center justify-center p-4 bg-black/50">
|
||||
<div className="w-full max-w-md bg-[var(--surface)] rounded-[32px] shadow-2xl overflow-hidden animate-in zoom-in-95 duration-200">
|
||||
<div className="fixed inset-0 z-[3000] flex items-end sm:items-center justify-center p-0 sm:p-4 bg-black/50">
|
||||
<div className="w-full h-full sm:w-auto sm:max-w-md sm:h-auto sm:max-h-[85vh] bg-[var(--surface)] rounded-t-2xl sm:rounded-[32px] shadow-2xl overflow-hidden animate-in zoom-in-95 duration-200 flex flex-col">
|
||||
{/* Header */}
|
||||
<div className="relative h-32 bg-gradient-to-r from-blue-500 via-purple-500 to-pink-500 overflow-hidden">
|
||||
<div className="relative h-32 bg-gradient-to-r from-blue-500 via-purple-500 to-pink-500 overflow-hidden shrink-0">
|
||||
<div className="absolute inset-0 opacity-10">
|
||||
<div className="absolute inset-0 bg-[radial-gradient(circle_at_20%_50%,rgba(255,255,255,.3)_0%,transparent_50%)]" />
|
||||
</div>
|
||||
@@ -227,11 +227,11 @@ export const JoinTourLoginModal: React.FC<JoinTourLoginModalProps> = ({
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="p-8">
|
||||
<h2 className="text-3xl font-bold text-[var(--text-primary)] mb-2 text-center">
|
||||
<div className="flex-1 overflow-y-auto p-5 sm:p-8">
|
||||
<h2 className="text-2xl sm:text-3xl font-bold text-[var(--text-primary)] mb-2 text-center">
|
||||
Gia nhập tour
|
||||
</h2>
|
||||
<p className="text-center text-[var(--text-secondary)] mb-6">
|
||||
<p className="text-center text-[var(--text-secondary)] mb-4 sm:mb-6">
|
||||
Đăng nhập để tham gia chuyến du lịch này
|
||||
</p>
|
||||
|
||||
@@ -242,11 +242,11 @@ export const JoinTourLoginModal: React.FC<JoinTourLoginModalProps> = ({
|
||||
)}
|
||||
|
||||
{/* Google OAuth Button */}
|
||||
<div className="mb-6 flex justify-center">
|
||||
<div className="mb-4 sm:mb-6 flex justify-center">
|
||||
<div id="google-signin-btn-join-tour" className="w-full" />
|
||||
</div>
|
||||
|
||||
<div className="relative mb-6">
|
||||
<div className="relative mb-4 sm:mb-6">
|
||||
<div className="absolute inset-0 flex items-center">
|
||||
<div className="w-full border-t border-[var(--border)]" />
|
||||
</div>
|
||||
@@ -311,7 +311,7 @@ export const JoinTourLoginModal: React.FC<JoinTourLoginModalProps> = ({
|
||||
</form>
|
||||
|
||||
{/* Signup Link */}
|
||||
<div className="mt-6 text-center text-sm text-[var(--text-secondary)]">
|
||||
<div className="mt-4 sm:mt-6 text-center text-sm text-[var(--text-secondary)]">
|
||||
Chưa có tài khoản?{' '}
|
||||
<button
|
||||
onClick={() => {
|
||||
|
||||
@@ -114,12 +114,12 @@ export const LocationNavigationModal: React.FC<NavModalProps> = ({ isOpen, onClo
|
||||
: [0, 0];
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm p-4">
|
||||
<div className="bg-slate-900 border border-slate-700 w-full max-w-4xl h-[80vh] rounded-2xl overflow-hidden flex flex-col shadow-2xl">
|
||||
<div className="fixed inset-0 z-50 flex items-end sm:items-center justify-center bg-black/60 backdrop-blur-sm p-0 sm:p-4">
|
||||
<div className="bg-slate-900 border border-slate-700 w-full h-full sm:w-auto sm:max-w-4xl sm:h-[85vh] rounded-t-2xl sm:rounded-2xl overflow-hidden flex flex-col shadow-2xl animate-in zoom-in-95 duration-200">
|
||||
{/* Modal Header */}
|
||||
<div className="p-4 bg-slate-800 border-b border-slate-700 flex items-center justify-between">
|
||||
<div className="p-4 bg-slate-800 border-b border-slate-700 flex items-center justify-between shrink-0">
|
||||
<div>
|
||||
<h3 className="text-md font-bold text-white flex items-center gap-2">
|
||||
<h3 className="text-md sm:text-lg font-bold text-white flex items-center gap-2">
|
||||
📍 Chỉ đường đến: <span className="text-blue-400">{routeData.destination?.name}</span>
|
||||
</h3>
|
||||
<p className="text-xs text-gray-400 mt-0.5">Tuyến đường ngắn nhất từ vị trí hiện tại của bạn</p>
|
||||
|
||||
@@ -164,7 +164,7 @@ export const LoginModal: React.FC<LoginModalProps> = ({ isOpen, onClose, onSwitc
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 sm:p-6">
|
||||
<div className="fixed inset-0 z-50 flex items-end sm:items-center justify-center p-0 sm:p-4">
|
||||
{/* Backdrop */}
|
||||
<div
|
||||
className="absolute inset-0 bg-gray-900/60 backdrop-blur-sm animate-in fade-in duration-300"
|
||||
@@ -172,8 +172,8 @@ export const LoginModal: React.FC<LoginModalProps> = ({ isOpen, onClose, onSwitc
|
||||
/>
|
||||
|
||||
{/* Modal Content */}
|
||||
<div className="relative w-full max-w-md bg-[var(--surface)] rounded-3xl shadow-2xl overflow-hidden max-h-[90vh] overflow-y-auto animate-in zoom-in-95 duration-300">
|
||||
<div className="p-8 sm:p-10">
|
||||
<div className="relative w-full sm:max-w-md bg-[var(--surface)] rounded-t-2xl sm:rounded-3xl shadow-2xl overflow-hidden sm:max-h-[85vh] flex flex-col h-full animate-in zoom-in-95 duration-300">
|
||||
<div className="p-8 sm:p-10 flex-1 overflow-y-auto">
|
||||
<div className="flex justify-between items-start mb-8">
|
||||
<div>
|
||||
<h2 className="text-3xl font-bold text-[var(--text-primary)]">Đăng nhập</h2>
|
||||
|
||||
@@ -439,16 +439,16 @@ export const MembersTab: React.FC<MembersTabProps> = ({
|
||||
|
||||
{/* Manual Merge Modal Selector */}
|
||||
{assigningManualMember && (
|
||||
<div className="fixed inset-0 z-[2000] flex items-center justify-center p-4">
|
||||
<div className="fixed inset-0 z-[2000] flex items-end sm:items-center justify-center p-0 sm:p-4">
|
||||
<div className="absolute inset-0 bg-gray-900/60 backdrop-blur-sm" onClick={() => setAssigningManualMember(null)} />
|
||||
<div className="relative w-full max-w-md bg-white rounded-3xl shadow-2xl overflow-hidden flex flex-col max-h-[80vh] animate-in zoom-in-95 duration-200">
|
||||
<div className="p-5 border-b border-gray-100 flex justify-between items-center bg-gray-50/50">
|
||||
<div className="relative w-full sm:max-w-md bg-white rounded-t-2xl sm:rounded-3xl shadow-2xl overflow-hidden flex flex-col h-full sm:h-auto sm:max-h-[85vh] animate-in zoom-in-95 duration-200">
|
||||
<div className="p-5 border-b border-gray-100 flex justify-between items-center bg-gray-50/50 shrink-0">
|
||||
<div>
|
||||
<h3 className="text-md font-bold text-gray-900 flex items-center gap-2">
|
||||
<GitMerge className="w-5 h-5 text-indigo-600" /> Gán tài khoản hệ thống
|
||||
</h3>
|
||||
<p className="text-xs text-gray-500 mt-1">
|
||||
Chọn một tài khoản hệ thống để gán cho thành viên thủ công <strong>"{assigningManualMember.displayName}"</strong>.
|
||||
Chọn một tài khoản hệ thống để gán cho thành viên thủ cộ<strong>"{assigningManualMember.displayName}"</strong>.
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
|
||||
@@ -34,24 +34,24 @@ export const NotificationModal: React.FC<NotificationModalProps> = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-[3000] flex items-center justify-center p-4">
|
||||
<div className="fixed inset-0 z-[3000] flex items-end sm:items-center justify-center p-0 sm:p-4">
|
||||
{/* Backdrop */}
|
||||
<div className="absolute inset-0 bg-gray-900/60 backdrop-blur-sm animate-in fade-in duration-200" onClick={onConfirm} />
|
||||
|
||||
{/* Modal Content */}
|
||||
<div className="relative w-full max-w-sm bg-[var(--surface)] rounded-[32px] shadow-2xl overflow-hidden p-8 text-center animate-in zoom-in-95 duration-200">
|
||||
<div className="flex justify-center mb-5">
|
||||
<div className="relative w-full sm:max-w-sm bg-[var(--surface)] rounded-t-2xl sm:rounded-[32px] shadow-2xl overflow-hidden p-8 sm:p-8 h-full sm:h-auto sm:max-h-[85vh] flex flex-col animate-in zoom-in-95 duration-200">
|
||||
<div className="flex justify-center mb-5 shrink-0">
|
||||
{icons[type]}
|
||||
</div>
|
||||
|
||||
<h2 className="text-xl font-black text-[var(--text-primary)] mb-2">{title}</h2>
|
||||
<p className="text-[var(--text-muted)] text-sm leading-relaxed mb-8">
|
||||
<p className="text-[var(--text-muted)] text-sm leading-relaxed mb-8 flex-1">
|
||||
{message || "Bạn không được phép gỡ bỏ thành viên này!"}
|
||||
</p>
|
||||
|
||||
<button
|
||||
onClick={onConfirm}
|
||||
className={`w-full py-4 text-white font-bold rounded-2xl transition-all shadow-lg active:scale-95 ${colors[type]}`}
|
||||
className={`w-full py-4 text-white font-bold rounded-2xl transition-all shadow-lg active:scale-95 mt-auto ${colors[type]}`}
|
||||
>
|
||||
Đã hiểu
|
||||
</button>
|
||||
|
||||
@@ -819,7 +819,7 @@ export const PublicPhotoModal: React.FC<PublicPhotoModalProps> = ({
|
||||
|
||||
{isFullscreen && (
|
||||
<div
|
||||
className="fixed inset-0 z-[9999] bg-black/95 flex items-center justify-center cursor-zoom-out animate-in fade-in duration-200"
|
||||
className="fixed inset-0 z-[9999] bg-black/95 flex items-end sm:items-center justify-center cursor-zoom-out animate-in fade-in duration-200"
|
||||
onClick={() => setIsFullscreen(false)}
|
||||
>
|
||||
<button
|
||||
@@ -833,7 +833,7 @@ export const PublicPhotoModal: React.FC<PublicPhotoModalProps> = ({
|
||||
alt="Fullscreen photo"
|
||||
onContextMenu={(e) => { if (!isLoggedIn) e.preventDefault(); }}
|
||||
onDragStart={(e) => { if (!isLoggedIn) e.preventDefault(); }}
|
||||
className={`max-w-full max-h-full object-contain select-none animate-in zoom-in-95 duration-200 ${
|
||||
className={`max-w-full max-h-full sm:max-w-screen-md object-contain select-none animate-in zoom-in-95 duration-200 ${
|
||||
!isLoggedIn ? 'pointer-events-none' : ''
|
||||
}`}
|
||||
/>
|
||||
|
||||
@@ -100,19 +100,14 @@ export const ReportBusinessModal: React.FC<ReportBusinessModalProps> = ({
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-[3000] flex items-center justify-center p-4">
|
||||
{/* Backdrop */}
|
||||
<div
|
||||
className="absolute inset-0 bg-gray-900/60 backdrop-blur-sm animate-in fade-in duration-300"
|
||||
onClick={onClose}
|
||||
/>
|
||||
return (
|
||||
<div className="fixed inset-0 z-[3000] flex items-end sm:items-center justify-center p-0 sm:p-4 bg-black/50">
|
||||
|
||||
{/* Content Container */}
|
||||
<div className="relative w-full max-w-lg bg-white rounded-3xl shadow-2xl overflow-hidden animate-in zoom-in-95 duration-300 flex flex-col max-h-[90vh]">
|
||||
|
||||
<div className="relative w-full h-full sm:max-w-lg bg-white rounded-t-2xl sm:rounded-3xl shadow-2xl overflow-hidden animate-in zoom-in-95 duration-300 flex flex-col sm:max-h-[85vh]">
|
||||
|
||||
{/* Header */}
|
||||
<div className="p-6 border-b border-gray-100 flex justify-between items-center bg-gray-50/50">
|
||||
<div className="p-6 border-b border-gray-100 flex justify-between items-center bg-gray-50/50 shrink-0">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="p-2 bg-red-50 text-red-500 rounded-xl">
|
||||
<ShieldAlert className="w-6 h-6" />
|
||||
@@ -131,7 +126,7 @@ export const ReportBusinessModal: React.FC<ReportBusinessModalProps> = ({
|
||||
</div>
|
||||
|
||||
{success ? (
|
||||
<div className="p-10 flex flex-col items-center justify-center text-center space-y-4">
|
||||
<div className="p-10 flex flex-col items-center justify-center text-center space-y-4 flex-1">
|
||||
<div className="w-16 h-16 bg-emerald-100 text-emerald-600 rounded-full flex items-center justify-center shadow-lg animate-bounce">
|
||||
<ShieldAlert className="w-8 h-8" />
|
||||
</div>
|
||||
@@ -147,7 +142,6 @@ export const ReportBusinessModal: React.FC<ReportBusinessModalProps> = ({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Loại hình */}
|
||||
<div className="space-y-1.5">
|
||||
<label className="text-xs font-bold text-gray-500 uppercase tracking-wider">{t('businessType')} *</label>
|
||||
<select
|
||||
@@ -162,7 +156,6 @@ export const ReportBusinessModal: React.FC<ReportBusinessModalProps> = ({
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Tên */}
|
||||
<div className="space-y-1.5">
|
||||
<label className="text-xs font-bold text-gray-500 uppercase tracking-wider">{t('businessName')} *</label>
|
||||
<input
|
||||
@@ -176,7 +169,6 @@ export const ReportBusinessModal: React.FC<ReportBusinessModalProps> = ({
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
{/* Số điện thoại */}
|
||||
<div className="space-y-1.5">
|
||||
<label className="text-xs font-bold text-gray-500 uppercase tracking-wider flex items-center gap-1">
|
||||
<Phone className="w-3.5 h-3.5 text-gray-400" /> {t('businessPhone')}
|
||||
@@ -190,7 +182,6 @@ export const ReportBusinessModal: React.FC<ReportBusinessModalProps> = ({
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Email */}
|
||||
<div className="space-y-1.5">
|
||||
<label className="text-xs font-bold text-gray-500 uppercase tracking-wider flex items-center gap-1">
|
||||
<Mail className="w-3.5 h-3.5 text-gray-400" /> {t('businessEmail')}
|
||||
@@ -205,7 +196,6 @@ export const ReportBusinessModal: React.FC<ReportBusinessModalProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Địa chỉ */}
|
||||
<div className="space-y-1.5">
|
||||
<label className="text-xs font-bold text-gray-500 uppercase tracking-wider flex items-center gap-1">
|
||||
<MapPin className="w-3.5 h-3.5 text-gray-400" /> {t('businessAddress')}
|
||||
@@ -214,12 +204,11 @@ export const ReportBusinessModal: React.FC<ReportBusinessModalProps> = ({
|
||||
type="text"
|
||||
value={address}
|
||||
onChange={(e) => setAddress(e.target.value)}
|
||||
placeholder="VD: 123 Đường Trần Phú, Đà Lạt..."
|
||||
placeholder="VD: 123 Đường Trần Phú, Đà Nẵng..."
|
||||
className="w-full px-4 py-3 bg-gray-50 border border-gray-100 rounded-2xl focus:ring-2 focus:ring-blue-500 focus:bg-white outline-none transition-all text-sm text-gray-800"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Tọa độ địa lý */}
|
||||
<div className="space-y-1.5 bg-blue-50/50 p-4 rounded-2xl border border-blue-100">
|
||||
<div className="flex justify-between items-center mb-2">
|
||||
<span className="text-xs font-bold text-blue-700 uppercase tracking-wider flex items-center gap-1.5">
|
||||
@@ -259,7 +248,6 @@ export const ReportBusinessModal: React.FC<ReportBusinessModalProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Lý do */}
|
||||
<div className="space-y-1.5">
|
||||
<label className="text-xs font-bold text-gray-500 uppercase tracking-wider">{t('reportReason')} *</label>
|
||||
<textarea
|
||||
|
||||
@@ -66,16 +66,16 @@ export const TagSelectModal: React.FC<TagSelectModalProps> = ({ isOpen, onClose,
|
||||
|
||||
if (!isOpen) return null;
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-[6000] flex items-center justify-center p-4">
|
||||
return (
|
||||
<div className="fixed inset-0 z-[6000] flex items-end sm:items-center justify-center p-0 sm:p-4">
|
||||
<div
|
||||
className="absolute inset-0 bg-slate-950/80 backdrop-blur-md"
|
||||
onClick={handleClose}
|
||||
/>
|
||||
|
||||
<div className="relative bg-white dark:bg-slate-900 rounded-3xl shadow-2xl max-w-md w-full max-h-[90vh] overflow-y-auto animate-in zoom-in-95 duration-300">
|
||||
<div className="relative bg-white dark:bg-slate-900 w-full h-full sm:w-auto sm:max-w-md sm:h-auto sm:max-h-[85vh] rounded-t-2xl sm:rounded-3xl shadow-2xl flex flex-col overflow-hidden animate-in zoom-in-95 duration-300">
|
||||
{/* Header */}
|
||||
<div className="sticky top-0 bg-white dark:bg-slate-900 border-b border-gray-200 dark:border-slate-700 px-6 py-5 flex justify-between items-center">
|
||||
<div className="sticky top-0 bg-white dark:bg-slate-900 border-b border-gray-200 dark:border-slate-700 px-6 py-5 flex justify-between items-center shrink-0">
|
||||
<h2 className="text-xl font-bold text-gray-900 dark:text-white">
|
||||
🏷️ Lựa chọn thẻ
|
||||
</h2>
|
||||
@@ -87,8 +87,8 @@ export const TagSelectModal: React.FC<TagSelectModalProps> = ({ isOpen, onClose,
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="p-6 space-y-6">
|
||||
{/* Content */}
|
||||
<div className="p-6 space-y-6 overflow-y-auto flex-1">
|
||||
{/* Image Preview */}
|
||||
{photoUrl && (
|
||||
<div className="flex justify-center">
|
||||
@@ -201,7 +201,7 @@ export const TagSelectModal: React.FC<TagSelectModalProps> = ({ isOpen, onClose,
|
||||
</div>
|
||||
|
||||
{/* Footer */}
|
||||
<div className="sticky bottom-0 bg-white dark:bg-slate-900 border-t border-gray-200 dark:border-slate-700 px-6 py-4 flex gap-3">
|
||||
<div className="sticky bottom-0 bg-white dark:bg-slate-900 border-t border-gray-200 dark:border-slate-700 px-6 py-4 flex gap-3 shrink-0">
|
||||
<button
|
||||
onClick={handleClose}
|
||||
className="flex-1 px-4 py-3 rounded-xl border-2 border-gray-200 dark:border-slate-700 text-gray-900 dark:text-white font-bold hover:bg-gray-100 dark:hover:bg-slate-800 transition-colors"
|
||||
|
||||
@@ -797,13 +797,13 @@ export const UserManagementModal: React.FC<UserManagementModalProps> = ({ isOpen
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-[2000] flex items-center justify-center p-4">
|
||||
return (
|
||||
<div className="fixed inset-0 z-[2000] flex items-end sm:items-center justify-center p-0 sm:p-4">
|
||||
<div className="absolute inset-0 bg-gray-900/60 backdrop-blur-sm" onClick={onClose} />
|
||||
<div className="relative w-full max-w-5xl bg-white rounded-3xl shadow-2xl overflow-hidden flex flex-col h-[85vh]">
|
||||
|
||||
<div className="relative w-full sm:max-w-5xl bg-white rounded-t-2xl sm:rounded-3xl shadow-2xl overflow-hidden flex flex-col h-full sm:h-auto sm:max-h-[85vh] animate-in zoom-in-95 duration-200">
|
||||
|
||||
{/* Header */}
|
||||
<div className="p-6 border-b border-gray-100 flex justify-between items-center bg-gray-50/50">
|
||||
<div className="p-6 sm:p-6 border-b border-gray-100 flex justify-between items-center bg-gray-50/50 shrink-0">
|
||||
<div>
|
||||
<h2 className="text-2xl font-bold text-gray-900 flex items-center gap-2">
|
||||
<Shield className="w-6 h-6 text-blue-600" /> Hệ thống quản trị
|
||||
|
||||
Reference in New Issue
Block a user