Notifications
{{ pushError }}
Desktop alerts fire while AMS is open in a tab, including minimised. Push reaches you with AMS fully closed — on iPhone, add AMS to your Home Screen first.
No notifications
Account Hub
{{ activeClients.length }}
+{{ sunsetClientCount }} sunset
Overdue
{{ getTaskCountByUrgency('Overdue') }}
Urgent Pipeline
{{ getTaskCountByUrgency('Urgent') }}
{{ currentUserRole === 'Admin' ? 'Collected YTD' : 'Collected WTD' }}
£{{ currentUserRole === 'Admin' ? calculatePaidInvoicesYTD() : calculatePaidInvoicesWTD() }}
Pipeline Eff.
{{ calculatePipelineEfficiency() }}%
Live Team Attendance
Live Real-Time| Staff | Current Status | Status Duration | Total Productive |
|---|---|---|---|
| {{ getStaffName(shift.userId) }} | {{ shift.status }} | {{ shift.durationDisplay }} | {{ formatSecondsToTime(shift.totalWorkSeconds || 0) }} |
| No active staff shifts found right now. | |||
Attendance & Productivity
Live Team Performance Metrics
Live Team Capacity
{{ metric.name }}
{{ metric.totalProdHours }}H Prod.
Cumulative Productive Hours (Uptick)
Time Analysis (Session Duration)
Financial Health (Inv Count)
Urgency Analysis (Deadlines)
Workflow Capacity (Total Active)
Staff Productivity (Breakdown)
Recent Task Operations
{{ formatDate(log.createdAt) }}
{{ log.action }}
{{ log.context }}
Op: {{ log.staffName }}
Staff Activity Feed
{{ formatDate(log.createdAt) }}
{{ log.action }}
{{ log.context }}
Staff: {{ log.staffName }}
| Account Name | Status | Account Handler | Phone | Active HMRC Services | Completed Work | Docs | Actions |
|---|---|---|---|---|---|---|---|
{{ client.name }} {{ client.company || 'Private' }} |
{{ isSunsetClient(client) ? 'Sunset' : 'Active' }}
Retired {{ formatDeadline(client.sunsetAt) }}
|
{{ getStaffName(client.accountHandlerId) }} | {{ client.phone || '—' }} |
{{ s.serviceType }}
|
{{ getClientCompletedTasks(client.id).length }} Tasks Done
{{ getClientCompletedTasks(client.id).map(t => t.serviceType).join(', ') || 'No history' }}
|
Account Links {{ linkDisplayLabel(link) }} {{ link.url }} |
Compliance Pipeline
Recurring statutory obligations only. Ad-hoc work lives in , inbound work in .
Overdue
{{ countByUrgency(compliancePipeline, 'Overdue') }}
Urgent (<= 2d)
{{ countByUrgency(compliancePipeline, 'Urgent') }}
Due (3-15d)
{{ countByUrgency(compliancePipeline, 'Pending') }}
Upcoming (16d+)
{{ countByUrgency(compliancePipeline, 'Upcoming') }}
Pipeline Clear
No compliance tasks match the current filters.
| Client | Service / Period | Deadline | Internal | Status | Personnel | Action |
|---|---|---|---|---|---|---|
|
{{ getTaskDisplayName(task) }}
Handler: {{ getStaffName(getClient(task.clientId).accountHandlerId) }}
|
{{ task.serviceType }}
{{ periodKeyLabel(task.periodKey) }}
|
{{ formatDeadline(task.filingDeadline) }}
{{ deadlineDistanceLabel(task) }}
|
{{ formatDeadline(task.internalDeadline) }} | {{ task.status }} {{ getTaskPriority(task) }} | {{ getStaffName(task.assigneeId) }} |
Admin Tasks
Internal one-off work. These never recur and are completed permanently.
Overdue
{{ countByUrgency(adminTasks, 'Overdue') }}
Urgent
{{ countByUrgency(adminTasks, 'Urgent') }}
Unassigned
{{ adminTasks.filter(t => !t.assigneeId).length }}
Total Open
{{ adminTasks.length }}
{{ task.serviceType }}
{{ task.description }}
{{ formatDeadline(task.filingDeadline) }}
{{ deadlineDistanceLabel(task) }}
Drop here
No Admin Tasks
Nothing matches the current filters.
{{ task.serviceType }}
{{ getTaskPriority(task) }}{{ getTaskDisplayName(task) }} · {{ task.description }}
{{ formatDeadline(task.filingDeadline) }}
{{ deadlineDistanceLabel(task) }}
| Client | Task | Due | Priority | Status | Assigned | Action |
|---|---|---|---|---|---|---|
{{ getTaskDisplayName(task) }} |
{{ task.serviceType }}
{{ task.description }}
|
{{ formatDeadline(task.filingDeadline) }}
{{ deadlineDistanceLabel(task) }}
|
{{ getTaskPriority(task) }} | {{ task.status }} | {{ task.assigneeId ? getStaffName(task.assigneeId) : 'Unassigned' }} |
|
Client Requests
Inbound submissions from the public request form. Match each one to an account, then turn it into work.
Share this with clients
{{ publicRequestUrl }}
Awaiting Client Approval
{{ d.formTitle }}
{{ d.clientName }} · sent by {{ d.createdByName }}
When a client approves, an Admin Task is created automatically.
New Submissions
{{ req.subject }}
{{ req.name }} · {{ req.company }}
{{ req.detail }}
{{ answer.label }}
{{ formatRequestAnswer(answer.value) }}
In Progress
{{ task.serviceType }}
{{ getTaskDisplayName(task) }}
Inbox Clear
Nothing waiting. New submissions from the request form land here.
Recurring Schedules
Each schedule generates one Compliance Pipeline task per period. Filed periods are kept permanently.
No Schedules
Schedules are created automatically when you assign a service to a client, or add one manually.
| Client | Service | Frequency | Next Due | Filed | State | Action |
|---|---|---|---|---|---|---|
{{ getClientName(sch.clientId) }} |
{{ sch.serviceType }} | {{ FREQUENCY_LABELS[sch.frequency] || sch.frequency }} | {{ formatJsDate(scheduleNextDue(sch)) }} | {{ scheduleFiledCount(sch) }} | {{ sch.active === false ? 'Paused' : 'Active' }} |
|
Monthly Targets
Set what each client should get this month. Progress is read live from the Compliance Pipeline and Admin Tasks — targets never hold their own copy of the work.
Target Month
{{ monthKeyLabel(targetMonth) }}
Targets Set
{{ targetSummary.total }}
Complete
{{ targetSummary.complete }}
At Risk
{{ targetSummary.atRisk }}
Missed
{{ targetSummary.missed }}
No Targets for {{ monthKeyLabel(targetMonth) }}
Set a target to commit to a piece of work for a client this month. Matching tasks in the pipeline light it up automatically.
| Client | Service | Deadline | Owner | Progress | State | Actions |
|---|---|---|---|---|---|---|
|
{{ getClientName(t.clientId) }}
{{ getClient(t.clientId)?.company || 'Private' }}
Client sunset
|
{{ t.serviceType }} |
{{ formatDeadline(t.deadline) }}
{{ deadlineDistanceLabel({ filingDeadline: t.deadline }) }}
|
{{ t.assigneeId ? getStaffName(t.assigneeId) : 'Unassigned' }} |
{{ targetProgress(t).filed }}/{{ targetProgress(t).total }} filed
{{ targetProgress(t).percent }}%
No matching work yet. {{ t.notes }} |
{{ targetState(t) }} |
|
Completed Tasks Archive
Review filed and completed assignments per individual.
| Client Account | Task / Service | Type | Date Completed | Action |
|---|---|---|---|---|
| {{ task.clientName }} | {{ task.taskName }} | {{ task.type }} | {{ formatDate(task.dateCompleted) }} | Archived |
| Please select a staff member above to view history. | ||||
| No completed tasks found for this timeframe. |
Time Recorder
Professional Time Tracking
Shift Totals
Activity Log
| Time | Event |
|---|---|
| {{ formatDateOnlyTime(log.timestamp) }} | {{ log.type }} |
Team Workload Distribution
Active Task Allocation Per Staff Member
{{ data.member.name }}
{{ data.member.role }}
{{ data.activeTasks.length }}
Active Tasks
Pending
{{ data.stats.pending }}
In Progress
{{ data.stats.inProgress }}
Auditing
{{ data.stats.auditing }}
Filed
{{ data.stats.filed }}
{{ getTaskDisplayName(task) }}
{{ task.serviceType }}
Handler Oversight
Staff Schedule Monitor
Detailed Time Estimation & Completion Status
{{ member.name }}
{{ member.role }}
Active Assignments
{{ getMemberTasks(member.id).length }}
| Task Details | Schedule (Est. vs Actual) | Percentage Completion | Efficiency |
|---|---|---|---|
|
{{ getTaskDisplayName(task) }}
{{ task.serviceType }}
|
Target {{ task.estimatedHours || 0 }}h Actual {{ formatSecondsToHours(task.timeSpent) }} |
{{ task.completionPercentage || 0 }}% Done
|
No Estimate Set
On Track
Over Time
|
My Assignments
Focus Mode • {{ myPersonalTasks.length }} Active Tasks
| Client | Service | Deadline | Status | Action |
|---|---|---|---|---|
{{ getTaskDisplayName(task) }} Oversight (Assigned to: {{ getStaffName(task.assigneeId) }}) | {{ task.serviceType }} | {{ formatDate(task.filingDeadline) }} | {{ task.status }} | |
| No tasks currently assigned to you. | ||||
Monthly Target
Awaiting funds (Total)
£{{ calculatePendingInvoices() }}
Awaiting funds (WTD)
£{{ calculatePendingInvoicesWTD() }}
Overdue (Arrears)
£{{ calculateOverdueInvoices() }}
Collected Revenue (YTD)
£{{ calculatePaidInvoicesYTD() }}
Collected Revenue (WTD)
£{{ calculatePaidInvoicesWTD() }}
Weekly Target
| Serial | Account Profile | Net Value | Status | Control |
|---|---|---|---|---|
| {{ inv.invoiceNumber || inv.id }} |
{{ inv.clientName }}
Due: {{ formatDate(inv.date) }} (Overdue)
|
£{{ (parseFloat(inv.amount) || 0).toFixed(2) }} | {{ inv.status || 'Draft' }} | |
| No invoices found matching current filters. | ||||
Staff Shift Management
Admin Control Panel
{{ staff.name }}
{{ staff.role }}
Current Status Duration
Practice Reporting
Live figures across the whole practice. Derived from data already loaded — reading this page costs nothing.
Open Work
{{ reportKpis.open }}
Overdue
{{ reportKpis.overdue }}
Unassigned
{{ reportKpis.unassigned }}
Filed / {{ reportPeriodLabel }}
{{ reportKpis.filed }}
Avg Turnaround
{{ reportNum(reportKpis.avgTurnaround, 'd') }}
Filed On Time
{{ reportNum(reportKpis.onTime, '%') }}
Completed-work figures cover the most recent 150 filings only — that cap is deliberate, and keeps your Firestore read costs down. {{ reportCoverage.undated }} filed task(s) predate completion timestamps, so they are excluded from turnaround and on-time figures.
Throughput
Tasks filed per month
Overdue Ageing
How long missed deadlines have been sitting
Open Work by Type
Staff Scorecard
Open load now, plus everything filed in the selected window
| Staff | Open | Overdue | Filed | Avg Days | On Time |
|---|---|---|---|---|---|
|
{{ staffInitials(r.id) }}
{{ r.name }}
|
{{ r.open }} | {{ r.overdue }} | {{ r.filed }} | {{ reportNum(r.avgTurnaround, 'd') }} | {{ reportNum(r.onTime, '%') }} |
| No activity in this window. | |||||
By Service Line
Sorted by overdue exposure
| Service | Open | Overdue | Filed | Avg |
|---|---|---|---|---|
| {{ r.name }} | {{ r.open }} | {{ r.overdue }} | {{ r.filed }} | {{ reportNum(r.avgTurnaround, 'd') }} |
| Nothing to report. | ||||
Client Exposure
Top 10 accounts by outstanding work
| Account | Open | Overdue |
|---|---|---|
| {{ r.name }} | {{ r.open }} | {{ r.overdue }} |
| No open work. | ||
Raw Data Exports
For spreadsheets, pivot tables and third-party systems
Personnel Directory
Manage team access and system roles.
| Personnel | System Access | Enrolled Since | Control |
|---|---|---|---|
|
{{ user.name }}
{{ user.email }}
|
{{ user.role }} | {{ formatDate(user.createdAt) }} |
Audit Trail
System-wide operations and tracking.
| Personnel | Operation | Context | Timestamp |
|---|---|---|---|
| {{ log.staffName }} | {{ log.action }} | {{ log.context }} | {{ formatDate(log.createdAt) }} |
| No activity logs found for this selection. | |||
Message sync problem
{{ chatError }}
Calling unavailable
{{ callSystemError }} Paste the updated firestore.rules into Firebase Console → Firestore Database → Rules. Chat is unaffected.
Messages
{{ availableChats.find(c => c.id === activeChatId)?.name || 'Select a chat' }}
Secure End-to-End Connection
Showing the most recent {{ chatMessages.length }} messages. Older history is not loaded to keep the database reads down.
Beginning of conversation
System Notifications
Enter your Google Chat Incoming Webhook URL here.
Daily · in-app calls
Calling a teammate rings them inside AMS and opens a private, single-use room in a floating panel — no new tab and no third-party sign-in. A fresh room is created for every call and expires afterwards, so links can never be reused.
Nothing to configure. The API credential lives as an encrypted Cloudflare environment variable and never reaches the browser.
{{ dailySdkReady ? 'In-app calling ready' : 'In-app calling unavailable' }}
The Daily video SDK did not load in this browser, so calls will open in a new tab instead of the floating panel. An ad-blocker, privacy extension or network policy blocking unpkg.com is the usual cause — allow it for this site and reload.
Calls will open in the floating panel inside AMS.
Email provider
Assignees, the person who raised the item, and every administrator are emailed when a task is assigned, when its status changes, when a deadline is close or missed, and when a client requests a call.
Email alerts are not sending
{{ emailAlertError }}
The sending credential lives as an encrypted Cloudflare environment variable and never reaches the browser. A problem with sending will be reported here.
Alerts never go to the person who caused them. If you are the assignee, the person who raised it and the only administrator, a real action emails nobody at all — so use this to test.
{{ emailTestResult }}
Most recent alert
{{ lastEmailOutcome }}
No email address on file
{{ staffMissingEmail.join(', ') }} — these people are skipped by every email alert. Add an address on their record in Personnel.
Deadline reminders
A deadline is counted down over the five days before it lands — in 5 days, in 4 days, down to tomorrow and today — then daily once it is late.
Once more than 10 tasks are in either group, the individual emails stop and one digest goes to administrators instead, naming the total and the worst offender. Forty late tasks should not mean forty emails.
Swept hourly from an open AMS session, so it needs somebody to have AMS open that day. Each task raises at most one email per day however many people are signed in.
End-of-week report
Every Friday, administrators get one email covering the week: how many actions were recorded, what was completed, what is open and overdue, a breakdown by type of work, and how much each person did.
Counted from the audit trail rather than the task lists, so a busy week is not under-reported. If nobody opens AMS on the Friday, the report is sent on the next day someone does — it is delayed, never skipped.
Play each cue on demand, without waiting for a message or placing a call. If these are silent the problem is your volume, your browser, or the mute toggle in the header — not AMS.
{{ soundEnabled ? 'Alert sounds are on.' : 'Alert sounds are MUTED — nothing will play until you unmute using the speaker icon in the header.' }}
Requested Calls
Clients who have asked to speak to someone. Log the request when it comes in, then close it out once the call has happened.
Waiting on you
{{ myCallRequests.length }} {{ myCallRequests.length === 1 ? 'client is' : 'clients are' }} waiting for a call from you.
No open call requests
{{ req.clientName }}
for {{ req.requestedForName }}
{{ req.reason }}
Client Form Builder
Select a form to fill in and send to a client, or create a new one.
No forms yet
{{ form.title }}
{{ form.questions?.length || 0 }} questions
Fill & Send to Client
Select a form on the left to pre-fill it and send an approval link to a client.
Fill & Send
{{ dispatchForm.formTitle }}
Approval Link Ready
Send this to the client. Their approval automatically creates an Admin Task.
{{ selectedDispatchClient.name }}
Pre-fill answers (optional — client can complete/correct)
System Confirmation
{{ notification }}
Set Your Password
You signed in with a temporary password set by your administrator. Choose your own to continue.
{{ confirmDialog.title }}
{{ confirmDialog.message }}
Gateway Access
{{ authBusyMessage }}
Please wait
{{ busyMessage || 'Saving changes...' }}
Start Team Meeting
Enter your Google Meet link below to notify all active staff.
Shift Ended
Your session has been logged. What would you like to do next?
Shift Check-In
Please confirm your attendance to access the portal workspace.
Current Time
{{ new Date().toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}) }}
{{ isEditingClient ? 'Modify Profile' : 'New Client Registration' }}
Basic Info & Management
Give each link a label — Google Drive, Payroll folder, HMRC portal — and staff can attach the right one to an admin task. Rows left blank are discarded on save.
Account is {{ clientForm.status === 'sunset' ? 'sunset' : 'active' }}
{{ clientForm.status === 'sunset' ? 'Retired, not deleted. History, filings and invoices are intact; recurring schedules are paused and Monthly Targets will not accept this client.' : 'Sunsetting keeps every record and pauses the recurring schedules, so the account stops attracting new work without leaving the system.' }}
Tax & Login Details
HMRC Services Config
Completed Work History
| Work | Type | Filed |
|---|---|---|
| {{ item.serviceType }} | {{ TASK_KIND_META[item.kind]?.label || 'Task' }} | {{ formatDeadline(item.date) }} |
| No completed work recorded for this account yet. | ||
{{ getClient(selectedTask.clientId)?.name }}
{{ getClient(selectedTask.clientId)?.company || 'Private Account' }}
Account Handler
{{ getStaffName(getClient(selectedTask.clientId).accountHandlerId) }}
Tracked Time
Completed task is read-only
Compliance Identity
UTR Reference
{{ getClient(selectedTask.clientId)?.utr || '—' }}
NI Number
{{ getClient(selectedTask.clientId)?.nino || '—' }}
Gateway Access
User ID
{{ getClient(selectedTask.clientId)?.gatewayId || 'Pending' }}
{{ (selectedTask.clientLinks || []).length ? 'Attached Links' : 'Account Links' }}
Counts Towards Target
{{ getTarget(selectedTask.targetId).serviceType }}
{{ monthKeyLabel(getTarget(selectedTask.targetId).month) }} · due {{ formatDeadline(getTarget(selectedTask.targetId).deadline) }}
{{ targetProgress(getTarget(selectedTask.targetId)).percent }}% · {{ targetState(getTarget(selectedTask.targetId)) }}
Client Uploads
Staff Uploads
Select several at once · up to 15MB each
{{ selectedTask.serviceType }}
Read-only for completed tasks
Priority can raise a task's urgency but never hides an approaching deadline.
Matching work is picked up automatically; link it here only if it should count towards a different target.
{{ selectedTask.description }}
Internal Notes
{{ segment.text }}{{ segment.text }}
Type @ followed by a team member's name
Create Ad-hoc Task
Selected: {{ selectedDailyLogClient.name }} — {{ selectedDailyLogClient.company }}
Can't find them?This account is sunset
It has been retired from active service. You can still raise closing-down work against it, but it cannot be given a Monthly Target until it is reactivated in the Accounts Hub.
This account has no saved links yet.
New account link
{{ dailyLogLinkError }}
No Monthly Targets set for this account. Create one under Monthly Targets to track progress.
{{ formTemplate.id ? 'Edit Form' : 'New Client Form' }}
{{ isEditingInvoice ? 'Modify Billing' : 'Record Transaction' }}
{{ selectedInvoiceClient.name }}
{{ selectedInvoiceClient.company || 'Private Client' }}
Start typing to find a client or company.
Register Personnel
{{ scheduleForm.id ? 'Edit' : 'New' }} Recurring Schedule
Generates one pipeline task per period
Every following period is calculated from this date.
Update available
A newer version of AMS is live. This tab will update itself as soon as you are not in the middle of something — or take it now.
{{ callPanelPeer }}
Connecting {{ callDuration }}
{{ callPanelError }}
Starting audio
Incoming call
{{ incomingCall.fromName }}
Answering opens the meeting room in a new tab.
Calling
{{ outgoingCall.toName }}
Their AMS will ring for {{ 45 }} seconds. The room opens automatically when they answer.
Join the room nowLog a Call Request
A client has asked to speak to someone. Record it here and they will be notified straight away.
{{ targetForm.id ? 'Edit' : 'New' }} Monthly Target
Progress is tracked from the real work
Selected: {{ selectedTargetClient.name }}
{{ selectedTargetClient?.name }} is sunset
This account has been retired from active service, so it cannot be added to the targets list. Reactivate it first if the work really is going ahead — everything on the record is still there.
The target turns "at risk" five days out and "missed" once it passes unfinished.
How progress is counted
Any Compliance Pipeline or Admin Task for this client, with a matching service and a deadline inside this month, is picked up automatically. You can also pin a task to this target from the task itself, or raise one straight from the targets list.
Access Control
{{ editingPermissionsUser?.name }}
Financial Viewer
Can view WTD Pending and WTD Revenue stats only.
Billing Manager
Full Billing Access. Can edit Monthly/Weekly Targets.
Shift Supervisor
View Live Dashboard, Manage Staff Shifts, Call Meetings.
Compliance Officer
Access to full Audit Trail and System Logs.
Account Manager
Can Delete Clients and Tasks (Dangerous).