refactor: overhaul project structure, update configuration, and improve consistency across admin and investor dashboard components.
This commit is contained in:
1
JML
Submodule
1
JML
Submodule
Submodule JML added at 7332f85512
@@ -1,7 +1,7 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Plus, Save, Trash2, X } from 'lucide-react';
|
import { Plus, Save, Trash2, X, Gift } from 'lucide-react';
|
||||||
import { CompanySettings } from '../page';
|
import { CompanySettings } from '../page';
|
||||||
|
|
||||||
interface PlanSelectionProps {
|
interface PlanSelectionProps {
|
||||||
@@ -14,6 +14,108 @@ interface PlanSelectionProps {
|
|||||||
isDirty?: boolean;
|
isDirty?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reusable Free Service Conditions editor
|
||||||
|
function FreeServiceConditions({
|
||||||
|
conditions,
|
||||||
|
accentColor,
|
||||||
|
onChange,
|
||||||
|
}: {
|
||||||
|
conditions: { months: number; freeServices: number }[];
|
||||||
|
accentColor: string;
|
||||||
|
onChange: (updated: { months: number; freeServices: number }[]) => void;
|
||||||
|
}) {
|
||||||
|
const addCondition = () => {
|
||||||
|
onChange([...conditions, { months: 3, freeServices: 1 }]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeCondition = (i: number) => {
|
||||||
|
onChange(conditions.filter((_, idx) => idx !== i));
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateCondition = (i: number, field: 'months' | 'freeServices', value: number) => {
|
||||||
|
const updated = conditions.map((c, idx) => idx === i ? { ...c, [field]: value } : c);
|
||||||
|
onChange(updated);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="bg-amber-50 border border-amber-100 rounded-xl p-4 space-y-3">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Gift className="w-4 h-4 text-amber-600" />
|
||||||
|
<label className="text-xs font-semibold text-amber-700 uppercase tracking-wide">
|
||||||
|
Free Service Conditions
|
||||||
|
</label>
|
||||||
|
<span className="text-[10px] text-amber-500 font-medium bg-amber-100 px-2 py-0.5 rounded-full">
|
||||||
|
e.g. "3 months → 2 free services"
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={addCondition}
|
||||||
|
className={`flex items-center gap-1.5 px-2.5 py-1.5 rounded-lg text-xs font-semibold transition-all ${accentColor} text-white hover:opacity-90`}
|
||||||
|
>
|
||||||
|
<Plus className="w-3 h-3" /> Add Condition
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{conditions.length === 0 && (
|
||||||
|
<p className="text-xs text-amber-400 italic text-center py-2">
|
||||||
|
No free service conditions set. Click "Add Condition" to add one.
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="space-y-2">
|
||||||
|
{conditions.map((cond, i) => (
|
||||||
|
<div key={i} className="flex items-center gap-3 bg-white border border-amber-100 rounded-lg px-3 py-2 group">
|
||||||
|
{/* Month input */}
|
||||||
|
<div className="flex items-center gap-1.5">
|
||||||
|
<label className="text-xs text-slate-500 font-medium shrink-0">Month:</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
min={1}
|
||||||
|
max={999}
|
||||||
|
value={cond.months}
|
||||||
|
onChange={(e) => updateCondition(i, 'months', parseInt(e.target.value) || 1)}
|
||||||
|
className="w-16 px-2 py-1 border border-slate-200 rounded-md text-xs text-slate-800 text-center font-semibold focus:outline-none focus:ring-1 focus:ring-amber-400"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span className="text-slate-300 text-sm">→</span>
|
||||||
|
|
||||||
|
{/* Free services input */}
|
||||||
|
<div className="flex items-center gap-1.5">
|
||||||
|
<label className="text-xs text-slate-500 font-medium shrink-0">Free Services:</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
min={1}
|
||||||
|
max={99}
|
||||||
|
value={cond.freeServices}
|
||||||
|
onChange={(e) => updateCondition(i, 'freeServices', parseInt(e.target.value) || 1)}
|
||||||
|
className="w-16 px-2 py-1 border border-slate-200 rounded-md text-xs text-slate-800 text-center font-semibold focus:outline-none focus:ring-1 focus:ring-amber-400"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Preview badge */}
|
||||||
|
<span className="flex-1 text-[10px] font-bold text-amber-700 bg-amber-50 border border-amber-100 rounded-full px-2.5 py-1 text-center truncate">
|
||||||
|
{cond.months} {cond.months === 1 ? 'month' : 'months'} → {cond.freeServices} free service{cond.freeServices !== 1 ? 's' : ''} free
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{/* Remove */}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => removeCondition(i)}
|
||||||
|
className="p-1 text-slate-300 hover:text-red-500 hover:bg-red-50 rounded-md transition-all opacity-0 group-hover:opacity-100"
|
||||||
|
title="Remove condition"
|
||||||
|
>
|
||||||
|
<X className="w-3.5 h-3.5" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default function PlanSelection({
|
export default function PlanSelection({
|
||||||
settings,
|
settings,
|
||||||
setSettings,
|
setSettings,
|
||||||
@@ -172,6 +274,18 @@ export default function PlanSelection({
|
|||||||
</div>
|
</div>
|
||||||
{plan.contractMonths.length === 0 && <p className="text-xs text-slate-400 mt-2">No contract months selected.</p>}
|
{plan.contractMonths.length === 0 && <p className="text-xs text-slate-400 mt-2">No contract months selected.</p>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Free Service Conditions */}
|
||||||
|
<FreeServiceConditions
|
||||||
|
conditions={plan.freeServiceConditions ?? []}
|
||||||
|
accentColor="bg-blue-600"
|
||||||
|
onChange={(updated) => {
|
||||||
|
const plans = [...settings.plans.singleRent];
|
||||||
|
plans[idx] = { ...plans[idx], freeServiceConditions: updated };
|
||||||
|
setSettings({ ...settings, plans: { ...settings.plans, singleRent: plans } });
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-2 block">Description</label>
|
<label className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-2 block">Description</label>
|
||||||
<textarea value={plan.description} onChange={(e) => { const updated = [...settings.plans.singleRent]; updated[idx].description = 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" rows={2} placeholder="Enter plan description..." />
|
<textarea value={plan.description} onChange={(e) => { const updated = [...settings.plans.singleRent]; updated[idx].description = 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" rows={2} placeholder="Enter plan description..." />
|
||||||
@@ -312,6 +426,18 @@ export default function PlanSelection({
|
|||||||
</div>
|
</div>
|
||||||
{plan.contractMonths.length === 0 && <p className="text-xs text-slate-400 mt-2">No contract months selected.</p>}
|
{plan.contractMonths.length === 0 && <p className="text-xs text-slate-400 mt-2">No contract months selected.</p>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Free Service Conditions */}
|
||||||
|
<FreeServiceConditions
|
||||||
|
conditions={plan.freeServiceConditions ?? []}
|
||||||
|
accentColor="bg-purple-600"
|
||||||
|
onChange={(updated) => {
|
||||||
|
const plans = [...settings.plans.rentToOwn];
|
||||||
|
plans[idx] = { ...plans[idx], freeServiceConditions: updated };
|
||||||
|
setSettings({ ...settings, plans: { ...settings.plans, rentToOwn: plans } });
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-2 block">Description</label>
|
<label className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-2 block">Description</label>
|
||||||
<textarea value={plan.description} onChange={(e) => { const updated = [...settings.plans.rentToOwn]; updated[idx].description = e.target.value; setSettings({ ...settings, plans: { ...settings.plans, rentToOwn: updated } }); }} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" rows={2} placeholder="Enter plan description..." />
|
<textarea value={plan.description} onChange={(e) => { const updated = [...settings.plans.rentToOwn]; updated[idx].description = e.target.value; setSettings({ ...settings, plans: { ...settings.plans, rentToOwn: updated } }); }} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" rows={2} placeholder="Enter plan description..." />
|
||||||
@@ -452,6 +578,18 @@ export default function PlanSelection({
|
|||||||
</div>
|
</div>
|
||||||
{plan.contractMonths.length === 0 && <p className="text-xs text-slate-400 mt-2">No contract months selected.</p>}
|
{plan.contractMonths.length === 0 && <p className="text-xs text-slate-400 mt-2">No contract months selected.</p>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Free Service Conditions */}
|
||||||
|
<FreeServiceConditions
|
||||||
|
conditions={plan.freeServiceConditions ?? []}
|
||||||
|
accentColor="bg-green-600"
|
||||||
|
onChange={(updated) => {
|
||||||
|
const plans = [...settings.plans.shareEv];
|
||||||
|
plans[idx] = { ...plans[idx], freeServiceConditions: updated };
|
||||||
|
setSettings({ ...settings, plans: { ...settings.plans, shareEv: plans } });
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-2 block">Description</label>
|
<label className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-2 block">Description</label>
|
||||||
<textarea value={plan.description} onChange={(e) => { const updated = [...settings.plans.shareEv]; updated[idx].description = e.target.value; setSettings({ ...settings, plans: { ...settings.plans, shareEv: updated } }); }} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" rows={2} placeholder="Enter plan description..." />
|
<textarea value={plan.description} onChange={(e) => { const updated = [...settings.plans.shareEv]; updated[idx].description = e.target.value; setSettings({ ...settings, plans: { ...settings.plans, shareEv: updated } }); }} className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm" rows={2} placeholder="Enter plan description..." />
|
||||||
@@ -465,26 +603,16 @@ export default function PlanSelection({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{deleteModal.type !== null && deleteModal.idx !== null && (
|
|
||||||
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
|
{/* Delete Confirmation Modal */}
|
||||||
<div className="bg-white rounded-xl shadow-xl w-full max-w-sm">
|
{deleteModal.type !== null && (
|
||||||
<div className="p-4 border-b border-slate-100 flex justify-between items-center">
|
<div className="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50 p-4">
|
||||||
<h3 className="font-semibold text-slate-800 flex items-center gap-2">
|
<div className="bg-white rounded-xl shadow-xl w-full max-w-md p-6 space-y-4">
|
||||||
<Trash2 className="w-5 h-5 text-red-500" /> Delete Plan
|
<h3 className="text-lg font-bold text-slate-800">Delete Plan?</h3>
|
||||||
</h3>
|
<p className="text-sm text-slate-500">This will permanently remove the plan. This action cannot be undone.</p>
|
||||||
<button onClick={() => setDeleteModal({ type: null, idx: null })} className="text-slate-400 hover:text-slate-600 text-2xl">×</button>
|
<div className="flex items-center justify-end gap-2 pt-2 border-t border-slate-100">
|
||||||
</div>
|
<button onClick={() => setDeleteModal({ type: null, idx: null })} className="px-4 py-2 border border-slate-200 text-slate-500 rounded-lg text-sm font-medium hover:bg-slate-50">Cancel</button>
|
||||||
<div className="p-4">
|
<button onClick={handleDeletePlan} className="px-4 py-2 bg-red-600 text-white rounded-lg text-sm font-medium hover:bg-red-700">Delete Plan</button>
|
||||||
<p className="text-sm text-slate-600">Are you sure you want to delete this plan? This action cannot be undone.</p>
|
|
||||||
{deleteModal.type && deleteModal.idx !== null && settings.plans[deleteModal.type][deleteModal.idx] && (
|
|
||||||
<div className="mt-3 p-3 bg-slate-50 rounded-lg">
|
|
||||||
<p className="text-sm font-medium text-slate-700">{settings.plans[deleteModal.type][deleteModal.idx].name}</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className="p-4 border-t border-slate-100 flex justify-end gap-2">
|
|
||||||
<button onClick={() => setDeleteModal({ type: null, idx: null })} className="px-4 py-2 border border-slate-200 text-slate-600 rounded-lg text-sm">Cancel</button>
|
|
||||||
<button onClick={handleDeletePlan} className="px-4 py-2 bg-red-600 text-white rounded-lg text-sm hover:bg-red-700">Delete Plan</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ export interface CompanySettings {
|
|||||||
monthlyPenalty2: number;
|
monthlyPenalty2: number;
|
||||||
monthlyPenalty3: number;
|
monthlyPenalty3: number;
|
||||||
ficoSharePercent: number;
|
ficoSharePercent: number;
|
||||||
|
freeServiceConditions: { months: number; freeServices: number }[];
|
||||||
description: string;
|
description: string;
|
||||||
}[];
|
}[];
|
||||||
rentToOwn: {
|
rentToOwn: {
|
||||||
@@ -151,6 +152,7 @@ export interface CompanySettings {
|
|||||||
profit: number;
|
profit: number;
|
||||||
ficoRentSharePercent: number;
|
ficoRentSharePercent: number;
|
||||||
ficoProfitSharePercent: number;
|
ficoProfitSharePercent: number;
|
||||||
|
freeServiceConditions: { months: number; freeServices: number }[];
|
||||||
description: string;
|
description: string;
|
||||||
}[];
|
}[];
|
||||||
shareEv: {
|
shareEv: {
|
||||||
@@ -179,6 +181,7 @@ export interface CompanySettings {
|
|||||||
monthlyPenalty3: number;
|
monthlyPenalty3: number;
|
||||||
totalMonthlySubscription: number;
|
totalMonthlySubscription: number;
|
||||||
ficoSharePercent: number;
|
ficoSharePercent: number;
|
||||||
|
freeServiceConditions: { months: number; freeServices: number }[];
|
||||||
description: string;
|
description: string;
|
||||||
}[];
|
}[];
|
||||||
investment: {
|
investment: {
|
||||||
@@ -498,6 +501,10 @@ const initialSettings: CompanySettings = {
|
|||||||
monthlyPenalty2: 30000,
|
monthlyPenalty2: 30000,
|
||||||
monthlyPenalty3: 50000,
|
monthlyPenalty3: 50000,
|
||||||
ficoSharePercent: 50,
|
ficoSharePercent: 50,
|
||||||
|
freeServiceConditions: [
|
||||||
|
{ months: 3, freeServices: 2 },
|
||||||
|
{ months: 6, freeServices: 4 },
|
||||||
|
],
|
||||||
description: 'Premium single person rental plan with extra benefits',
|
description: 'Premium single person rental plan with extra benefits',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -519,6 +526,10 @@ const initialSettings: CompanySettings = {
|
|||||||
monthlyPenalty2: 22000,
|
monthlyPenalty2: 22000,
|
||||||
monthlyPenalty3: 40000,
|
monthlyPenalty3: 40000,
|
||||||
ficoSharePercent: 45,
|
ficoSharePercent: 45,
|
||||||
|
freeServiceConditions: [
|
||||||
|
{ months: 2, freeServices: 1 },
|
||||||
|
{ months: 3, freeServices: 2 },
|
||||||
|
],
|
||||||
description: 'Standard single person rental plan',
|
description: 'Standard single person rental plan',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -540,6 +551,9 @@ const initialSettings: CompanySettings = {
|
|||||||
monthlyPenalty2: 18000,
|
monthlyPenalty2: 18000,
|
||||||
monthlyPenalty3: 30000,
|
monthlyPenalty3: 30000,
|
||||||
ficoSharePercent: 40,
|
ficoSharePercent: 40,
|
||||||
|
freeServiceConditions: [
|
||||||
|
{ months: 2, freeServices: 1 },
|
||||||
|
],
|
||||||
description: 'Economy single person rental plan',
|
description: 'Economy single person rental plan',
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -568,6 +582,10 @@ const initialSettings: CompanySettings = {
|
|||||||
profit: 20000,
|
profit: 20000,
|
||||||
ficoRentSharePercent: 50,
|
ficoRentSharePercent: 50,
|
||||||
ficoProfitSharePercent: 45,
|
ficoProfitSharePercent: 45,
|
||||||
|
freeServiceConditions: [
|
||||||
|
{ months: 3, freeServices: 2 },
|
||||||
|
{ months: 6, freeServices: 4 },
|
||||||
|
],
|
||||||
description: 'Premium rent to own plan with high-end EV',
|
description: 'Premium rent to own plan with high-end EV',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -594,6 +612,10 @@ const initialSettings: CompanySettings = {
|
|||||||
profit: 15000,
|
profit: 15000,
|
||||||
ficoRentSharePercent: 45,
|
ficoRentSharePercent: 45,
|
||||||
ficoProfitSharePercent: 45,
|
ficoProfitSharePercent: 45,
|
||||||
|
freeServiceConditions: [
|
||||||
|
{ months: 2, freeServices: 1 },
|
||||||
|
{ months: 3, freeServices: 2 },
|
||||||
|
],
|
||||||
description: 'Standard rent to own plan',
|
description: 'Standard rent to own plan',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -620,6 +642,9 @@ const initialSettings: CompanySettings = {
|
|||||||
profit: 15000,
|
profit: 15000,
|
||||||
ficoRentSharePercent: 40,
|
ficoRentSharePercent: 40,
|
||||||
ficoProfitSharePercent: 40,
|
ficoProfitSharePercent: 40,
|
||||||
|
freeServiceConditions: [
|
||||||
|
{ months: 2, freeServices: 1 },
|
||||||
|
],
|
||||||
description: 'Economy rent to own plan',
|
description: 'Economy rent to own plan',
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -650,6 +675,10 @@ const initialSettings: CompanySettings = {
|
|||||||
monthlyPenalty3: 35000,
|
monthlyPenalty3: 35000,
|
||||||
totalMonthlySubscription: 16800,
|
totalMonthlySubscription: 16800,
|
||||||
ficoSharePercent: 50,
|
ficoSharePercent: 50,
|
||||||
|
freeServiceConditions: [
|
||||||
|
{ months: 3, freeServices: 2 },
|
||||||
|
{ months: 6, freeServices: 4 },
|
||||||
|
],
|
||||||
description: 'Premium shared EV with premium bikes',
|
description: 'Premium shared EV with premium bikes',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -678,6 +707,10 @@ const initialSettings: CompanySettings = {
|
|||||||
monthlyPenalty3: 25000,
|
monthlyPenalty3: 25000,
|
||||||
totalMonthlySubscription: 11200,
|
totalMonthlySubscription: 11200,
|
||||||
ficoSharePercent: 45,
|
ficoSharePercent: 45,
|
||||||
|
freeServiceConditions: [
|
||||||
|
{ months: 2, freeServices: 1 },
|
||||||
|
{ months: 3, freeServices: 2 },
|
||||||
|
],
|
||||||
description: 'Standard shared EV plan',
|
description: 'Standard shared EV plan',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -706,6 +739,9 @@ const initialSettings: CompanySettings = {
|
|||||||
monthlyPenalty3: 20000,
|
monthlyPenalty3: 20000,
|
||||||
totalMonthlySubscription: 8400,
|
totalMonthlySubscription: 8400,
|
||||||
ficoSharePercent: 40,
|
ficoSharePercent: 40,
|
||||||
|
freeServiceConditions: [
|
||||||
|
{ months: 2, freeServices: 1 },
|
||||||
|
],
|
||||||
description: 'Economy shared EV plan',
|
description: 'Economy shared EV plan',
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -1127,6 +1163,7 @@ export default function CompanySettingsPage() {
|
|||||||
monthlyPenalty2: 22000,
|
monthlyPenalty2: 22000,
|
||||||
monthlyPenalty3: 40000,
|
monthlyPenalty3: 40000,
|
||||||
ficoSharePercent: 45,
|
ficoSharePercent: 45,
|
||||||
|
freeServiceConditions: [],
|
||||||
description: '',
|
description: '',
|
||||||
} : type === 'rentToOwn' ? {
|
} : type === 'rentToOwn' ? {
|
||||||
id: newId,
|
id: newId,
|
||||||
@@ -1152,6 +1189,7 @@ export default function CompanySettingsPage() {
|
|||||||
profit: 15000,
|
profit: 15000,
|
||||||
ficoRentSharePercent: 45,
|
ficoRentSharePercent: 45,
|
||||||
ficoProfitSharePercent: 45,
|
ficoProfitSharePercent: 45,
|
||||||
|
freeServiceConditions: [],
|
||||||
description: '',
|
description: '',
|
||||||
} : {
|
} : {
|
||||||
id: newId,
|
id: newId,
|
||||||
@@ -1179,6 +1217,7 @@ export default function CompanySettingsPage() {
|
|||||||
monthlyPenalty3: 25000,
|
monthlyPenalty3: 25000,
|
||||||
totalMonthlySubscription: 11200,
|
totalMonthlySubscription: 11200,
|
||||||
ficoSharePercent: 45,
|
ficoSharePercent: 45,
|
||||||
|
freeServiceConditions: [],
|
||||||
description: '',
|
description: '',
|
||||||
};
|
};
|
||||||
if (type === 'singleRent') {
|
if (type === 'singleRent') {
|
||||||
|
|||||||
Reference in New Issue
Block a user