feat: optimize KYC action buttons for mobile layout and add approval modal support

This commit is contained in:
sazzadulalambd
2026-05-06 18:03:53 +06:00
parent 502e576fc1
commit 016f12ae83
2 changed files with 91 additions and 65 deletions

View File

@@ -3,10 +3,9 @@ import withPWAInit from "@ducanh2912/next-pwa";
const withPWA = withPWAInit({ const withPWA = withPWAInit({
dest: "public", dest: "public",
disable: false, // Explicitly enabling PWA even in development mode per user request disable: false,
register: true, register: true,
skipWaiting: true, } as any);
});
const nextConfig: NextConfig = { const nextConfig: NextConfig = {
images: { images: {
@@ -18,6 +17,7 @@ const nextConfig: NextConfig = {
}, },
], ],
}, },
turbopack: {},
}; };
export default withPWA(nextConfig); export default withPWA(nextConfig);

View File

@@ -254,6 +254,7 @@ export default function KYCDetailPage() {
const [editForm, setEditForm] = useState<Partial<Request>>({}); const [editForm, setEditForm] = useState<Partial<Request>>({});
const [showMessageModal, setShowMessageModal] = useState(false); const [showMessageModal, setShowMessageModal] = useState(false);
const [showAddNoteModal, setShowAddNoteModal] = useState(false); const [showAddNoteModal, setShowAddNoteModal] = useState(false);
const [showApproveModal, setShowApproveModal] = useState(false);
const [newNoteText, setNewNoteText] = useState(''); const [newNoteText, setNewNoteText] = useState('');
const [newMessageText, setNewMessageText] = useState(''); const [newMessageText, setNewMessageText] = useState('');
const [showAddDocModal, setShowAddDocModal] = useState(false); const [showAddDocModal, setShowAddDocModal] = useState(false);
@@ -409,82 +410,86 @@ export default function KYCDetailPage() {
</div> </div>
<p className="text-slate-500 mt-1">{request.name} {request.submittedAt}</p> <p className="text-slate-500 mt-1">{request.name} {request.submittedAt}</p>
</div> </div>
<div className="flex gap-2">
<div className="flex flex-col sm:flex-row sm:flex-wrap gap-2">
{editMode ? ( {editMode ? (
<> <>
<button onClick={handleSaveEdit} className="px-4 py-2 bg-green-600 text-white rounded-lg text-sm hover:bg-green-700 flex items-center gap-2"> <button onClick={handleSaveEdit} className="flex-1 sm:flex-none px-3 sm:px-4 py-2 bg-green-600 text-white rounded-lg text-sm hover:bg-green-700 flex items-center justify-center gap-2">
<Save className="w-4 h-4" /> Save <Save className="w-4 h-4" /> <span>Save</span>
</button> </button>
<button onClick={() => { setEditForm(request); setEditMode(false); }} className="px-4 py-2 border border-slate-200 text-slate-600 rounded-lg text-sm hover:bg-slate-50"> <button onClick={() => { setEditForm(request); setEditMode(false); }} className="flex-1 sm:flex-none px-3 sm:px-4 py-2 border border-slate-200 text-slate-600 rounded-lg text-sm hover:bg-slate-50">
Cancel Cancel
</button> </button>
</> </>
) : ( ) : (
<> <>
{request.type === 'biker' && request.status !== 'approved' && ( {/* Top Row on Mobile: Make [Type] Button */}
<button <div className="flex gap-2 w-full sm:w-auto">
onClick={() => { {request.type === 'biker' && request.status !== 'approved' && (
if (confirm('Approve this request and create biker profile?')) { <button
setRequest(prev => prev ? { ...prev, status: 'approved', verificationStage: 'active' } : null); onClick={() => setShowApproveModal(true)}
alert('Biker created successfully!'); className="flex-1 sm:flex-none px-3 sm:px-4 py-2 bg-blue-600 text-white rounded-lg text-sm hover:bg-blue-700 flex items-center justify-center gap-2"
} >
}} <Bike className="w-4 h-4" /> <span>Make Biker</span>
className="px-4 py-2 bg-blue-600 text-white rounded-lg text-sm hover:bg-blue-700 flex items-center gap-2" </button>
> )}
<Bike className="w-4 h-4" /> Make Biker {request.type === 'investor' && request.status !== 'approved' && (
<button
onClick={() => {
if (confirm('Approve this request and create investor profile?')) {
setRequest(prev => prev ? { ...prev, status: 'approved' } : null);
alert('Investor created successfully!');
}
}}
className="flex-1 sm:flex-none px-3 sm:px-4 py-2 bg-purple-600 text-white rounded-lg text-sm hover:bg-purple-700 flex items-center justify-center gap-2"
>
<DollarSign className="w-4 h-4" /> <span>Make Investor</span>
</button>
)}
{request.type === 'swapstation' && request.status !== 'approved' && (
<button
onClick={() => {
if (confirm('Approve this request and create shop profile?')) {
setRequest(prev => prev ? { ...prev, status: 'approved' } : null);
alert('Shop created successfully!');
}
}}
className="flex-1 sm:flex-none px-3 sm:px-4 py-2 bg-green-600 text-white rounded-lg text-sm hover:bg-green-700 flex items-center justify-center gap-2"
>
<Store className="w-4 h-4" /> <span>Make Shop</span>
</button>
)}
{request.type === 'merchant' && request.status !== 'approved' && (
<button
onClick={() => {
if (confirm('Approve this request and create merchant profile?')) {
setRequest(prev => prev ? { ...prev, status: 'approved' } : null);
alert('Merchant created successfully!');
}
}}
className="flex-1 sm:flex-none px-3 sm:px-4 py-2 bg-orange-600 text-white rounded-lg text-sm hover:bg-orange-700 flex items-center justify-center gap-2"
>
<User className="w-4 h-4" /> <span>Make Merchant</span>
</button>
)}
</div>
{/* Bottom Row on Mobile: Edit, Note, SMS */}
<div className="flex gap-2 w-full sm:w-auto">
<button onClick={() => setEditMode(true)} className="flex-1 sm:flex-none px-3 sm:px-4 py-2 border border-slate-200 text-slate-600 rounded-lg text-sm hover:bg-slate-50 flex items-center justify-center gap-2">
<Edit className="w-4 h-4" /> <span>Edit</span>
</button> </button>
)} <button onClick={() => setShowAddNoteModal(true)} className="flex-1 sm:flex-none px-3 sm:px-4 py-2 border border-slate-200 text-slate-600 rounded-lg text-sm hover:bg-slate-50 flex items-center justify-center gap-2">
{request.type === 'investor' && request.status !== 'approved' && ( <MessageSquare className="w-4 h-4" /> <span>Note</span>
<button
onClick={() => {
if (confirm('Approve this request and create investor profile?')) {
setRequest(prev => prev ? { ...prev, status: 'approved' } : null);
alert('Investor created successfully!');
}
}}
className="px-4 py-2 bg-purple-600 text-white rounded-lg text-sm hover:bg-purple-700 flex items-center gap-2"
>
<DollarSign className="w-4 h-4" /> Make Investor
</button> </button>
)} <button onClick={() => setShowMessageModal(true)} className="flex-1 sm:flex-none px-3 sm:px-4 py-2 bg-accent text-white rounded-lg text-sm hover:bg-accent/90 flex items-center justify-center gap-2">
{request.type === 'swapstation' && request.status !== 'approved' && ( <Send className="w-4 h-4" /> <span>SMS</span>
<button
onClick={() => {
if (confirm('Approve this request and create shop profile?')) {
setRequest(prev => prev ? { ...prev, status: 'approved' } : null);
alert('Shop created successfully!');
}
}}
className="px-4 py-2 bg-green-600 text-white rounded-lg text-sm hover:bg-green-700 flex items-center gap-2"
>
<Store className="w-4 h-4" /> Make Shop
</button> </button>
)} </div>
{request.type === 'merchant' && request.status !== 'approved' && (
<button
onClick={() => {
if (confirm('Approve this request and create merchant profile?')) {
setRequest(prev => prev ? { ...prev, status: 'approved' } : null);
alert('Merchant created successfully!');
}
}}
className="px-4 py-2 bg-orange-600 text-white rounded-lg text-sm hover:bg-orange-700 flex items-center gap-2"
>
<User className="w-4 h-4" /> Make Merchant
</button>
)}
<button onClick={() => setEditMode(true)} className="px-4 py-2 border border-slate-200 text-slate-600 rounded-lg text-sm hover:bg-slate-50 flex items-center gap-2">
<Edit className="w-4 h-4" /> Edit
</button>
<button onClick={() => setShowAddNoteModal(true)} className="px-4 py-2 border border-slate-200 text-slate-600 rounded-lg text-sm hover:bg-slate-50 flex items-center gap-2">
<MessageSquare className="w-4 h-4" /> Note
</button>
<button onClick={() => setShowMessageModal(true)} className="px-4 py-2 bg-accent text-white rounded-lg text-sm hover:bg-accent/90 flex items-center gap-2">
<Send className="w-4 h-4" /> SMS
</button>
</> </>
)} )}
</div> </div>
</div> </div>
</div> </div>
@@ -771,6 +776,27 @@ export default function KYCDetailPage() {
</div> </div>
)} )}
{showApproveModal && (
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
<div className="bg-white rounded-xl shadow-xl w-full max-w-md">
<div className="p-4 border-b border-slate-100 flex justify-between items-center">
<h3 className="font-semibold text-slate-800">Approve Request</h3>
<button onClick={() => setShowApproveModal(false)} className="text-slate-400 hover:text-slate-600">×</button>
</div>
<div className="p-4">
<p className="text-sm text-slate-700 mb-4">Approve this request and create biker profile?</p>
<div className="flex justify-end gap-2">
<button onClick={() => setShowApproveModal(false)} className="px-4 py-2 border border-slate-200 text-slate-600 rounded-lg">Cancel</button>
<button onClick={() => {
setRequest(prev => prev ? { ...prev, status: 'approved', verificationStage: 'active' } : null);
setShowApproveModal(false);
toast.success('Biker created successfully!');
}} className="px-4 py-2 bg-blue-600 text-white rounded-lg">Confirm</button>
</div>
</div>
</div>
</div>
)}
{showAddNoteModal && ( {showAddNoteModal && (
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4"> <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
<div className="bg-white rounded-xl shadow-xl w-full max-w-md"> <div className="bg-white rounded-xl shadow-xl w-full max-w-md">