feat: client extra fields + KYC home-visit & video-KYC dialogs
- Add Education Level, Degree/Qualification, Religion, Social Category dropdowns (individual clients) with dependent filtering on the create/edit/preview/view flows - Add Agriculture Income & Non-Agriculture Income fields under Financial & Classification - Gate Save with a Verify Client alert dialog when sanctions screening is not yet performed - Trim Office Name and CKYC Number columns from clients list; widen table to fill container - Remove DIP/Screening log IDs from preview and personal-data tabs - Rename "Branch Visit" to "Home Visit" across KYC management - Wire Take Action: open dedicated dialogs for Schedule Home Visit (officer + datetime) and Send Video KYC link (channels + officer + 48h expiry + session preview) - Migrate Signatory and Guardian image dialogs to inject() for prefer-inject lint rule Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
d72e969dc3
commit
52e3395345
@@ -89,6 +89,38 @@ export class KycManagementComponent {
|
||||
toastVisible = false;
|
||||
private toastTimer: any;
|
||||
|
||||
/** Home Visit scheduling dialog */
|
||||
homeVisitOpen = false;
|
||||
homeVisitOfficer = '';
|
||||
homeVisitDateTime = '';
|
||||
homeVisitNote = '';
|
||||
bankOfficers = [
|
||||
'Amit Sharma — Branch Officer (Bhopal Main)',
|
||||
'Neha Verma — KYC Officer (Bhopal Main)',
|
||||
'Ravi Kulkarni — Field Officer (Bhopal Zone-2)',
|
||||
'Sunita Patel — Compliance Officer (Bhopal Main)',
|
||||
'Manoj Tiwari — Field Officer (Indore Zone-1)'
|
||||
];
|
||||
scheduledHomeVisits: { client: string; address: string; officer: string; dateTime: string; note: string }[] = [];
|
||||
|
||||
/** Video KYC link dialog */
|
||||
vkycOpen = false;
|
||||
vkycOfficer = '';
|
||||
vkycExpiry = '';
|
||||
vkycChannels = { sms: true, email: true, whatsapp: false };
|
||||
vkycMessage = '';
|
||||
vkycSessionId = '';
|
||||
sentVkycLinks: {
|
||||
client: string;
|
||||
mobile: string;
|
||||
email: string;
|
||||
officer: string;
|
||||
expiry: string;
|
||||
channels: string[];
|
||||
sessionId: string;
|
||||
link: string;
|
||||
}[] = [];
|
||||
|
||||
clients: Record<string, KmClient> = {
|
||||
rajesh: {
|
||||
id: 'rajesh',
|
||||
@@ -119,14 +151,35 @@ export class KycManagementComponent {
|
||||
branch: 'Bhopal Main'
|
||||
},
|
||||
notices: [
|
||||
{ no: 'N1', channel: 'SMS + Email', date: '31 Mar 2027', ref: 'MSG-2027-0331-001', delivery: 'Delivered', response: 'No Action' },
|
||||
{ no: 'N2', channel: 'Reg. Post + IVR', date: '10 Apr 2027', ref: 'RP-BPL-20270410-443', delivery: 'In Transit', response: 'Pending' }
|
||||
{
|
||||
no: 'N1',
|
||||
channel: 'SMS + Email',
|
||||
date: '31 Mar 2027',
|
||||
ref: 'MSG-2027-0331-001',
|
||||
delivery: 'Delivered',
|
||||
response: 'No Action'
|
||||
},
|
||||
{
|
||||
no: 'N2',
|
||||
channel: 'Reg. Post + IVR',
|
||||
date: '10 Apr 2027',
|
||||
ref: 'RP-BPL-20270410-443',
|
||||
delivery: 'In Transit',
|
||||
response: 'Pending'
|
||||
}
|
||||
],
|
||||
noticesSent: 2,
|
||||
noticePending: 'Notice 3',
|
||||
nextStage: 'Debit Freeze',
|
||||
pendingActions: ['Send Notice 3 (due 20 Apr 2027)', 'Schedule Branch Visit', 'Send Video KYC link'],
|
||||
actionTaken: ['Notice 1 delivered', 'Notice 2 dispatched via Reg. Post'],
|
||||
pendingActions: [
|
||||
'Send Notice 3 (due 20 Apr 2027)',
|
||||
'Schedule Home Visit',
|
||||
'Send Video KYC link'
|
||||
],
|
||||
actionTaken: [
|
||||
'Notice 1 delivered',
|
||||
'Notice 2 dispatched via Reg. Post'
|
||||
],
|
||||
evidence: null
|
||||
},
|
||||
priya: {
|
||||
@@ -158,15 +211,45 @@ export class KycManagementComponent {
|
||||
branch: 'Bhopal Main'
|
||||
},
|
||||
notices: [
|
||||
{ no: 'N1', channel: 'SMS + Email', date: '10 Mar 2027', ref: 'MSG-2027-0310-003', delivery: 'Delivered', response: 'No Response' },
|
||||
{ no: 'N2', channel: 'Reg. Post', date: '20 Mar 2027', ref: 'RP-BPL-20270320-091', delivery: 'Delivered', response: 'No Response' },
|
||||
{ no: 'N3', channel: 'Branch Visit', date: '30 Mar 2027', ref: 'VIS-BPL-20270330-012', delivery: 'Visit Done', response: 'Refused' }
|
||||
{
|
||||
no: 'N1',
|
||||
channel: 'SMS + Email',
|
||||
date: '10 Mar 2027',
|
||||
ref: 'MSG-2027-0310-003',
|
||||
delivery: 'Delivered',
|
||||
response: 'No Response'
|
||||
},
|
||||
{
|
||||
no: 'N2',
|
||||
channel: 'Reg. Post',
|
||||
date: '20 Mar 2027',
|
||||
ref: 'RP-BPL-20270320-091',
|
||||
delivery: 'Delivered',
|
||||
response: 'No Response'
|
||||
},
|
||||
{
|
||||
no: 'N3',
|
||||
channel: 'Home Visit',
|
||||
date: '30 Mar 2027',
|
||||
ref: 'VIS-BPL-20270330-012',
|
||||
delivery: 'Visit Done',
|
||||
response: 'Refused'
|
||||
}
|
||||
],
|
||||
noticesSent: 3,
|
||||
noticePending: 'None — all 3 sent',
|
||||
nextStage: 'Inoperative by 30 Jun 2027',
|
||||
pendingActions: ['Account in Debit Freeze', 'Inoperative transition due 30 Jun 2027', 'Maker-checker unfreeze pending'],
|
||||
actionTaken: ['Notice 1 delivered', 'Notice 2 delivered via Reg. Post', 'Notice 3 — Branch visit done, client refused', 'Debit Freeze applied 10 Apr 2027'],
|
||||
pendingActions: [
|
||||
'Account in Debit Freeze',
|
||||
'Inoperative transition due 30 Jun 2027',
|
||||
'Maker-checker unfreeze pending'
|
||||
],
|
||||
actionTaken: [
|
||||
'Notice 1 delivered',
|
||||
'Notice 2 delivered via Reg. Post',
|
||||
'Notice 3 — Branch visit done, client refused',
|
||||
'Debit Freeze applied 10 Apr 2027'
|
||||
],
|
||||
evidence: {
|
||||
type: 'visit',
|
||||
date: '30 Mar 2027',
|
||||
@@ -206,15 +289,46 @@ export class KycManagementComponent {
|
||||
branch: 'Bhopal South'
|
||||
},
|
||||
notices: [
|
||||
{ no: 'N1', channel: 'SMS + Email', date: '13 Feb 2027', ref: 'MSG-2027-0213-006', delivery: 'Delivered', response: 'No Response' },
|
||||
{ no: 'N2', channel: 'Reg. Post + IVR', date: '23 Feb 2027', ref: 'RP-BPL-20270223-044', delivery: 'Delivered', response: 'No Response' },
|
||||
{ no: 'N3', channel: 'Video KYC', date: '5 Mar 2027', ref: 'VKYC-2027-0305-007', delivery: 'No Response', response: 'No Action' }
|
||||
{
|
||||
no: 'N1',
|
||||
channel: 'SMS + Email',
|
||||
date: '13 Feb 2027',
|
||||
ref: 'MSG-2027-0213-006',
|
||||
delivery: 'Delivered',
|
||||
response: 'No Response'
|
||||
},
|
||||
{
|
||||
no: 'N2',
|
||||
channel: 'Reg. Post + IVR',
|
||||
date: '23 Feb 2027',
|
||||
ref: 'RP-BPL-20270223-044',
|
||||
delivery: 'Delivered',
|
||||
response: 'No Response'
|
||||
},
|
||||
{
|
||||
no: 'N3',
|
||||
channel: 'Video KYC',
|
||||
date: '5 Mar 2027',
|
||||
ref: 'VKYC-2027-0305-007',
|
||||
delivery: 'No Response',
|
||||
response: 'No Action'
|
||||
}
|
||||
],
|
||||
noticesSent: 3,
|
||||
noticePending: 'None',
|
||||
nextStage: 'Dormant by 30 Sep 2027',
|
||||
pendingActions: ['Account Inoperative — all txns blocked', 'Dormant transition due 30 Sep 2027', 'RBI Dormant Account reporting'],
|
||||
actionTaken: ['Notice 1 delivered', 'Notice 2 delivered via Reg. Post', 'Notice 3 — Video KYC invite sent (no response)', 'Debit Freeze 15 Mar 2027', 'Inoperative 15 May 2027'],
|
||||
pendingActions: [
|
||||
'Account Inoperative — all txns blocked',
|
||||
'Dormant transition due 30 Sep 2027',
|
||||
'RBI Dormant Account reporting'
|
||||
],
|
||||
actionTaken: [
|
||||
'Notice 1 delivered',
|
||||
'Notice 2 delivered via Reg. Post',
|
||||
'Notice 3 — Video KYC invite sent (no response)',
|
||||
'Debit Freeze 15 Mar 2027',
|
||||
'Inoperative 15 May 2027'
|
||||
],
|
||||
evidence: {
|
||||
type: 'vkyc',
|
||||
date: '5 Mar 2027',
|
||||
@@ -252,22 +366,54 @@ export class KycManagementComponent {
|
||||
branch: 'Bhopal East'
|
||||
},
|
||||
notices: [
|
||||
{ no: 'N1', channel: 'SMS + Email', date: '1 Dec 2026', ref: 'MSG-2026-1201-009', delivery: 'Delivered', response: 'No Response' },
|
||||
{ no: 'N2', channel: 'Reg. Post', date: '11 Dec 2026', ref: 'RP-BPL-20261211-077', delivery: 'Delivered', response: 'No Response' },
|
||||
{ no: 'N3', channel: 'Branch Visit', date: '22 Dec 2026', ref: 'VIS-BPL-20261222-019', delivery: 'Not Found', response: 'Not Found at Address' }
|
||||
{
|
||||
no: 'N1',
|
||||
channel: 'SMS + Email',
|
||||
date: '1 Dec 2026',
|
||||
ref: 'MSG-2026-1201-009',
|
||||
delivery: 'Delivered',
|
||||
response: 'No Response'
|
||||
},
|
||||
{
|
||||
no: 'N2',
|
||||
channel: 'Reg. Post',
|
||||
date: '11 Dec 2026',
|
||||
ref: 'RP-BPL-20261211-077',
|
||||
delivery: 'Delivered',
|
||||
response: 'No Response'
|
||||
},
|
||||
{
|
||||
no: 'N3',
|
||||
channel: 'Home Visit',
|
||||
date: '22 Dec 2026',
|
||||
ref: 'VIS-BPL-20261222-019',
|
||||
delivery: 'Not Found',
|
||||
response: 'Not Found at Address'
|
||||
}
|
||||
],
|
||||
noticesSent: 3,
|
||||
noticePending: 'None',
|
||||
nextStage: 'Dormant (Final) — RBI Reporting',
|
||||
pendingActions: ['RBI Dormant Account Report submission', 'Branch Manager approval for any reversal', 'Regional Manager sign-off required'],
|
||||
actionTaken: ['Notice 1–3 sent, all no response', 'Debit Freeze 1 Jan 2027', 'Inoperative 2 Mar 2027', 'Dormant 1 Jun 2027', 'RBI report auto-generated'],
|
||||
pendingActions: [
|
||||
'RBI Dormant Account Report submission',
|
||||
'Branch Manager approval for any reversal',
|
||||
'Regional Manager sign-off required'
|
||||
],
|
||||
actionTaken: [
|
||||
'Notice 1–3 sent, all no response',
|
||||
'Debit Freeze 1 Jan 2027',
|
||||
'Inoperative 2 Mar 2027',
|
||||
'Dormant 1 Jun 2027',
|
||||
'RBI report auto-generated'
|
||||
],
|
||||
evidence: {
|
||||
type: 'visit',
|
||||
date: '22 Dec 2026',
|
||||
officer: 'Rekha Sharma',
|
||||
gps: '23.2491° N, 77.4384° E',
|
||||
location: 'Awadhpuri, Bhopal',
|
||||
outcome: 'Client not found at registered address. Neighbours confirmed relocation. Address verification required.',
|
||||
outcome:
|
||||
'Client not found at registered address. Neighbours confirmed relocation. Address verification required.',
|
||||
docket: 'VIS-BPL-20261222-019'
|
||||
}
|
||||
},
|
||||
@@ -300,12 +446,23 @@ export class KycManagementComponent {
|
||||
branch: 'Bhopal Main'
|
||||
},
|
||||
notices: [
|
||||
{ no: 'N1', channel: 'SMS + Email', date: '5 Apr 2027', ref: 'MSG-2027-0405-011', delivery: 'Delivered', response: 'No Action' }
|
||||
{
|
||||
no: 'N1',
|
||||
channel: 'SMS + Email',
|
||||
date: '5 Apr 2027',
|
||||
ref: 'MSG-2027-0405-011',
|
||||
delivery: 'Delivered',
|
||||
response: 'No Action'
|
||||
}
|
||||
],
|
||||
noticesSent: 1,
|
||||
noticePending: 'Notice 2 & 3',
|
||||
nextStage: 'Debit Freeze if no action',
|
||||
pendingActions: ['Send Notice 2 (due 15 Apr 2027)', 'Send Notice 3 (due 25 Apr 2027)', 'Branch visit if needed'],
|
||||
pendingActions: [
|
||||
'Send Notice 2 (due 15 Apr 2027)',
|
||||
'Send Notice 3 (due 25 Apr 2027)',
|
||||
'Branch visit if needed'
|
||||
],
|
||||
actionTaken: ['Notice 1 delivered 5 Apr 2027'],
|
||||
evidence: null
|
||||
},
|
||||
@@ -338,14 +495,35 @@ export class KycManagementComponent {
|
||||
branch: 'Bhopal North'
|
||||
},
|
||||
notices: [
|
||||
{ no: 'N1', channel: 'SMS + Email', date: '29 Mar 2027', ref: 'MSG-2027-0329-014', delivery: 'Delivered', response: 'No Action' },
|
||||
{ no: 'N2', channel: 'Reg. Post + IVR', date: '8 Apr 2027', ref: 'RP-BPL-20270408-088', delivery: 'Delivered', response: 'No Response' }
|
||||
{
|
||||
no: 'N1',
|
||||
channel: 'SMS + Email',
|
||||
date: '29 Mar 2027',
|
||||
ref: 'MSG-2027-0329-014',
|
||||
delivery: 'Delivered',
|
||||
response: 'No Action'
|
||||
},
|
||||
{
|
||||
no: 'N2',
|
||||
channel: 'Reg. Post + IVR',
|
||||
date: '8 Apr 2027',
|
||||
ref: 'RP-BPL-20270408-088',
|
||||
delivery: 'Delivered',
|
||||
response: 'No Response'
|
||||
}
|
||||
],
|
||||
noticesSent: 2,
|
||||
noticePending: 'URGENT: Notice 3',
|
||||
nextStage: 'Debit Freeze in 3 days',
|
||||
pendingActions: ['URGENT: Send Notice 3 NOW', 'Schedule Branch Visit immediately', 'Consider Video KYC as last resort'],
|
||||
actionTaken: ['Notice 1 delivered', 'Notice 2 delivered via Reg. Post + IVR'],
|
||||
pendingActions: [
|
||||
'URGENT: Send Notice 3 NOW',
|
||||
'Schedule Home Visit immediately',
|
||||
'Consider Video KYC as last resort'
|
||||
],
|
||||
actionTaken: [
|
||||
'Notice 1 delivered',
|
||||
'Notice 2 delivered via Reg. Post + IVR'
|
||||
],
|
||||
evidence: null
|
||||
}
|
||||
};
|
||||
@@ -384,6 +562,108 @@ export class KycManagementComponent {
|
||||
this.toastTimer = setTimeout(() => (this.toastVisible = false), 2800);
|
||||
}
|
||||
|
||||
/**
|
||||
* Routes a "Take Action" click. Opens the Home Visit dialog if the action is
|
||||
* a home-visit scheduling action; otherwise falls back to a toast confirmation.
|
||||
*/
|
||||
takeAction(action: string): void {
|
||||
if (!this.current) return;
|
||||
const lower = action.toLowerCase();
|
||||
if (lower.includes('home visit')) {
|
||||
this.openHomeVisitDialog();
|
||||
return;
|
||||
}
|
||||
if (lower.includes('video kyc')) {
|
||||
this.openVkycDialog();
|
||||
return;
|
||||
}
|
||||
this.toast(action + ' initiated for ' + this.current.name);
|
||||
}
|
||||
|
||||
openHomeVisitDialog(): void {
|
||||
this.homeVisitOfficer = '';
|
||||
this.homeVisitNote = '';
|
||||
// Default to tomorrow at 10:00 AM (datetime-local format: YYYY-MM-DDTHH:mm)
|
||||
const t = new Date();
|
||||
t.setDate(t.getDate() + 1);
|
||||
t.setHours(10, 0, 0, 0);
|
||||
const pad = (n: number) => n.toString().padStart(2, '0');
|
||||
this.homeVisitDateTime = `${t.getFullYear()}-${pad(t.getMonth() + 1)}-${pad(t.getDate())}T${pad(t.getHours())}:${pad(t.getMinutes())}`;
|
||||
this.homeVisitOpen = true;
|
||||
}
|
||||
|
||||
closeHomeVisitDialog(): void {
|
||||
this.homeVisitOpen = false;
|
||||
}
|
||||
|
||||
saveHomeVisit(): void {
|
||||
if (!this.current || !this.homeVisitOfficer || !this.homeVisitDateTime) return;
|
||||
this.scheduledHomeVisits.push({
|
||||
client: this.current.name,
|
||||
address: this.current.contact.address,
|
||||
officer: this.homeVisitOfficer,
|
||||
dateTime: this.homeVisitDateTime,
|
||||
note: this.homeVisitNote
|
||||
});
|
||||
const when = new Date(this.homeVisitDateTime).toLocaleString('en-IN', {
|
||||
day: '2-digit',
|
||||
month: 'short',
|
||||
year: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
});
|
||||
this.toast(`Home Visit scheduled for ${this.current.name} on ${when}`);
|
||||
this.homeVisitOpen = false;
|
||||
}
|
||||
|
||||
openVkycDialog(): void {
|
||||
this.vkycOfficer = '';
|
||||
this.vkycMessage = '';
|
||||
this.vkycChannels = { sms: true, email: true, whatsapp: false };
|
||||
// Default: link expires 48 hours from now (RBI Video-based KYC norms)
|
||||
const t = new Date();
|
||||
t.setHours(t.getHours() + 48);
|
||||
const pad = (n: number) => n.toString().padStart(2, '0');
|
||||
this.vkycExpiry = `${t.getFullYear()}-${pad(t.getMonth() + 1)}-${pad(t.getDate())}T${pad(t.getHours())}:${pad(t.getMinutes())}`;
|
||||
// Generate a session id (token preview only — server would issue the real one)
|
||||
this.vkycSessionId = 'VKYC-' + Math.random().toString(36).slice(2, 10).toUpperCase();
|
||||
this.vkycOpen = true;
|
||||
}
|
||||
|
||||
closeVkycDialog(): void {
|
||||
this.vkycOpen = false;
|
||||
}
|
||||
|
||||
get vkycSelectedChannels(): string[] {
|
||||
const out: string[] = [];
|
||||
if (this.vkycChannels.sms) out.push('SMS');
|
||||
if (this.vkycChannels.email) out.push('Email');
|
||||
if (this.vkycChannels.whatsapp) out.push('WhatsApp');
|
||||
return out;
|
||||
}
|
||||
|
||||
get vkycLink(): string {
|
||||
return `https://vkyc.bank.example/session/${this.vkycSessionId}`;
|
||||
}
|
||||
|
||||
saveVkyc(): void {
|
||||
if (!this.current || !this.vkycOfficer || !this.vkycExpiry) return;
|
||||
const channels = this.vkycSelectedChannels;
|
||||
if (channels.length === 0) return;
|
||||
this.sentVkycLinks.push({
|
||||
client: this.current.name,
|
||||
mobile: this.current.contact.mobile,
|
||||
email: this.current.contact.email,
|
||||
officer: this.vkycOfficer,
|
||||
expiry: this.vkycExpiry,
|
||||
channels,
|
||||
sessionId: this.vkycSessionId,
|
||||
link: this.vkycLink
|
||||
});
|
||||
this.toast(`Video KYC link sent to ${this.current.name} via ${channels.join(' + ')}`);
|
||||
this.vkycOpen = false;
|
||||
}
|
||||
|
||||
/** Compliance journey stepper state for a given client */
|
||||
getStepperState(c: KmClient): { label: string; state: 'done' | 'pending' | 'current' | 'danger' }[] {
|
||||
return [
|
||||
@@ -393,19 +673,20 @@ export class KycManagementComponent {
|
||||
{
|
||||
label: 'Notice 3',
|
||||
state:
|
||||
c.noticesSent >= 3
|
||||
? 'done'
|
||||
: c.noticesSent >= 2
|
||||
? c.state === 'urgent'
|
||||
? 'danger'
|
||||
: 'current'
|
||||
: 'pending'
|
||||
c.noticesSent >= 3 ? 'done' : c.noticesSent >= 2 ? (c.state === 'urgent' ? 'danger' : 'current') : 'pending'
|
||||
},
|
||||
{
|
||||
label: 'Debit Freeze',
|
||||
state: ['freeze', 'inop', 'dormant'].includes(c.state) ? 'done' : c.noticesSent >= 3 ? 'danger' : 'pending'
|
||||
state: [
|
||||
'freeze',
|
||||
'inop',
|
||||
'dormant'
|
||||
].includes(c.state) ? 'done' : c.noticesSent >= 3 ? 'danger' : 'pending'
|
||||
},
|
||||
{ label: 'Inoperative', state: ['inop', 'dormant'].includes(c.state) ? 'done' : 'pending' },
|
||||
{ label: 'Inoperative', state: [
|
||||
'inop',
|
||||
'dormant'
|
||||
].includes(c.state) ? 'done' : 'pending' },
|
||||
{ label: 'Dormant', state: c.state === 'dormant' ? 'danger' : 'pending' }
|
||||
];
|
||||
}
|
||||
@@ -418,26 +699,30 @@ export class KycManagementComponent {
|
||||
|
||||
stateLabel(state: string): string {
|
||||
return (
|
||||
{
|
||||
alert: 'Alert Window',
|
||||
freeze: 'Debit Freeze',
|
||||
inop: 'Inoperative',
|
||||
dormant: 'Dormant',
|
||||
urgent: 'Urgent Alert'
|
||||
} as Record<string, string>
|
||||
)[state] || state;
|
||||
(
|
||||
{
|
||||
alert: 'Alert Window',
|
||||
freeze: 'Debit Freeze',
|
||||
inop: 'Inoperative',
|
||||
dormant: 'Dormant',
|
||||
urgent: 'Urgent Alert'
|
||||
} as Record<string, string>
|
||||
)[state] || state
|
||||
);
|
||||
}
|
||||
|
||||
stateClass(state: string): string {
|
||||
return (
|
||||
{
|
||||
alert: 'sp-al',
|
||||
freeze: 'sp-fr',
|
||||
inop: 'sp-in',
|
||||
dormant: 'sp-do',
|
||||
urgent: 'sp-fr'
|
||||
} as Record<string, string>
|
||||
)[state] || 'sp-al';
|
||||
(
|
||||
{
|
||||
alert: 'sp-al',
|
||||
freeze: 'sp-fr',
|
||||
inop: 'sp-in',
|
||||
dormant: 'sp-do',
|
||||
urgent: 'sp-fr'
|
||||
} as Record<string, string>
|
||||
)[state] || 'sp-al'
|
||||
);
|
||||
}
|
||||
|
||||
riskClass(risk: string): string {
|
||||
|
||||
Reference in New Issue
Block a user