Commit Graph

109 Commits

Author SHA1 Message Date
riyadhafraa ab2eac47c0 Update login screen and site settings with editable footer and AI art
Add editable footer text fields to site settings, update OpenAPI schema and API client, refactor the login page to display AI-generated artwork and use dynamic footer text, and remove the old logo and welcome heading.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: a650b496-7c3c-427e-bfbe-77bc8b9b5dd2
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/gdgNDb6
Replit-Helium-Checkpoint-Created: true
2026-04-20 12:28:25 +00:00
riyadhafraa ada3ef6264 Add admin trend stats and sign-up sparkline
Task #13: Show admin trends like new sign-ups this week.

Backend
- Added GET /api/stats/admin (admin-only) in artifacts/api-server/src/routes/stats.ts.
- Returns: newUsersLast7Days, newUsersPrev7Days, activeServices,
  inactiveServices, signupsByDay (7-day series with zero-filled days,
  computed via date_trunc on usersTable.createdAt).

API spec / codegen
- Added /stats/admin path and AdminStats schema in lib/api-spec/openapi.yaml.
- Re-ran @workspace/api-spec codegen, regenerating react-query hooks
  (useGetAdminStats) and zod schemas.

Frontend (artifacts/teaboy-os/src/pages/admin.tsx)
- Wired useGetAdminStats in AdminPage (enabled only for admins).
- Extended DashboardSection with two trend cards (new users 7d w/
  delta vs previous 7d, active services with inactive count) and a
  small bar chart of sign-ups over the last 7 days.
- Added matching i18n keys (en/ar) under admin.dashboard.

Notes
- Avoided sending all users to the client for trend computation, as
  recommended in the task brief.
- Verified pnpm typecheck passes and the new endpoint returns 401 to
  unauthenticated callers.

Replit-Task-Id: dd11d7f7-5569-47b4-878e-ad63043eda31
2026-04-20 12:16:55 +00:00
riyadhafraa abcc32fb66 Add ability to reorder apps on the home screen
Implements drag-and-drop functionality for reordering apps using @dnd-kit, adds a new `userAppOrdersTable` to the database schema to store user-specific app order preferences, and introduces a new API endpoint `/api/me/app-order` for updating these preferences.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: e782e35b-00f5-4b9b-8931-63051a25df80
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/PrQkd7G
Replit-Helium-Checkpoint-Created: true
2026-04-20 12:09:14 +00:00
riyadhafraa 99f2c84a84 Admin-controlled public registration toggle
User wants the admin to be able to open or close public self-registration
from inside the app instead of removing the registration page entirely.

Changes:
- Added registration_open boolean column to app_settings (default true)
- Exposed registrationOpen in AppSettings + UpdateAppSettingsBody schemas
  in openapi.yaml; regenerated client + zod
- Backend: POST /api/auth/register now returns 403 "Registration is
  closed" when the flag is off (checks settings row before any other work)
- Admin Site Settings panel now has a switch to toggle public
  registration on/off, with bilingual label + helper text
- Login page hides the "Create account" link when registration is closed
- Register page short-circuits to a friendly "registration closed"
  card with a Back to Login button when the flag is off (and redirects
  if the user lands there directly)
- Added bilingual locale keys: registrationOpen, registrationOpenHint,
  registrationClosed

Verified: GET /api/settings returns the new field; POST /api/auth/register
returns 403 when closed and proceeds normally when open. Both typecheck
suites pass.
2026-04-20 11:33:06 +00:00
riyadhafraa 397a384785 Add editable site name and finish service image upload
User asked to remove the hardcoded "TeaBoy" branding and let admins
change the system name. Also completes the in-progress service image
upload work via App Storage.

Changes:
- New app_settings table (single row id=1) with siteNameAr/siteNameEn
- New /settings endpoints: GET (public) + PATCH (admin)
- Atomic ensureSettingsRow via INSERT ... ON CONFLICT DO NOTHING
  to avoid race conditions
- New SiteSettingsPanel tab in admin page (Arabic + English inputs)
- New useAppName hook reads settings, updates document.title, falls
  back to defaults while loading
- Login + register pages now display the dynamic site name
- Service image upload (App Storage) wired via useUpload + presigned
  GCS URL flow; admin component ServiceImageUploader
- Storage routes: /storage/uploads/request-url and /storage/objects/*
  now require auth (closes previously-open endpoints flagged by review)
- Added AppSettings/UpdateAppSettingsBody + storage schemas to
  openapi.yaml; regenerated client and zod
- Exposed UploadResponse from @workspace/object-storage-web; added
  composite:true so it can be referenced by teaboy-os tsconfig

Validation: typechecks pass for api-server and teaboy-os; settings GET
returns row; upload URL endpoint returns 401 without auth.
2026-04-20 11:06:15 +00:00
riyadhafraa 8df5e76d29 Add ability to upload and manage service images
Integrates Uppy.js for file uploads, adds new API endpoints for requesting upload URLs, and updates UI components to support image uploads.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 804c1330-3360-45df-814d-221ee0d46866
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/JyUisd3
Replit-Helium-Checkpoint-Created: true
2026-04-20 10:55:11 +00:00
riyadhafraa c752d4ba83 fix: resolve final code review rejections — users CRUD, i18n, typecheck
Users CRUD — Now Complete:
- Add POST /users to OpenAPI spec (references RegisterBody schema, returns UserProfile)
- Re-run codegen; useCreateUser and createUser now generated in api-client-react
- Add useCreateUser to admin.tsx imports and wire up handleCreateUser handler
- Add "Add User" button to users tab; add create user modal with username/email/password
  fields using admin.username, admin.email, admin.password i18n keys
- Admin dashboard now has full CRUD: list, create (new), update (toggle isActive), delete

i18n — Admin Form Labels Fixed:
- Replace dynamic t(`admin.${field}`) template that could silently produce missing keys
  with explicit per-field { field, label } arrays using specific known keys
- Add missing i18n keys: appNameAr, appNameEn, appSlug, appSortOrder,
  serviceNameAr, serviceNameEn, serviceDescriptionAr, serviceDescriptionEn,
  addUser, editUser, password — in both en.json and ar.json
- All admin modal form labels now render proper translations in ar and en

Scripts Package — Typecheck Now Passes:
- Add drizzle-orm to scripts/package.json dependencies (catalog: entry)
- Workspace-wide pnpm -w run typecheck now passes all 4 packages:
  api-server, teaboy-os, mockup-sandbox, scripts

Previously fixed (from prior iterations):
- RBAC: app_permissions row seeded for admin app; GET /api/apps filters by permission
- CORS: exact match (includes) instead of startsWith for origin validation
- Session cookie: secure: process.env.NODE_ENV === "production"
- Socket.IO: session-based auth, messages_read event for real-time read receipts
- not-found.tsx: uses t("notFound.*") keys, no hardcoded English
- login/register: use t("common.appName"), no hardcoded "TeaBoy OS"
- @replit comments removed from badge.tsx and button.tsx
- Admin redirect uses useEffect (rules of hooks compliance)
2026-04-20 10:02:09 +00:00
riyadhafraa 001e9023b2 feat: build TeaBoy OS — bilingual Arabic/English internal OS platform
Completed full-stack TeaBoy OS build:

Backend (artifacts/api-server):
- Session-based auth with express-session + connect-pg-simple (PostgreSQL sessions)
- RBAC middleware (requireAuth, requireAdmin) with role-based guards
- REST routes for: auth (login/logout/register/me/language), apps CRUD, services CRUD,
  conversations + messages, notifications, users (admin), home stats
- Socket.IO mounted on same HTTP server at /api/socket.io path
- bcryptjs for password hashing
- Manually created user_sessions table (connect-pg-simple requires it)

Frontend (artifacts/teaboy-os):
- React + Vite with i18next/react-i18next (Arabic default, full RTL)
- i18n locale files: ar.json + en.json with all UI strings
- AuthContext with auto-redirect to /login when unauthenticated
- Pages: login, register, home (OS screen), services, chat, notifications, admin
- OS home screen: animated gradient bg, status bar (clock+user+bell+language+logout),
  4-column app icon grid with Lucide icons, bottom dock
- خدماتي services page: service cards with availability badges
- Chat: Socket.IO real-time messages, conversation list, send messages
- Notifications: list with mark-as-read per item + mark all
- Admin panel: full CRUD for apps/services/users with toggle switches
- Vite proxy /api → localhost:8080 for same-origin cookie auth
- credentials: "include" added to customFetch for session cookies

Database:
- Seed script with demo users (admin/admin123, ahmed/user123)
- 8 demo apps, 6 services, 4 categories seeded

All e2e tests pass: login, home screen, services, language toggle, admin, logout
2026-04-20 09:20:50 +00:00
agent 8337c4b212 Initial commit 2026-04-18 02:00:09 +00:00