3.7 KiB
3.7 KiB
Onboarding — Messaging/Inbox/Support Web SDK
Welcome. This is a static demo of a Slack-grade messaging + inbox + support product,
shipped as a React SDK (@lynkd/messaging-inbox-sdk) consumed by a Next.js demo app
(apps/web), styled to match the LynkedUp Pro dashboard. Read this first; deep dives are in
../docs.
Run it
pnpm install # Node >= 20, pnpm >= 8
pnpm dev # http://localhost:4300
No DB, no env setup needed — mock data ships in code and every feature works.
Mental model (read once, saves hours)
- UI is headless-first. Product logic lives in SDK hooks (
useMessages,useInbox,useTickets…). Components inapps/web/componentsare just presentation. - The UI never calls a backend directly. It calls
BffClient→ the BFF (apps/web/app/api/bff/**) → the mock store (apps/web/lib/mock/store.ts). This is the one seam you replace to go real. This is the BFF pattern. - Config is resolved once on the server (
apps/web/lib/config.ts→getServerConfig()) fromNEXT_PUBLIC_*env, then handed to the client provider as plain JSON. That's how feature flags + theme reach the browser without dynamicprocess.envaccess. - Theme = CSS variables.
theme.tswrites--c-*,--r-*,--font-*onto<html>. Tailwind colors map to those vars (tailwind.config.ts). Light/dark + brand swap are just different variable values.
Where things are
| I want to… | Go to |
|---|---|
| Add / change a domain type | packages/messaging-inbox-sdk/src/types.ts |
| Add a feature flag | packages/messaging-inbox-sdk/src/config.ts (FeatureFlags + defaultFlags) |
| Change default theme | packages/messaging-inbox-sdk/src/config.ts (darkTokens/lightTokens/defaultTheme) |
| Add a data hook | packages/messaging-inbox-sdk/src/hooks.ts |
| Add a BFF endpoint | apps/web/app/api/bff/<path>/route.ts + a method on store + a method on BffClient |
| Change seed data | apps/web/lib/mock/data.ts |
| Edit the sidebar/header | apps/web/components/nav/* |
| Edit a message/composer/thread | apps/web/components/message/* |
| Edit the Support console | apps/web/components/support/SupportView.tsx |
| Add a page/route | apps/web/app/(app)/<route>/page.tsx |
Add a feature end-to-end (worked example)
Say you want a /pins page listing pinned messages:
- Flag (optional): add
pinsPage: booleantoFeatureFlags+defaultFlags. - BFF: add
GET /api/bff/pinsreturningstore.messages.filter(m => m.isPinned). - Client: add
listPinned()toBffClient. - Hook: add
usePinned()inhooks.ts. - UI:
apps/web/app/(app)/pins/page.tsxrenders a list, gated byuseFeature("pinsPage").
Conventions
- Client vs server components: anything using SDK hooks/
useUineeds"use client". Pages are thin server components that render a client view component. - Styling: Tailwind utility classes + the semantic tokens (
bg-panel,text-muted,border-border,rounded-card,bg-accent). Don't hard-code hex — use tokens so light/dark + theming keep working. - Icons:
lucide-react. - Time: render relative/clock time with
lib/format.ts(client-only, avoids SSR drift).
Gotchas
- The Next.js version is pinned for the demo and has a known CVE — bump before real use.
- The mock store is in-memory: it resets on server restart (that's expected).
- Message timestamps are seeded relative to server start, so "just now / 4m" stays sensible.
Next
../docs/ARCHITECTURE.md— the full picture../docs/IIOS_INTEGRATION.md— make it real./memory/— durable project decisions (also loaded by Claude Code)