diff --git a/src/app/admin/settings/page.tsx b/src/app/admin/settings/page.tsx index 26a4bba..923d75c 100644 --- a/src/app/admin/settings/page.tsx +++ b/src/app/admin/settings/page.tsx @@ -350,61 +350,67 @@ const initialSettings: CompanySettings = { { id: 'SC-002', name: 'JAIBEN Service Center - Banani', address: 'Road 11, Banani, Dhaka', phone: '+8801712345671', rating: 4.5 }, ], companyPolicy: { - investor: { - title: 'Investor Policy', - description: '

Investor Guidelines

Welcome to our investor program. This document outlines the terms and conditions for all investors participating in our EV fleet sharing initiative.

Key Requirements

Note: Past performance does not guarantee future results. Please read all terms carefully before investing.

', + investor: { + title: 'Investor Policy', + description: '

Investor Guidelines

Welcome to our investor program. This document outlines the terms and conditions for all investors participating in our EV fleet sharing initiative.

Key Requirements

Note: Past performance does not guarantee future results. Please read all terms carefully before investing.

', rules: [ { name: 'No smoking in vehicles', description: 'Smoking is strictly prohibited inside any vehicle in the fleet' }, { name: 'Return with same fuel/charge level', description: 'Vehicles must be returned with the same fuel/charge level as when rented' }, { name: 'No unauthorized drivers', description: 'Only authorized drivers listed in the agreement are permitted to drive' }, { name: 'Follow traffic rules', description: 'All traffic laws and regulations must be followed' }, { name: 'Report accidents within 24 hours', description: 'Any accident must be reported within 24 hours of occurrence' } - ] + ] }, - merchant: { - title: 'Merchant Policy', - description: '

Merchant Terms & Conditions

Thank you for joining our merchant network. These guidelines ensure smooth operations for all participating merchants.

Operational Requirements

Commission Structure

Merchants receive 15% commission on each completed delivery plus monthly bonuses for high performance.

', + merchant: { + title: 'Merchant Policy', + description: '

Merchant Terms & Conditions

Thank you for joining our merchant network. These guidelines ensure smooth operations for all participating merchants.

Operational Requirements

Commission Structure

Merchants receive 15% commission on each completed delivery plus monthly bonuses for high performance.

', rules: [ { name: 'No smoking in vehicles', description: 'Smoking is strictly prohibited inside any vehicle in the fleet' }, { name: 'Return with same fuel/charge level', description: 'Vehicles must be returned with the same fuel/charge level as when rented' }, { name: 'No unauthorized drivers', description: 'Only authorized drivers listed in the agreement are permitted to drive' }, { name: 'Follow traffic rules', description: 'All traffic laws and regulations must be followed' }, { name: 'Report accidents within 24 hours', description: 'Any accident must be reported within 24 hours of occurrence' } - ] + ] }, - swapStation: { - title: 'Swap Station Policy', - description: '

Swap Station Guidelines

Welcome to our battery swap station network. Follow these safety and operational protocols for optimal service.

Safety Protocols

Operating Hours

Stations operate 24/7 for subscriber convenience. Emergency support available round the clock.

', + swapStation: { + title: 'Swap Station Policy', + description: '

Swap Station Guidelines

Welcome to our battery swap station network. Follow these safety and operational protocols for optimal service.

Safety Protocols

Operating Hours

Stations operate 24/7 for subscriber convenience. Emergency support available round the clock.

', rules: [ { name: 'No smoking in vehicles', description: 'Smoking is strictly prohibited inside any vehicle in the fleet' }, { name: 'Return with same fuel/charge level', description: 'Vehicles must be returned with the same fuel/charge level as when rented' }, { name: 'No unauthorized drivers', description: 'Only authorized drivers listed in the agreement are permitted to drive' }, { name: 'Follow traffic rules', description: 'All traffic laws and regulations must be followed' }, { name: 'Report accidents within 24 hours', description: 'Any accident must be reported within 24 hours of occurrence' } - ] + ] }, rentalTypes: [ - { type: 'single', name: 'Rental (Single)', title: 'Rental (Single)', description: '

Single Person Rental

Perfect for individual riders who need a reliable vehicle for daily commute or delivery work.

Plan Features

Pricing

Starting from ৳400/day with deposit of ৳5,000.

', rules: [ - { name: 'No smoking in vehicles', description: 'Smoking is strictly prohibited inside any vehicle' }, - { name: 'Return with same fuel/charge level', description: 'Vehicles must be returned with the same fuel/charge level' }, - { name: 'No unauthorized drivers', description: 'Only the registered rider is permitted to drive' }, - { name: 'Follow traffic rules', description: 'All traffic laws must be followed' }, - { name: 'Report accidents within 24 hours', description: 'Any accident must be reported within 24 hours' } - ], enabled: true }, - { type: 'shared', name: 'Rental (2 Person Shared)', title: 'Rental (2 Person Shared)', description: '

Shared Rental Plan

Ideal for companions or delivery partners who want to share riding costs and responsibilities.

Plan Features

Pricing

Starting from ৳600/day (৳300 each) with deposit of ৳8,000.

', rules: [ - { name: 'No smoking in vehicles', description: 'Smoking is strictly prohibited inside any vehicle' }, - { name: 'Return with same fuel/charge level', description: 'Vehicles must be returned with the same fuel/charge level' }, - { name: 'No unauthorized drivers', description: 'Both registered riders are permitted to drive' }, - { name: 'Follow traffic rules', description: 'All traffic laws must be followed' }, - { name: 'Report accidents within 24 hours', description: 'Any accident must be reported within 24 hours' } - ], enabled: true }, - { type: 'renttoown', name: 'Rent-to-Own', title: 'Rent-to-Own', description: '

Rent-to-Own Plan

Build ownership gradually with our rent-to-own program. After completing the tenure, own the EV outright.

Program Benefits

Requirements

Good payment history required. Credit check applies.

', rules: [ - { name: 'No smoking in vehicles', description: 'Smoking is strictly prohibited inside any vehicle' }, - { name: 'Return with same fuel/charge level', description: 'Vehicles must be returned with the same fuel/charge level' }, - { name: 'No unauthorized drivers', description: 'Only the registered rider is permitted to drive' }, - { name: 'Follow traffic rules', description: 'All traffic laws must be followed' }, - { name: 'Report accidents within 24 hours', description: 'Any accident must be reported within 24 hours' } - ], enabled: true }, + { + type: 'single', name: 'Rental (Single)', title: 'Rental (Single)', description: '

Single Person Rental

Perfect for individual riders who need a reliable vehicle for daily commute or delivery work.

Plan Features

Pricing

Starting from ৳400/day with deposit of ৳5,000.

', rules: [ + { name: 'No smoking in vehicles', description: 'Smoking is strictly prohibited inside any vehicle' }, + { name: 'Return with same fuel/charge level', description: 'Vehicles must be returned with the same fuel/charge level' }, + { name: 'No unauthorized drivers', description: 'Only the registered rider is permitted to drive' }, + { name: 'Follow traffic rules', description: 'All traffic laws must be followed' }, + { name: 'Report accidents within 24 hours', description: 'Any accident must be reported within 24 hours' } + ], enabled: true + }, + { + type: 'shared', name: 'Rental (2 Person Shared)', title: 'Rental (2 Person Shared)', description: '

Shared Rental Plan

Ideal for companions or delivery partners who want to share riding costs and responsibilities.

Plan Features

Pricing

Starting from ৳600/day (৳300 each) with deposit of ৳8,000.

', rules: [ + { name: 'No smoking in vehicles', description: 'Smoking is strictly prohibited inside any vehicle' }, + { name: 'Return with same fuel/charge level', description: 'Vehicles must be returned with the same fuel/charge level' }, + { name: 'No unauthorized drivers', description: 'Both registered riders are permitted to drive' }, + { name: 'Follow traffic rules', description: 'All traffic laws must be followed' }, + { name: 'Report accidents within 24 hours', description: 'Any accident must be reported within 24 hours' } + ], enabled: true + }, + { + type: 'renttoown', name: 'Rent-to-Own', title: 'Rent-to-Own', description: '

Rent-to-Own Plan

Build ownership gradually with our rent-to-own program. After completing the tenure, own the EV outright.

Program Benefits

Requirements

Good payment history required. Credit check applies.

', rules: [ + { name: 'No smoking in vehicles', description: 'Smoking is strictly prohibited inside any vehicle' }, + { name: 'Return with same fuel/charge level', description: 'Vehicles must be returned with the same fuel/charge level' }, + { name: 'No unauthorized drivers', description: 'Only the registered rider is permitted to drive' }, + { name: 'Follow traffic rules', description: 'All traffic laws must be followed' }, + { name: 'Report accidents within 24 hours', description: 'Any accident must be reported within 24 hours' } + ], enabled: true + }, ], }, rentalPolicy: { @@ -676,7 +682,7 @@ export default function CompanySettingsPage() { const [newDocName, setNewDocName] = useState(''); const [newDocDesc, setNewDocDesc] = useState(''); const [activeInvestTab, setActiveInvestTab] = useState(0); - const [editingPolicy, setEditingPolicy] = useState<{tab: string; index: number} | null>(null); + const [editingPolicy, setEditingPolicy] = useState<{ tab: string; index: number } | null>(null); const [editPolicyName, setEditPolicyName] = useState(''); const [editPolicyDesc, setEditPolicyDesc] = useState(''); const [editPolicyDescHtml, setEditPolicyDescHtml] = useState(''); @@ -760,7 +766,7 @@ export default function CompanySettingsPage() { setSettings({ ...settings, plans: { ...settings.plans, swapStation: updatedPlans } }); setActiveSwapTab(updatedPlans.length - 1); setAddSwapStationPlan(false); -setNewSwapName(''); + setNewSwapName(''); } }; const [activeRiderTab, setActiveRiderTab] = useState(0); @@ -1869,7 +1875,7 @@ setNewSwapName('');

Company's Policy

-
+
@@ -1878,294 +1884,251 @@ setNewSwapName(''); {activeMasterTab === 'investor' && (
-
- - setSettings({ ...settings, companyPolicy: { ...settings.companyPolicy, investor: { title: e.target.value, description: settings.companyPolicy?.investor?.description || '', rules: settings.companyPolicy?.investor?.rules || [] } } })} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm mt-1" /> + +
+ +
-
- - setSettings({ ...settings, companyPolicy: { ...settings.companyPolicy, investor: { title: settings.companyPolicy?.investor?.title || '', description: val, rules: settings.companyPolicy?.investor?.rules || [] } } })} placeholder="Enter policy description..." minHeight={160} /> -
-
- -
-
-
- - -
-
- {(settings.companyPolicy?.investor?.rules || []).map((policy, i) => ( -
- {editingPolicy?.tab === 'investor' && editingPolicy?.index === i ? ( -
- setEditPolicyName(e.target.value)} className="w-full px-2 py-1.5 border border-slate-200 rounded text-sm" placeholder="Policy Name" /> - setEditPolicyDescHtml(val)} placeholder="Policy Description..." minHeight={100} /> -
- - -
+
+ {(settings.companyPolicy?.investor?.rules || []).map((policy, i) => ( +
+ {editingPolicy?.tab === 'investor' && editingPolicy?.index === i ? ( +
+ setEditPolicyName(e.target.value)} className="w-full px-2 py-1.5 border border-slate-200 rounded text-sm" placeholder="Policy Name" /> + setEditPolicyDescHtml(val)} placeholder="Policy Description..." minHeight={100} /> +
+ +
- ) : ( -
-
-
- {policy.name} -
-

{policy.description}

-
-
- - +
+ ) : ( +
+
+
+ {policy.name}
+

{policy.description}

- )} -
- ))} -
- {showAddPolicy && ( -
- setNewPolicyName(e.target.value)} className="w-full px-2 py-1.5 border border-slate-200 rounded text-sm mb-2" placeholder="Policy Name" /> - setNewPolicyDesc(val)} placeholder="Policy Description..." minHeight={100} /> -
- - -
+
+ + +
+
+ )}
- )} + ))}
+ {showAddPolicy && ( +
+ setNewPolicyName(e.target.value)} className="w-full px-2 py-1.5 border border-slate-200 rounded text-sm mb-2" placeholder="Policy Name" /> + setNewPolicyDesc(val)} placeholder="Policy Description..." minHeight={100} /> +
+ + +
+
+ )} +
)} {activeMasterTab === 'merchant' && (
-
- - setSettings({ ...settings, companyPolicy: { ...settings.companyPolicy, merchant: { title: e.target.value, description: settings.companyPolicy?.merchant?.description || '', rules: settings.companyPolicy?.merchant?.rules || [] } } })} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm mt-1" /> + +
+ +
-
- - setSettings({ ...settings, companyPolicy: { ...settings.companyPolicy, merchant: { title: settings.companyPolicy?.merchant?.title || '', description: val, rules: settings.companyPolicy?.merchant?.rules || [] } } })} placeholder="Enter policy description..." minHeight={160} /> -
-
- -
-
-
- - -
-
- {(settings.companyPolicy?.merchant?.rules || []).map((policy, i) => ( -
- {editingPolicy?.tab === 'merchant' && editingPolicy?.index === i ? ( -
- setEditPolicyName(e.target.value)} className="w-full px-2 py-1.5 border border-slate-200 rounded text-sm" placeholder="Policy Name" /> - setEditPolicyDescHtml(val)} placeholder="Policy Description..." minHeight={100} /> -
- - -
+
+ {(settings.companyPolicy?.merchant?.rules || []).map((policy, i) => ( +
+ {editingPolicy?.tab === 'merchant' && editingPolicy?.index === i ? ( +
+ setEditPolicyName(e.target.value)} className="w-full px-2 py-1.5 border border-slate-200 rounded text-sm" placeholder="Policy Name" /> + setEditPolicyDescHtml(val)} placeholder="Policy Description..." minHeight={100} /> +
+ +
- ) : ( -
-
-
- {policy.name} -
-

{policy.description}

-
-
- - +
+ ) : ( +
+
+
+ {policy.name}
+

{policy.description}

- )} -
- ))} -
- {showAddPolicy && ( -
- setNewPolicyName(e.target.value)} className="w-full px-2 py-1.5 border border-slate-200 rounded text-sm mb-2" placeholder="Policy Name" /> - setNewPolicyDesc(val)} placeholder="Policy Description..." minHeight={100} /> -
- - -
+
+ + +
+
+ )}
- )} + ))}
+ {showAddPolicy && ( +
+ setNewPolicyName(e.target.value)} className="w-full px-2 py-1.5 border border-slate-200 rounded text-sm mb-2" placeholder="Policy Name" /> + setNewPolicyDesc(val)} placeholder="Policy Description..." minHeight={100} /> +
+ + +
+
+ )}
+ )} {activeMasterTab === 'swapstation' && (
-
- - setSettings({ ...settings, companyPolicy: { ...settings.companyPolicy, swapStation: { title: e.target.value, description: settings.companyPolicy?.swapStation?.description || '', rules: settings.companyPolicy?.swapStation?.rules || [] } } })} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm mt-1" /> + +
+ +
-
- - setSettings({ ...settings, companyPolicy: { ...settings.companyPolicy, swapStation: { title: settings.companyPolicy?.swapStation?.title || '', description: val, rules: settings.companyPolicy?.swapStation?.rules || [] } } })} placeholder="Enter policy description..." minHeight={160} /> -
-
- -
-
-
- - -
-
- {(settings.companyPolicy?.swapStation?.rules || []).map((policy, i) => ( -
- {editingPolicy?.tab === 'swapstation' && editingPolicy?.index === i ? ( -
- setEditPolicyName(e.target.value)} className="w-full px-2 py-1.5 border border-slate-200 rounded text-sm" placeholder="Policy Name" /> - setEditPolicyDescHtml(val)} placeholder="Policy Description..." minHeight={100} /> -
- - -
+
+ {(settings.companyPolicy?.swapStation?.rules || []).map((policy, i) => ( +
+ {editingPolicy?.tab === 'swapstation' && editingPolicy?.index === i ? ( +
+ setEditPolicyName(e.target.value)} className="w-full px-2 py-1.5 border border-slate-200 rounded text-sm" placeholder="Policy Name" /> + setEditPolicyDescHtml(val)} placeholder="Policy Description..." minHeight={100} /> +
+ +
- ) : ( -
-
-
- {policy.name} -
-

{policy.description}

-
-
- - +
+ ) : ( +
+
+
+ {policy.name}
+

{policy.description}

- )} -
- ))} -
- {showAddPolicy && ( -
- setNewPolicyName(e.target.value)} className="w-full px-2 py-1.5 border border-slate-200 rounded text-sm mb-2" placeholder="Policy Name" /> - setNewPolicyDesc(val)} placeholder="Policy Description..." minHeight={100} /> -
- - -
+
+ + +
+
+ )}
- )} + ))}
+ {showAddPolicy && ( +
+ setNewPolicyName(e.target.value)} className="w-full px-2 py-1.5 border border-slate-200 rounded text-sm mb-2" placeholder="Policy Name" /> + setNewPolicyDesc(val)} placeholder="Policy Description..." minHeight={100} /> +
+ + +
+
+ )}
+ )} {activeMasterTab === 'rentalType' && (
{(settings.companyPolicy?.rentalTypes || []).map((rtype, idx) => (
-
+

{rtype.name}

-
- { - const updated = [...(settings.companyPolicy?.rentalTypes || [])]; - updated[idx] = { ...updated[idx], title: e.target.value }; - setSettings({ ...settings, companyPolicy: { ...settings.companyPolicy, rentalTypes: updated } }); - }} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" placeholder="Policy Title" /> - { - const updated = [...(settings.companyPolicy?.rentalTypes || [])]; - updated[idx] = { ...updated[idx], description: val }; - setSettings({ ...settings, companyPolicy: { ...settings.companyPolicy, rentalTypes: updated } }); - }} placeholder="Enter policy description..." minHeight={120} /> -
-
- -
-
- {(rtype.rules || []).map((policy, policyIdx) => ( -
- {editingPolicy?.tab === 'rentalType' && editingPolicy?.index === policyIdx ? ( -
- setEditPolicyName(e.target.value)} className="w-full px-2 py-1.5 border border-slate-200 rounded text-sm" placeholder="Policy Name" /> - setEditPolicyDescHtml(val)} placeholder="Policy Description..." minHeight={100} /> -
- - -
-
- ) : ( -
-
-
- {policy.name} -
-

{policy.description}

-
-
- - -
-
- )} -
- ))} -
- - {editingPolicy?.tab === 'rentalTypeAdd' && editingPolicy?.index === idx && ( -
- setNewPolicyName(e.target.value)} className="w-full px-2 py-1.5 border border-slate-200 rounded text-sm mb-2" placeholder="Policy Name" /> - setNewPolicyDesc(val)} placeholder="Policy Description..." minHeight={100} /> -
- - -
-
- )} +
+ +
+
+
+ {(rtype.rules || []).map((policy, policyIdx) => ( +
+ {editingPolicy?.tab === 'rentalType' && editingPolicy?.index === policyIdx ? ( +
+ setEditPolicyName(e.target.value)} className="w-full px-2 py-1.5 border border-slate-200 rounded text-sm" placeholder="Policy Name" /> + setEditPolicyDescHtml(val)} placeholder="Policy Description..." minHeight={100} /> +
+ + +
+
+ ) : ( +
+
+
+ {policy.name} +
+

{policy.description}

+
+
+ + +
+
+ )} +
+ ))} +
+ + {editingPolicy?.tab === 'rentalTypeAdd' && editingPolicy?.index === idx && ( +
+ setNewPolicyName(e.target.value)} className="w-full px-2 py-1.5 border border-slate-200 rounded text-sm mb-2" placeholder="Policy Name" /> + setNewPolicyDesc(val)} placeholder="Policy Description..." minHeight={100} /> +
+ + +
+
+ )}
+ ))}
@@ -2173,754 +2136,763 @@ setNewSwapName('');
)}
-)} + ) + } - {activeTab === 'plans' && ( -
-
-

Plan Selection

-
- -
- - - -
- - {activePlanTab === 'singleRent' && ( -
- {settings.plans.singleRent.map((plan, idx) => ( -
-
-
- {/* {plan.tier === 'Premium' ? '👑' : plan.tier === 'Standard' ? '⚖️' : '💰'} */} -
-

SINGLE RENT - {plan.tier} - ৳{plan.dailyRent}/day

-

{plan.description}

-
-
- -
-
-
-
- - { const updated = [...settings.plans.singleRent]; updated[idx].dailyRent = parseInt(e.target.value); setSettings({ ...settings, plans: { ...settings.plans, singleRent: updated } }); }} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm mt-1" /> -
-
- - { const updated = [...settings.plans.singleRent]; updated[idx].weeklySubscription = parseInt(e.target.value); setSettings({ ...settings, plans: { ...settings.plans, singleRent: updated } }); }} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm mt-1" /> -
-
- - { const updated = [...settings.plans.singleRent]; updated[idx].monthlySubscription = parseInt(e.target.value); setSettings({ ...settings, plans: { ...settings.plans, singleRent: updated } }); }} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm mt-1" /> -
-
- - { const updated = [...settings.plans.singleRent]; updated[idx].deposit = parseInt(e.target.value); setSettings({ ...settings, plans: { ...settings.plans, singleRent: updated } }); }} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm mt-1" /> -
-
- - { const updated = [...settings.plans.singleRent]; updated[idx].ficoSharePercent = parseInt(e.target.value); setSettings({ ...settings, plans: { ...settings.plans, singleRent: updated } }); }} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm mt-1" /> -
-
- - -
-
-
-
- FICO + JAIBEN = - {plan.ficoSharePercent + (100 - plan.ficoSharePercent)}% (FICO: {plan.ficoSharePercent}% + JAIBEN: {100 - plan.ficoSharePercent}%) -
-
-
- -