Opens from the drawer's "More Details", replacing the placeholder toast.
The board swaps for a full-width lead record; "← Pipeline" goes back.
- Detail page: breadcrumb, hero (avatar, stage/type/storm/age pills,
Call + Email), stage progress bar + 7-step stepper, and an overview
grid of Contact / Property / Job Details / Insurance / Assignment.
- Move Stage dropdown so a lead can be re-staged from the detail page,
not only by dragging on the kanban board. Stage changes now route
through one setStage() used by both paths, so "reached" advancement
and the toast behave identically.
- Detail is keyed by lead id rather than a snapshot, so a stage move
updates the pills, progress, stepper and page accent live.
- pipeline-data: PLead gains phones, propertyType, source, tradeType,
urgency, insurance (null for Retail jobs) and assignment. All derived
deterministically from the existing rows — no Date.now, so SSR and
client render identically.
- Dropdown is a bottom sheet under 720px and an anchored menu above it;
dropped overflow:hidden on .pld-hero, which was clipping it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Resolve conflicts in dashboard.tsx and dashboard.css:
- Keep goutamnextflow's SDK inbox/messenger, settings, notifications,
realtime provider and smart gallery (the old messenger/inbox files
were deleted on that branch)
- Graft the feat/leads additions (Leads, Verify views + their CSS) on top
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Shared RealtimeProvider opens ONE dashboard-wide IIOS message socket reused by
the messenger tab and the new NotificationCenter. CrmMessagingAdapter gains
setFocus (drives presence/push suppression) and subscribeActivity (joins all
of the caller's threads, fans out incoming messages). NotificationCenter shows
a clickable toast on new messages when you're not on the messenger tab and
deep-links to the conversation. Pulls @insignia/iios-messaging-ui@0.1.7.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Topbar search box → debounced crm.search → dropdown of hits (chat/mail, highlighted
snippet). Clicking a hit switches to the right tab and focuses the exact thread:
mail → Inbox, chat → Messenger (via the SDK's new focusThreadId, 0.1.6). Snippet HTML
is escaped except the <em> highlight. Demo mode searches an in-memory set.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the SMTP 'coming soon' stub with a real card: host/port/SSL/user/password/
from-address/from-name → crm.settings.smtp.configure, masked status from
crm.settings.smtp.status. Mirrors the Twilio SMS card; demo mode stores hints locally.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
goutamnextflow adopts @insignia/iios-messaging-ui (drops the bespoke
messenger/inbox/mail) and adds Org Settings → Integrations. Resolve against
the Smart Gallery work:
- dashboard.tsx: route messenger→MessengerSdk, inbox→InboxSdk, add settings→
Settings (goutamnextflow) AND keep gallery→SmartGallery (ours). Drop the
now-deleted Messenger/Inbox imports.
- next.config.ts / package.json: union transpilePackages + deps (keep
@photo-gallery/sdk + ML deps AND @insignia/iios-messaging-ui).
- dashboard.css: keep both appended blocks (.gal* gallery + .settings-* org
settings).
Gallery integrates with zero errors. Vendored @photo-gallery/sdk re-synced
(0-diff). Verified: tsc clean + `next build` compiles the whole merged app
(gallery AI routes + dashboard). The new @insignia/iios-messaging-ui private
dep is stubbed locally (see .claude/dev-scripts); it resolves on CI/Vercel.
New Settings tab renders an Integrations section; the SMS (Twilio) card lets a
tenant admin connect their own Twilio account (Account SID / write-only Auth Token
/ E.164 from-number) via crm.settings.sms.configure, and shows the masked status
(from-number + SID last-4) from crm.settings.sms.status. Demo mode stores hints
locally. Email (SMTP) shown as the next provider on the same registry.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add Lead source dropdown options (Door Knock, Referral, Storm Chase,
Mailer/Postcard, Sign Call, Insurance Agent Referral, Repeat Customer,
Social Media, Other)
- Quick form: Referral shows a referral-note textarea; Door Knock shows a
canvasser search (by name or email) with picker + chip
- Full form is now a Next/Back wizard ending in Create Lead
- Reps gain email for canvasser search
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the bespoke in-CRM inbox with the SDK's <Inbox>, driven by a new
CrmInboxAdapter over the be-crm data door (crm.inbox.* + crm.mail.*).
Demo mode falls back to the SDK MockInboxAdapter. Maps --miu-* tokens for
.miu-inbox to the CRM theme.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The messenger tab now renders the shared SDK's <Messenger>, not the bespoke
in-CRM implementation. The CRM only supplies transport + theme:
- CrmMessagingAdapter implements the SDK's MessagingAdapter over the be-crm
data door (crm.messenger.conversation.list/open, history, send, directory);
live updates via a 4s poll for now (socket realtime is a follow-up that
reuses messenger-socket.tsx). Tenancy/auth stay server-side.
- messenger-sdk.tsx wires MessagingProvider + adapter (live = CrmMessagingAdapter,
demo = the SDK MockAdapter), themed by mapping --miu-* tokens to the CRM
design system.
- dashboard renders <MessengerSdk/>; the old messenger.tsx is left in place
for rollback and will be deleted once this is proven live.
NOTE: the SDK is installed from a local tarball (file:) for verification since
it isn't published yet. For deploy: publish @insignia/iios-messaging-ui to the
registry and change the dep to a version range. transpilePackages covers ESM.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Leads: card board with status stats, search + status tabs, a rich
lead-detail popup (contact, property, job, insurance, assignment,
storm banner) and a New Lead intake form (Quick / Full Form) with
multi-phone/email rows, site-photo dropzone and urgency picker.
Lead Verification: clickable stat tiles, status/source/assignee
filters, a full verification table, a detail popup with an activity
timeline, and a per-row actions menu (verify / reassign / pending…).
Both wired into the dashboard view switcher and styled with the
existing orange brand + glass-card system (dark & light themes).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The modal body is a flex child with overflow-y:auto but had no min-height:0,
so it refused to shrink below content height and pushed the footer past the
90vh cap (visible on the tall Group settings modal — the Done button was
clipped). Add flex:1 1 auto + min-height:0 so the body scrolls and the
footer stays pinned.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Per AppShell, email delivery lives in the domain API. Delete the frontend
/api/email/invite route + invite-email template, and the team-management email
wiring. be-crm now emails invitees on create/resend. Copy link stays as a
fallback (invite token still returned in the pending-invite list).
The invite link is token-only, so the landing page couldn't tell the invited
email or whether an account existed — it dumped everyone on an empty register
screen. Now it calls a public lookup (/api/invite/lookup → be-crm) and:
- first-time invitee → register with the email prefilled + locked;
- email already registered → sign in with the email prefilled;
- signed-in + registered → accept immediately; signed-in + no profile → onboarding.
Login now redeems the pending invite after sign-in (password/OTP/OAuth), so an
existing user's invite is accepted on login (not only when already logged in).
- POST /api/email/invite: sends the invite email via the Twilio Emails API using
server-only TWILIO_ACCOUNT_SID/TWILIO_AUTH_TOKEN (Vercel env), from
EMAIL_FROM_ADDRESS (default support@lynkedup.dev). Fixed invite template; gated
on a session cookie so it isn't an open relay.
- Team Management emails the invite on create and resend (token now returned by
both), with the Copy-link as a fallback. Mock mode skips email.
- Registration no longer asks for a role/persona (removed the role select +
allottee block); crm.account.register sends no persona.
- New users have no permissions → the sidebar now shows only Dashboard + Profile
for them, gated on crm.account.me (membership + permissions). Members see the
areas their permissions allow.
- Add /portal/invite?token=… : accepts the invite for a signed-in registered
user, or routes an unregistered invitee through register/onboarding, which
redeems the stashed token on completion (granting the invited role).
- Team Management: 'Copy link' on pending invites builds the invite link from
the invitation token (no email delivery yet).
Public, unauthenticated pages required for A2P 10DLC campaign verification:
- /sms-opt-in: web opt-in form (phone field, un-pre-checked consent checkbox,
message description, frequency, msg&data-rates + HELP/STOP disclaimers, links
to Terms & Privacy, 'Yes, sign me up!' submit).
- /privacy: Privacy Policy with the mandatory SMS clauses (no third-party/affiliate
sharing of mobile numbers or SMS consent, message frequency, rates disclosure).
- /terms: Terms of Service with an SMS program-terms section.
Business details centralized in legal-config.ts (replace SMS_SENDER with the
live Twilio number once approved).
/portal/onboarding is only a step in the Google sign-in flow. Redirect to
login unless the login page's onboard_email handoff hint is present (and the
session is authenticated), instead of showing an empty form on direct/typed
URL access. Hold rendering until the check passes to avoid a form flash, and
clear the hint once onboarding completes so it can't be reused.
After a Google sign-in with no CRM profile, route to /portal/onboarding — the
registration flow in mode='onboard': email skipped (Google-verified, prefilled
via getUserEmail), sets a password (updateUser) so email+password login also
works, skips the OTP-verify step, and persists the profile via crm.account.register.
Existing-profile users go straight to the dashboard. Bumps SDK ^0.2.3.
- Sidebar footer now shows the ACE identity (was static 'James Carter') with a
Sign-out menu; topbar user gets a Sign-out dropdown too. Both call useAuth().logout.
- Remove all visible 'Demo:' hints from login + register and the 'Demo mode' subtitle.
- team-management: new useTeamData() data layer serves live be-crm data door
(crm.team.member.search/role.list/invitation.list + set-roles/perm/invite
commands) or the mock fallback, gated on isShellConfigured(). A member can
hold MANY roles: role chips + multi-select picker in Edit/Invite modals.
- login OTP: OtpVerify wired to real Supabase email + SMS OTP (passwordless)
via appshell sendEmailOtp/verifyEmailOtp + sendPhoneOtp/verifyPhoneOtp.
- bump @abe-kap/appshell-sdk ^0.2.0 (phone OTP).
- dashboard sidebar now uses the --sidebar token so it turns white in
light mode instead of staying black; active nav item stays readable
- registration: drop the Property / Job ID step (job ID + find-by-address),
flow is now Account -> Verify -> Address with steps renumbered
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Replace roles with the 10 Construction Industry personas (Owner, Admin,
Sales Manager, Sales Rep, Project Manager, Site Supervisor, Canvasser,
Team Lead, Subcontractor, Other), each with description, attire &
appearance cues and a common-overlap note
- Render Attire & appearance + Common overlap sections on each role card
- Remap members/invites to new role ids; add canvasser, team-lead and
subcontractor members so every persona shows
- Set color-scheme per theme and style <select> options so the role
dropdown is legible in dark mode
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Flag emojis don't render on Windows, so derive an ISO code from the
emoji's regional indicators and load a flagcdn image in front of the
country-code selector (Account + Verify steps).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Team Management: crew hero, member gallery + list, role rings, invites
- Support Center: command-center Overview (live status, pulse ribbon, signal)
- AI Assistant: animated orb rings + textured stage
- Rules: rulebook cards (watermark, uniform orange), 3-up responsive grid
- Brand: --grad-brand now solid rgba(253,169,19,.92), white text/icons on
orange, no orange gradients; dark surfaces (--card-grad/--panel-2) #060608
- Segmented tabs get an on-brand orange active state
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Support Center overview rebuilt as a bento grid: large live-chat hero
tile, support team tile, mini channel tiles and a recent-tickets strip.
- Restore full workspace sidebar (Workspace/Team/Profile groups) with a
premium golden active state; unbuilt modules show a Coming Soon view.
- Use Western names across the UI (James Carter; Emma Wilson, Liam Foster,
Sophie Turner, Noah Mitchell) incl. tickets, threads, portal demo user.
- Remove the Allottee card from Profile; add a clean Account & identity
card and live-editable contacts.
- Relabel "Plot" -> "House number" everywhere; drop the allotment chip in
favour of the property category.
- Premium visual pass: brand gradients, depth, glow accents, pill tabs.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Full dashboard at /dashboard matching the Figma Linkedup-Web frame
- Dark/light theme toggle (persisted to localStorage)
- Live animated charts: stat sparkbars, P&L grouped bars, donut, gauge,
pipeline bars, progress, revenue-potential
- Sidebar, topbar, stat cards, weather, top sales reps
- 29 icons exported from Figma (currentColor) + lucide fallbacks
- Fix: bar charts had zero height (percentage in indefinite flex parent)
- Fix: removed content max-width that left a right-side gap
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>