Skip to content

Latest commit

 

History

17 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RKN AL TAHLIA

ركن التحلية

A responsive, single-page Arabic beverage and recipe browser built with React 19 and Framer Motion.

React JavaScript Framer Motion Create React App Version


Overview • Key Features • Screenshots • Tech Stack • Architecture • Data Model • Navigation Flow • Routes • Project Structure • Installation & Setup • Available Scripts • Author & Contact


Overview

RKN AL TAHLIA (recipes-tk) is a client-side single-page application (SPA) designed for discovering, filtering, and preparing curated Arabic beverage recipes. The application delivers an Arabic-first, Right-to-Left (RTL) experience with dynamic theme switching (light/dark mode), real-time search, category filters, and deep-linkable recipe navigation.

Architecture Note:
All recipe and beverage data is bundled locally within src/data.js. The repository operates entirely client-side without a backend server, database, external API integration, or authentication layer. User favorites are persisted locally via the browser's localStorage API.


Key Features

🎨 User Interface & Experience

  • RTL-Native Interface: Tailored specifically for Arabic reading flow and typography.
  • Theme Switching: Instant toggle between light and dark modes with persistent visual harmony.
  • Micro-Interactions & Transitions: Fluid page transitions, card hover animations, and hero motion driven by Framer Motion.
  • Accessibility & Motion Preferences: Target-card smooth scrolling automatically respects the user's prefers-reduced-motion settings.
  • Responsive Navigation: Sticky navigation bar, scroll progress indicator, custom loading screen, and mobile drawer menu.

🔍 Discovery & Recipe Exploration

  • Real-Time Search: Search across all drinks and recipe titles instantly.
  • Category Filtering: Filter items by Cold, Hot, and Sweet beverages.
  • Dedicated Recipe Views: Detailed preparation cards listing ingredients, step-by-step instructions, preparation time, difficulty level, and beverage classification.
  • Local Favorites: Save favorite beverages with instant synchronization to localStorage under favorite-drink-ids.

🔗 Deep Linking & Navigation

  • Bi-Directional Deep Linking: Seamless navigation between drink preview cards on the Home view and comprehensive Recipe cards on the Recipes view.
  • Anchor Offset Scrolling: Automated scroll targeting that calculates sticky navbar offsets using native CSS scroll-margin-top.

Screenshots

Hero Section & Discovery

Hero section

Drink Collection Grid

Drinks grid

Detailed Recipe View

Recipe details


Tech Stack

Category Technology Purpose & Role
Frontend Framework React 19 UI component composition, lifecycle management, and reactive hooks
Build & Tooling Create React App (react-scripts) Development server bundling, optimization, and production build pipelines
Programming Language JavaScript Application logic, routing rules, and local data models
Styling & Layout CSS Theme variables, RTL layout rules, responsive breakpoints, and custom styles
Motion & Animation Framer Motion View entry/exit transitions, hero element shifts, and loading states
Iconography React Icons Vector icons for social and brand links
Testing React Testing Library Unit and smoke testing (App.test.js)
Performance Metrics Web Vitals Standardized web vitals reporting scaffold (reportWebVitals.js)
Package Management npm Dependency management with locked resolution (package-lock.json)

Architecture

The application mounts via src/index.js in React.StrictMode. Top-level state and routing logic reside in src/App.js, which manages view rendering, query and hash parsing, filter application, and localStorage synchronization.

Routing is implemented natively with the browser History API and window.location, listening for popstate events without requiring external router dependencies like React Router.

flowchart TD
    entry["src/index.js and React StrictMode"] --> app["src/App.js"]
    data["src/data.js local recipes and drinks"] --> app
    app -->|syncs favorite IDs| storage["localStorage favorite-drink-ids"]
    app --> navbar["Navbar.js"]
    app --> hero["HeroSection.js"]
    app --> drinkGrid["DrinkCardGrid.js"]
    app --> recipeGrid["RecipeCardGrid.js"]
    app --> contact["Contact.js"]
    app --> footer["Footer.js"]
    app --> toast["Toast.js"]
Loading

Data Model

All records are declared in src/data.js. The relationship between drinks and recipes relies on deterministic, stable identifiers rather than array indices:

classDiagram
    class Recipe {
        +String id
        +String title
        +String image
        +String[] ingredients
        +String[] method
        +String description
        +String type
        +String preparationTime
        +String difficulty
        +String drinkId
    }

    class Drink {
        +String id
        +String recipeId
        +String name
        +String image
        +String category
        +String description
    }

    Recipe --> Drink : uses stable IDs
    Drink --> Recipe : uses stable IDs
Loading
  • Base Recipe Record: Defines id, title, image, ingredients, preparationMethod, description, type, time, difficulty, and drinkId.
  • Derived Drink Record: Extracted from the recipe dataset with matching drinkId (drink-<recipe-id>), recipeId, display name, image, category, and summary description.

Navigation Flow

The application provides deterministic two-way navigation between the Home overview grid and the detailed Recipes collection:

flowchart LR
    homeCard["Home drink card"] -->|"View Details"| recipeCard["Recipe card"]
    recipeCard -->|"Back to Drink"| homeCard
Loading

Scrolling & Transition Behavior

  1. Target Identification: Navigation buttons emit the stable entity ID (recipeId or drinkId).
  2. URL Update & View Render: App.js updates browser history, switches the active view, and triggers a lightweight Framer Motion fade-and-shift transition.
  3. Smooth Viewport Alignment: A useEffect hook triggers native smooth scrolling (block: "start"), adjusting for sticky header height via CSS scroll-margin-top.
  4. Cleanup & Accessibility: Timers for scheduled route scrolling are cleanly aborted if the route changes during execution, and animations are suppressed when reduced-motion preferences are detected.

Routes

The custom route parser in src/App.js evaluates pathnames, query parameters, and hashes:

Route / URL Pattern Active View Target Element / Purpose
/ Home Full home view: Hero, Drinks Grid, Statistics, Contact, and Footer
/#home Home Scroll-positions the viewport at the Hero section
/#drinks Home Scroll-positions the viewport at the Drinks collection section
/#contact Home Scroll-positions the viewport at the Contact section
/#drink-<drink-id> Home Scroll-targets the specific drink card with DOM ID drink-<drink-id>
/?recipe=<recipe-id> Home Scroll-targets the drink card matching the specified recipe ID
/drinks Home Direct pathname route targeting the Drinks collection
/recipes Recipes Displays the complete recipe cards collection
/recipes?recipe=<recipe-id> Recipes Targets and highlights the recipe card with DOM ID recipe-card-<recipe-id>
/recipes/<recipe-id> Recipes Displays recipes view with the specified recipe card marked active
/favorites Favorites Filtered view displaying user-saved favorite drink cards

Note: If an unknown recipe or drink ID is supplied in the URL, the page renders gracefully without attempting an invalid scroll target.


Component Architecture

Component File Path Responsibilities
Navbar src/components/Navbar.js Top-level branding, active section tracking, theme switcher, and mobile drawer toggle
HeroSection src/components/HeroSection.js Visual hero banner, quick category filters (Cold / Hot / Sweet), and search input
DrinkCardGrid src/components/DrinkCardGrid.js Grid of drink cards with favorite controls and links to detailed recipes
RecipeCardGrid src/components/RecipeCardGrid.js Structured recipe cards detailing ingredients, preparation steps, metadata, and back-links
Contact src/components/Contact.js External community and communication links (LinkedIn, Facebook, TikTok, WhatsApp)
Footer src/components/Footer.js Project information, internal anchors, and direct email link
Toast src/components/Toast.js Accessible alert status notification utilizing an aria-live region

State Management & Persistence

┌─────────────────────────────────────────────────────────────────────────┐
│                           src/App.js (State)                            │
├───────────────────────────────────┬─────────────────────────────────────┤
│ In-Memory (Transient)             │ Local Storage (Persistent)          │
├───────────────────────────────────┼─────────────────────────────────────┤
│ • Theme mode (light / dark)       │ • 'favorite-drink-ids'              │
│ • Search query                    │   (Validated and normalized against │
│ • Active category filter          │    available IDs in src/data.js)    │
│ • Mobile menu toggle state        │                                     │
│ • Active route & recipe ID        │                                     │
│ • Loading indicator state         │                                     │
└───────────────────────────────────┴─────────────────────────────────────┘

Project Structure

recipes-tk/
├── assets/
│   └── screenshots/
│       ├── drinks-grid.png
│       ├── hero-section.png
│       └── recipe-details.png
├── public/
│   ├── img/
│   ├── index.html
│   ├── manifest.json
│   ├── pr.jpg
│   └── robots.txt
├── src/
│   ├── components/
│   │   ├── Contact.js
│   │   ├── DrinkCardGrid.js
│   │   ├── Footer.js
│   │   ├── HeroSection.js
│   │   ├── Navbar.js
│   │   ├── RecipeCardGrid.js
│   │   └── Toast.js
│   ├── hooks/
│   │   └── useScrollProgress.js
│   ├── App.css
│   ├── App.js
│   ├── App.test.js
│   ├── data.js
│   ├── index.css
│   ├── index.js
│   ├── reportWebVitals.js
│   └── setupTests.js
├── package.json
├── package-lock.json
└── README.md

Installation & Setup

Prerequisites

  • Node.js and npm installed on your system.
  • A modern web browser supported by Create React App's default browserslist.

1. Clone the Repository

git clone <repository-url>
cd recipes-tk

2. Install Dependencies

npm install

Note: The project runs entirely on client-side static data. No environment variables or .env files are required.

3. Start Development Server

npm start

The application will launch at http://localhost:3000. If port 3000 is occupied, Create React App will prompt to run on an alternate available port.

4. Create Production Build

npm run build

Compiled, production-ready static assets will be output to the build/ directory.


Available Scripts

Script Command Purpose
Development npm start Launches the Create React App development server with hot reloading
Build npm run build Bundles and optimizes static production assets into build/
Test npm test Executes React Testing Library test suite (App.test.js) in interactive watch mode
Eject npm run eject Ejects Create React App configuration and dependencies (Irreversible)

Web & SEO Configuration

The HTML document shell located in public/index.html includes:

  • Language & Direction: lang="ar" for Arabic layout context.
  • Title: RKN AL TAHLIA
  • Description: ركن التحلية - وصفات مشروبات عربية فاخرة بأسلوب غني وفاخر.
  • Theme Color: #000000
  • Branding Assets: Favicon and Apple Touch Icon linked to public/pr.jpg.
  • Web App Manifest: public/manifest.json referencing default application metadata.
  • Robots Policy: public/robots.txt permitting standard web crawler access across all routes.

Deployment

The application compiles into static files (HTML, CSS, JS, and media assets) inside build/.

Important Deployment Requirement:
Because the application relies on client-side History API routing for pathname routes (such as /recipes and /favorites), your static web server (e.g., Nginx, Apache, Netlify, Vercel, Firebase Hosting, GitHub Pages) must be configured to route all unknown path requests back to public/index.html (SPA fallback).


Troubleshooting

Issue Potential Cause Solution
Dependency installation fails Node/npm version mismatch or corrupted node_modules Ensure Node.js is up to date and run npm install using the committed package-lock.json.
Port 3000 is already in use Another local process is binding to port 3000 Accept the CLI prompt to bind to an alternate port, or terminate the process utilizing port 3000.
404 Not Found on direct route visit Server lacking SPA rewrite / fallback configuration Configure your static web host to route all pathname requests (e.g., /recipes) to fallback to index.html.
Images failing to load Missing or altered asset paths Ensure the public/img/ directory remains intact with the original filenames, as images use root-relative paths.

Development Notes

  • ID Integrity: Always link drinks and recipes using stable string IDs (drink-<recipe-id>) rather than mutable array indexes.
  • Routing Engine: Preserve the browser History API and popstate event listeners when modifying view navigation.
  • Linting: Code formatting follows Create React App's internal ESLint configuration.

Version & License

  • Version: 0.1.0 (as declared in package.json).
  • License: No license file or project license declaration is currently included in the repository.

Author & Contact

Eslam Adel


Final Note

Thank You

Thank you for taking the time to explore this project. Your feedback, suggestions, and collaboration are always welcome.

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages