Files
SweetHomeWeb/full-project-analysis.md

22 KiB

SweetHome — Full Project Analysis

Project: SweetHome Next.js Real Estate Application Date: June 16, 2026 Framework: Next.js 16.1.6 (App Router) + React 18.3.1 Language: JavaScript (no TypeScript) Styling: Tailwind CSS v4 + DaisyUI (unused) + Flowbite (unused) API: Custom .NET backend at https://45.93.137.91.nip.io/api


1. Project Structure

Directory Tree (Top 3 Levels)

SweetHome/
├── .gitea/workflows/            # CI/CD deployer
├── app/                         # ★ MAIN APP (112 source files)
│   ├── account-verification/    # OTP email/phone verification
│   ├── auth/choose-role/        # Owner/Tenant/Agent role picker
│   ├── blocked/                 # Blocked account page
│   ├── booked-properties/       # User's booked properties
│   ├── change-password/         # Change password form
│   ├── components/              # ★ 14 reusable components
│   │   ├── home/                # HeroSearch, PropertyMap
│   │   ├── property/            # BookingCalendar, PropertyMap
│   │   ├── ratings/             # StarRating, PropertyRatingForm, etc.
│   │   ├── BottomNav.js         # Mobile bottom nav
│   │   ├── FloatingSidebar.js   # Desktop floating sidebar
│   │   ├── NavLinks.js          # Nav link atoms
│   │   ├── NotificationHandler.js # Firebase FCM handler
│   │   └── PropertyMapWithMarkers.js # Standalone Leaflet map
│   ├── contexts/                # ★ 3 context providers
│   │   ├── FavoritesContext.js
│   │   ├── NotificationsContext.js
│   │   └── PropertyContext.js   # ORPHANED (never mounted)
│   ├── enums/                   # 20 enum constant files
│   ├── faq/                     # FAQ accordion page
│   ├── favorites/               # Favorites list page
│   ├── forgot-password/         # 3-step forgot password
│   ├── i18n/                    # i18next config (Arabic/English)
│   ├── login/                   # 2-step login (credential + OTP)
│   ├── my-rates/                # Ratings received from owners
│   ├── notifications/           # Notifications list page
│   ├── onboarding/              # 3-step intro wizard
│   ├── owner/                   # ★ Owner dashboard (6 sub-routes)
│   │   ├── account-book/        # Financial dashboard
│   │   ├── bookings/            # Booking management
│   │   ├── calendar/            # Monthly calendar view
│   │   ├── profits/             # Revenue/profit stats
│   │   ├── properties/          # CRUD property management
│   │   └── reservations/        # Reservation requests
│   ├── payments/                # Deposit payment page
│   ├── privacy/                 # Privacy policy
│   ├── profile/                 # User profile CRUD
│   ├── properties/              # Property listings grid
│   ├── property/[id]/           # Property detail (dynamic route)
│   ├── register/                # Registration (tenant/owner/agent)
│   ├── reports/                 # 3-tab report submission
│   ├── reservations/            # Customer reservations
│   ├── services/                # AuthService.js
│   ├── settings/                # Account settings
│   ├── support/                 # Support contact form
│   ├── terms/                   # Terms of service
│   ├── utils/                   # ★ api.js, calculations, firebase, etc.
│   ├── ClientLayout.js          # Client layout shell (804 lines)
│   ├── layout.js                # Root server layout
│   ├── globals.css              # Tailwind + custom fonts
│   ├── page.js                  # Home page
│   ├── error.js                 # Error boundary
│   ├── loading.js               # Loading state
│   └── not-found.js             # 404 page
├── public/                      # Static files (fonts, images, APK)
│   ├── files/SweetHome.apk      # Android APK
│   ├── fonts/                   # Madani Arabic (woff2 + ttf)
│   └── firebase-messaging-sw.js # FCM service worker
├── package.json                 # 18 prod + 7 dev dependencies
├── next.config.mjs              # Next.js config
├── postcss.config.mjs           # PostCSS + Tailwind
├── jsconfig.json                # Path aliases (@/* → ./)
└── security-audit-report.md     # Previous security audit

Route Summary (33 pages)

Type Routes Count
Public /, /login, /register/*, /forgot-password, /auth/choose-role, /properties, /property/[id], /terms, /privacy, /faq, /support, /onboarding 14
Protected (auth only) /profile, /settings, /change-password, /account-verification, /favorites, /booked-properties, /reservations, /notifications, /payments, /my-rates, /reports, /blocked 12
Owner only /owner/properties, /owner/properties/add, /owner/reservations, /owner/bookings, /owner/calendar, /owner/profits, /owner/account-book 7

2. Architecture Overview

Layout Hierarchy

app/layout.js (Server Component — root HTML, fonts, metadata)
  └── app/ClientLayout.js (Client Component — 804 lines)
        ├── <NotificationsProvider>     (context)
        │   └── <FavoritesProvider>     (context)
        │       └── <main>{children}</main>
        ├── <BottomNav />               (mobile, authenticated only)
        └── <NotificationHandler />     (FCM push notifications)
  • No nested layouts — flat route structure
  • No middleware.js — all route protection is client-side only
  • Nav bar hidden on auth pages (/login, /register/*, /blocked, /forgot-password, /auth/choose-role)

Data Flow Pattern

Page (useEffect on mount)
  → API call (apiFetch from app/utils/api.js)
    → AuthService.getToken() → Authorization: Bearer <JWT>
    → fetch() to https://45.93.137.91.nip.io/api/{endpoint}
    → Response: auto-unwrap { data: ... } envelope
    → Return parsed data or throw on non-ok
  → Component state (useState)
  → Render UI with Tailwind classes

3. API Layer

File: app/utils/api.js (1198 lines — 370 commented legacy + 828 active) Ratings API: app/utils/ratings.js (separate file with own apiFetch)

Fetch Helpers

Function Lines Method Auth Error Handling Return Type
apiFetch(endpoint, options) 421-478 Any Auto Bearer Throws on non-ok (except 206) data (auto-unwrapped)
authFetch(endpoint, body, token) 483-524 POST Manual param Returns {status,data,ok,message} Object
reportFetch(endpoint, body) 526-558 POST None Returns {status,data,ok,message} Object
multipartAuthFetch(endpoint, formData) 772-803 POST Auto Bearer Returns {status,data,ok,message} Object

Exported API Functions (47 total)

Category Functions Count
Rent Properties getRentProperties, getRentProperty, getRentPropertyLocations, filterRentProperties 4
Sale Properties getSaleProperties, getSaleProperty, getSalePropertyById 3
Generic Property getProperty 1
Recommendations getRecommendations, getTopRecommendations 2
Reservations getAvailableDateRanges, getReservations, getReservation, checkAvailability, bookReservation, getUserReservations, getOwnerReservationRequests, getOwnerReservationsByStatuses, ownerConfirmReservation, confirmDepositPayment, adminConfirmDeposit, updateBookingStatus, payDeposit 13
Owner Management getMyRentListings, getMySaleListings, addRentProperty, addSaleProperty, editRentProperty, editSaleProperty, updateRentPropertyStatus, updateSalePropertyStatus, getOwnerContactInformation, getOwnerStatistics 10
Auth loginWithEmail, loginWithPhone, sendEmailOTP, sendPhoneOTP, verifyEmail, verifyPhone, changePassword, requestForgetPasswordOtp, verifyForgetPasswordOtp, resetPassword, deleteMyAccount 11
Registration addOwner, addCustomer, registerRealEstateAgent 3
Favorites getUserFavoriteProperties, addFavoriteProperty, removeFavoriteProperty 3
Notifications getUserNotifications, setFCMToken 2
Terms getARTerms, getENTerms, addOrUpdateTerms 3
Currencies getCurrencies 1
Files uploadPicture 1
Reports sendGeneralReport, submitReport, submitReservationReport, updateReservationReport, submitSaleReport, updateSaleReport 6
Profile getCustomerByUserId, getOwnerByUserId 2

Ratings API (5 functions)

addPropertyRating, addCustomerRating, getPropertyRatings, getCustomerRatings, getPropertyAverageRating

API Endpoint Coverage

HTTP Method Count Examples
GET 26 /RentProperties/GetRentProperties, /Reservations/GetAvailableDates/available/${id}
POST 17 /Auth/LogInWithEmail, /Reservations/PayDeposit/pay-deposit, /Rating/AddPropertyRating
PUT 8 /RentProperties/EditRentProperty/${id}, /Reservations/AdminConfirmDeposit/admin-confirm-deposit
DELETE 2 /FavoriteProperty/Remove, /User/DeleteMyAccount

4. State Management

Context Providers

Context File State Consumers Status
FavoritesProvider app/contexts/FavoritesContext.js favorites[], isLoading FloatingSidebar, /favorites, /properties, /property/[id] Active
NotificationsProvider app/contexts/NotificationsContext.js notifications[], unreadCount, isLoading BottomNav, FloatingSidebar Active
PropertyContext app/contexts/PropertyContext.js properties[], loading, error None Orphaned (never mounted)
PropertyContext app/utils/PropertyContext.js Same as above None Orphaned duplicate

localStorage Keys (10 actively written, ~5 legacy read-only)

Key Data Written By Read By
auth_token JWT string AuthService.addToken() AuthService.getToken(), firebase.js
cached_user User profile JSON AuthService.cacheUser() AuthService.getCachedUser()
language "en" or "ar" ClientLayout.js ClientLayout.js
sweethome_onboarding_completed "true" /onboarding/page.js /onboarding/page.js
ownerProperties Properties array JSON /owner/properties/page.js /owner/calendar/page.js
ownerBookings Bookings array JSON /owner/bookings/page.js /owner/bookings/page.js
ownerProfitsTable Profit data JSON /owner/profits/page.js /owner/profits/page.js
userProfile Profile form data JSON /profile/page.js /profile/page.js
userAvatar Base64 data URL /profile/page.js /profile/page.js
token, accessToken, authToken (legacy reads only) /settings, /payments, /reservations

Auth Flow

Login (app/login/page.js)
  → loginWithEmail() / loginWithPhone()
  → authFetch(POST /Auth/LogInWithEmail, { credential, password, device: 0 })
  → 200: AuthService.addToken(token) → localStorage.setItem('auth_token', token)
  → 206: OTP required → sendEmailOTP() → verifyEmail(code) → get final token
  → AuthService.cacheUser(user) → localStorage.setItem('cached_user', ...)
  → router.push('/')

ClientLayout.js (every page navigation)
  → AuthService.getUser() → decode JWT payload (base64 atob)
  → setUser({ name, email, phone, role: isOwner() ? 'owner' : 'customer' })
  → UI branches on user.role (show owner nav / customer nav / guest nav)

Page-level checks
  → Each protected page independently calls:
    AuthService.isAuthenticated() → else router.push('/login')
    AuthService.isOwner() → else router.push('/')

5. Component Architecture

Component Inventory (14 reusable components)

Component File Lines Purpose State
HeroSearch components/home/HeroSearch.js 321 Hero search with filters filters, login dialog
PropertyMap (home) components/home/PropertyMap.js 287 Map with markers + popup selectedProperty, map ref
PropertyMap (property) components/property/PropertyMap.js 166 Map at property detail Tooltip state
BookingCalendar components/property/BookingCalendar.js 124 Monthly booking grid currentMonth, selectedStart
PropertyMapWithMarkers components/PropertyMapWithMarkers.js 100 Generic Leaflet map Map ref, markers ref
StarRating components/ratings/StarRating.js 134 5-star input hoverRating
PropertyRatingList components/ratings/PropertyRatingList.js 286 Paginated reviews ratings, page, loading
PropertyRatingForm components/ratings/PropertyRatingForm.js 317 4-field rating form Clean/services/owner/experience
CustomerRatingForm components/ratings/CustomerRatingForm.js 92 3-field rating form Furn/terms/behavior
BottomNav components/BottomNav.js 58 Mobile bottom bar Badge from context
FloatingSidebar components/FloatingSidebar.js 158 Quick-access buttons Framer-motion variants
NavLinks components/NavLinks.js 42 Nav link atoms usePathname active
NotificationHandler components/NotificationHandler.js 151 FCM push handler Permission state

Largest Page Files

Rank File Lines Complexity
1 api.js 1198 60+ functions, 4 fetch helpers, 370 lines commented
2 PropertyDetail.js 1743 56 imports, 8+ state vars, booking calendar, image gallery, owner check, ratings, map
3 owner/properties/page.js 2057 CRUD + modals + localStorage caching + API calls
4 ClientLayout.js 804 Nav (desktop+mobile), user menu, language switcher, context providers
5 owner/properties/add/page.js 700+ Multi-step form with map, image upload, pricing
6 app/page.js (Home) 623 Property fetching, multi-filter, hero, map, feature cards

6. Key Patterns

Data Fetching (4 Patterns)

Pattern Usage Found In
useEffect + useState ~90% of pages Most pages
Context-level fetch 2 providers FavoritesContext, NotificationsContext
localStorage cache Owner dashboards owner/bookings, owner/calendar, owner/profits
Mock data fallback 3 owner pages owner/bookings, owner/calendar, owner/profits

Styling

  • 100% Tailwind CSS v4 (utility classes, no CSS modules)
  • Custom globals.css: Madani Arabic fonts (9 weights), Leaflet overrides, keyframe animations
  • Color palette: amber-500/600 (primary), #ede6e6 (bg), #156874 (accent teal)
  • RTL-first with dynamic LTR switching via currentLanguage state

Animations (Framer Motion v12.29.2)

  • initial/animate opacity + y/x translations (section reveals)
  • whileHover/whileTap scale (buttons, interactive elements)
  • AnimatePresence (property popups, user menus)
  • whileInView + viewport (scroll-triggered animations on home page)
  • staggerChildren (hero text)
  • Spring transitions { type: "spring", damping: 25, stiffness: 300 }

Form Handling

  • All forms: Controlled useState — no React Hook Form, Formik, or useReducer
  • Validation: Inline value === 0 && <p className="text-red-500">مطلوب</p>
  • No form libraries — all hand-rolled

Responsive Breakpoints

Breakpoint Layout
Default (mobile) Single column, BottomNav, hamburger menu
md: (768px) Desktop nav, 2-3 column grids
lg: (1024px) PropertyDetail sidebar, 3-column grids

7. Owner Pages Analysis (Dashboard Section)

Route File Lines Status Data Source
/owner/properties owner/properties/page.js 2057 Active API (getMyRentListings, getMySaleListings) + localStorage cache
/owner/properties/add owner/properties/add/page.js 700+ Active API (addRentProperty, addSaleProperty, uploadPicture)
/owner/reservations owner/reservations/page.js 1400+ Commented out Mock data (commented)
/owner/bookings owner/bookings/page.js 560+ ⚠️ Demo localStorage mock data only
/owner/calendar owner/calendar/page.js 580+ ⚠️ Demo localStorage mock data only
/owner/profits owner/profits/page.js 600+ ⚠️ Demo localStorage mock data only
/owner/account-book owner/account-book/page.js 500+ Active API (getOwnerStatistics)

8. Admin Functionality

Component Status Data Source
BookingRequests Active Real API (getReservations, adminConfirmDeposit)
Users Not implemented
Properties Not implemented
LedgerBook ⚠️ Mock only 3 hardcoded mock transactions
Dashboard Not implemented

Designed for internal admin use at /admin — tabs for Bookings/Users/Properties/Ledger/Dashboard.


9. Known Technical Debt

Dead Code

File Dead Lines Issue
api.js Lines 1-370 (370 lines) Entire legacy version commented out
StarRating.js Lines 1-93 (93 lines) Old framer-motion version commented out
PropertyRatingList.js ~150 lines Old version commented out
PropertyRatingForm.js ~220 lines Old version commented out
contexts/PropertyContext.js Entire file Never mounted
utils/PropertyContext.js Entire file Duplicate orphan

Code Duplication

Pattern Files Description
Leaflet maps 3 separate files PropertyMapWithMarkers.js, home/PropertyMap.js, property/PropertyMap.js — all setup Leaflet identically
Rating forms PropertyRatingForm.js (317) + CustomerRatingForm.js (92) ~75% code overlap; both define identical RatingField inline
formatCurrency 4+ locations Scattered across files with slightly different logic
Image URL building 4+ locations Different implementations for same task
Notifications page /notifications/page.js vs NotificationsContext Page duplicates all context state/logic

Architecture Issues

Issue Impact
No middleware.js All route protection is client-side only
JWT in localStorage XSS-vulnerable token storage
Client-side role checks Users can modify JWT to elevate privileges
Owner pages use mock data /owner/bookings, /owner/calendar, /owner/profits are demo-only
3 unused UI libraries DaisyUI, Flowbite, Yandex Maps imported but never used
No TypeScript 112 JS files, no type safety
No ESLint No linting configured
No testing framework Zero tests
Flat route structure No nested layouts; all pages share root layout
Active console.log ~30+ files with console.log statements (security risk)

10. Dependencies

Production (18)

Package Version Purpose
next 16.1.6 Framework
react / react-dom ^18.3.1 UI
firebase ^12.11.0 FCM push notifications
leaflet / react-leaflet 1.9.4 / 4.2.1 Maps
@pbe/react-yandex-maps ^1.2.5 Yandex Maps (unused)
framer-motion ^12.29.2 Animations
lucide-react ^0.563.0 Icons
flowbite / flowbite-react 4.0.1 / 0.12.16 UI library (unused)
react-hot-toast ^2.6.0 Toasts
i18next / react-i18next / i18next-browser-languagedetector 25.8 / 16.5 / 8.2 i18n
jspdf / html2canvas 4.2.1 / 1.4.1 PDF generation
xlsx ^0.18.5 Excel export
react-intersection-observer ^10.0.3 Scroll detection

Dev (7)

Package Version Purpose
tailwindcss ^4.1.18 CSS framework
@tailwindcss/postcss ^4 PostCSS plugin
postcss / autoprefixer ^8.5.6 / ^10.4.23 CSS processing
daisyui ^5.5.14 UI components (unused)
babel-plugin-react-compiler 1.0.0 React compiler optimization

Missing (notable absences)

  • No TypeScript
  • No ESLint
  • No testing (Jest, Playwright, Cypress)
  • No state management library (Redux, Zustand)
  • No data fetching library (React Query, SWR)
  • No form library (React Hook Form, Formik)
  • No security lib (helmet, cors, csurf)
  • No HTTP client (axios, ky)
  • No JWT lib (jsonwebtoken, jose)

11. Security Summary

(See security-audit-report.md for full details)

# Finding Severity
1 JWT in localStorage (XSS-theft) 🔴 Critical
2 Stored XSS via Leaflet popup HTML 🔴 Critical
3 OTP code logged to console 🔴 Critical
4 No server-side middleware 🔴 Critical
5 Passwords in URL query params 🔴 Critical
6 IDOR on property edit/status APIs 🔴 Critical
7 Client-only role checks 🟠 High
8 HTTP endpoints leak tokens 🟠 High
9 No CSP/security headers 🟠 High
10 Mass assignment via spread 🟠 High
11 Error messages leak internals 🟠 High
12 Hardcoded IPs (10+ files) 🟡 Medium

12. File Size Heatmap

Size Range Files Examples
1500-2100 lines 2 PropertyDetail.js (1743), owner/properties/page.js (2057)
600-1200 lines 6 api.js (1198), ClientLayout.js (804), login/page.js (800+), owner/properties/add/page.js (700+), app/page.js (623), owner/bookings/page.js (560+)
200-600 lines 15 Most page files
< 200 lines ~70 Enum files, smaller components, error/loading pages