Temă
Public site (apps/site)
React 19 + React Router 8 + TanStack Query 5, built with Vite 8. Same design as the prototype: its stylesheet is reused unchanged (src/styles/site.css) and the components render the same markup; additions.css only adds what the prototype did not have (tabs, notices, skeletons, pager).
Pages and URLs
All paths are English and resource-oriented; the single source is SITE_PATHS / siteRoutes in packages/shared/src/routes.ts, used by the SPA router, every link, and the API (emails, notifications).
| URL | Page |
|---|---|
/ with ?q=&category=&minPrice=&maxPrice=&condition=very-good&county=&delivery=1&sort=price-asc&page=2 | Listings: filters, chips, sorting, pages, "save search" |
/listings/:slug | Product: gallery, details, seller, similar listings, message, offer and report dialogs |
/listings/new, /listings/:id/edit | Post / edit a listing: photo upload (drag & drop, order, cover), live preview, checklist, drafts |
/account/listings (`?tab=review | sold |
/messages, /messages/:conversationId | Inbox and conversation: offers, counter-offers, quick replies (refreshed every few seconds) |
/notifications | Notifications, mark read |
/checkout/:listingId (?offer= for an accepted offer) | Delivery (courier / easybox), simulated card or cash on delivery, live total |
/account/orders (?role=selling), /account/orders/:code | Purchases and sales: timeline, AWB, ship / confirm / cancel, review |
/listings/:id/promote | Promotion packages (5 / 19 / 39 lei by default), simulated card payment |
/favorites (?tab=searches) | Saved listings and saved searches |
/sellers/:id | Public seller profile |
/login (`?mode=register | forgot-password&next=`) |
/reset-password?token=, /verify-email?token= | Targets of the email links |
/account/settings (#profile, #security, #notifications, #payout, #privacy) | Profile, password, notification switches, marketing consent (with evidence), payout IBAN, GDPR export (GET /api/account/export) and account deletion |
/help, /safety, /how-it-works | FAQ with search and topics; content pages from the prototype, translated |
/legal/terms, /legal/privacy, /legal/cookies, /legal/posting-rules | Legal documents (models: to be checked by a lawyer before launch) |
/contact | Opens a real support ticket; confirmation email with its code |
/promote | Promotion for the first active listing (same page as /listings/:id/promote) |
Filters live in the URL, so results can be shared, bookmarked and navigated with the back button.
Structure
src/api/ GraphQL queries and TanStack Query hooks (catalog.ts, session.tsx), response types
src/features/ one folder per area: listing, product, favorites, seller, auth, misc
src/layout/ header, category bar, drawer, footer, bottom navigation, error boundary
src/lib/ formatting (prices, relative time, Romanian plurals), error messages, toasts
src/i18n/ catalog.json (864 texts converted from the prototype) + catalog-react.ts (texts added in React)
src/ui/ icon sprite (the prototype's 30 icons + theme/language icons)Languages
@taraba/ui provides I18nProvider / useI18n(): Romanian text is the key, t('3 anunțuri') finds {n} anunțuri in the catalogue and puts the number back. Content written by people (titles, descriptions, seller-written specifications) is marked translate="no" and never translated. In the browser console, __tarabaMisses() lists texts shown on screen that have no translation yet.
Known follow-ups
- The bundle is ~600 KB (≈170 KB are the five translations); load only the selected language later.
- Fonts come from Google Fonts (allowed by the CSP); self-host them before going public.
Trust and discovery (later slice)
| URL | What |
|---|---|
/categories/:slug | Category landing page (indexable); other filters stay in the query string |
/account/settings#profile | Profile photo (square, metadata removed) and phone verification by SMS code |
/account/settings#identity | Identity verification: photo of an ID card, passport or driving licence, checked by the team, deleted after the decision |
/sellers/:id | Shows "Telefon verificat" / "Identitate verificată" and "Raportează utilizatorul" |
/account/disputes | The person's disputes as buyer or seller, with status, outcome and the seller's answer form |
/about, /careers, /press | Institutional pages |
/robots.txt, /sitemap.xml, /sitemap-N.xml | Generated by the API (/seo/...) from the live data and PUBLIC_SITE_URL |
Backoffice: /identity (needs the verify_identity permission: admin, moderator, support), profile photo removal on the user card, user reports in "Raportări și dispute". CRM: segment fields "Telefon verificat", "Identitate verificată".