Skip to content

foodinary-project/frontend-backend

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

48 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🍲 Foodinary - Discover Indonesian Culinary Heritage

Build Status Version License Webpack ES6+

A comprehensive web platform showcasing traditional Indonesian cuisine with AI-powered recipe recognition

πŸš€ Live Demo β€’ πŸ“– Documentation β€’ πŸ› Report Bug β€’ πŸ’‘ Request Feature


πŸ“‹ Table of Contents

🎯 Project Overview

Foodinary is a cutting-edge web platform designed to preserve and celebrate Indonesia's rich culinary heritage. Our platform combines traditional recipe knowledge with modern AI technology to create an immersive culinary experience for food enthusiasts worldwide.

🌟 Mission Statement

  • Preserve Indonesian culinary traditions through digital documentation
  • Educate users about the cultural significance of traditional dishes
  • Innovate with AI-powered food recognition technology
  • Connect food lovers through a comprehensive recipe database

🎯 Core Objectives

  • πŸ“š Cultural Preservation: Maintain authentic Indonesian recipes and their historical context
  • πŸ€– AI Integration: Leverage machine learning for intelligent food recognition
  • πŸ‘₯ Community Building: Create a platform for culinary enthusiasts to explore and share
  • πŸ“± User Experience: Provide intuitive, responsive design across all devices
  • πŸ” Discovery: Enable easy exploration of Indonesian cuisine diversity

✨ Key Features

🏠 Landing Experience

  • Hero Section with compelling call-to-action
  • Popular Cuisine Showcase featuring Indonesian favorites
  • Feature Highlights with interactive previews
  • Responsive Design optimized for all devices

πŸ” Recipe Discovery Engine

  • Comprehensive Database with 30+ authentic Indonesian recipes
  • Smart Filtering by taste profiles (Asin, Gurih, Manis, Pedas, dll.)
  • Advanced Search with real-time results
  • Detailed Recipe Pages with step-by-step instructions
  • Regional Information highlighting dish origins

πŸ“Έ AI-Powered Recipe Recognition

  • Photo Upload with drag-and-drop functionality
  • Real-time Camera capture for instant analysis
  • Machine Learning Integration for accurate food identification
  • Recipe Suggestions based on detected dishes
  • Multi-format Support (JPEG, PNG, WebP)

πŸ‘€ User Dashboard

  • Personal Statistics tracking cooking journey
  • Recipe History with detailed timestamps
  • Favorites Management for quick access
  • Account Customization with profile settings
  • Progress Tracking for culinary goals

πŸ” Authentication System

  • Secure Registration with email verification
  • JWT Token Authentication for session management
  • Password Recovery with reset functionality
  • Protected Routes ensuring secure access
  • Remember Me functionality for convenience

πŸ“Š Advanced Features

  • Offline Support for core functionality
  • Social Sharing capabilities
  • Print-friendly recipe formats
  • Nutritional Information (Coming Soon)
  • Video Tutorials (Coming Soon)

πŸ›  Technology Stack

🎨 Frontend Technologies

Technology Version Purpose
JavaScript ES6+ Core programming language with modern syntax
Webpack 5.98.0 Module bundling and build optimization
CSS3 Latest Advanced styling with Flexbox & Grid
HTML5 Latest Semantic markup structure

βš™οΈ Build Tools & Configuration

Tool Version Purpose
Webpack 5.98.0 Module bundler and asset optimization
Babel 7.26.9 JavaScript transpilation for browser compatibility
CSS Loader 7.1.2 CSS processing and optimization
Mini CSS Extract Plugin 2.9.2 CSS extraction for production builds
Clean Webpack Plugin 4.0.0 Build directory cleanup
Copy Webpack Plugin 13.0.0 Static asset copying

πŸ“¦ Core Dependencies

Package Version Purpose
SweetAlert2 11.22.0 Beautiful, responsive popups and modals
IDB 8.0.3 IndexedDB wrapper for client-side storage

πŸ”§ Development Dependencies

Package Version Purpose
Webpack Dev Server 5.2.0 Development server with hot reload
HTTP Server 14.1.1 Production build serving
Prettier 3.5.3 Code formatting and style consistency

πŸ“± Browser Support

  • βœ… Chrome 80+
  • βœ… Firefox 75+
  • βœ… Safari 13+
  • βœ… Edge 80+
  • βœ… Mobile browsers (iOS Safari, Chrome Mobile)

πŸ“ Project Structure

frontend-backend/
β”œβ”€β”€ πŸ“ dist/                           # Production build output
β”œβ”€β”€ πŸ“ src/                           # Source code directory
β”‚   β”œβ”€β”€ πŸ“„ index.html                 # Main HTML entry point
β”‚   β”œβ”€β”€ πŸ“ public/                    # Static assets & resources
β”‚   β”‚   β”œβ”€β”€ πŸ“ data/
β”‚   β”‚   β”‚   └── πŸ“„ recipes.json       # Recipe database (30+ dishes)
β”‚   β”‚   └── πŸ“ images/                # Image assets
β”‚   β”‚       β”œβ”€β”€ πŸ“ landing-page/      # Hero & showcase images
β”‚   β”‚       β”œβ”€β”€ πŸ“ meet-our-team/     # Team member photos
β”‚   β”‚       β”œβ”€β”€ πŸ“ auth-image.png     # Authentication visuals
β”‚   β”‚       └── πŸ“ logo.png           # Brand assets
β”‚   β”œβ”€β”€ πŸ“ scripts/                   # JavaScript source code
β”‚   β”‚   β”œβ”€β”€ πŸ“„ index.js              # Application entry point
β”‚   β”‚   β”œβ”€β”€ πŸ“„ config.js             # Environment configuration
β”‚   β”‚   β”œβ”€β”€ πŸ“ data/                 # Data layer
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ api.js            # API communication layer
β”‚   β”‚   β”‚   └── πŸ“„ database.js       # Local storage management
β”‚   β”‚   β”œβ”€β”€ πŸ“ pages/                # Page components
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ app.js            # Main application controller
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“ landingPage/      # Homepage components
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“ auth/             # Authentication pages
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“ login/        # Login functionality
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“ register/     # User registration
β”‚   β”‚   β”‚   β”‚   └── πŸ“ reset-password/ # Password recovery
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“ dashboard/        # User dashboard
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“ recipe/           # Recipe browsing & search
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“ cekResep/         # AI recipe recognition
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“ detail/           # Recipe detail pages
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“ favorite/         # User favorites
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“ history/          # User activity history
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“ about/            # About page & team info
β”‚   β”‚   β”‚   └── πŸ“ accountSettings/  # User preferences
β”‚   β”‚   β”œβ”€β”€ πŸ“ routes/               # Routing system
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ routes.js         # Route definitions & guards
β”‚   β”‚   β”‚   └── πŸ“„ url-parser.js     # URL parsing utilities
β”‚   β”‚   └── πŸ“ utils/                # Utility functions
β”‚   β”‚       β”œβ”€β”€ πŸ“„ auth.js           # Authentication helpers
β”‚   β”‚       β”œβ”€β”€ πŸ“„ camera.js         # Camera API integration
β”‚   β”‚       └── πŸ“„ index.js          # General utilities
β”‚   └── πŸ“ styles/                   # Stylesheet directory
β”‚       β”œβ”€β”€ πŸ“„ styles.css            # Main stylesheet (2500+ lines)
β”‚       └── πŸ“„ responsive.css        # Mobile-first responsive design
β”œβ”€β”€ πŸ“„ package.json                  # Project dependencies & scripts
β”œβ”€β”€ πŸ“„ webpack.common.js             # Shared webpack configuration
β”œβ”€β”€ πŸ“„ webpack.dev.js               # Development environment config
β”œβ”€β”€ πŸ“„ webpack.prod.js              # Production build optimization
β”œβ”€β”€ πŸ“„ .gitignore                   # Git ignore rules
└── πŸ“„ README.md                    # Project documentation

πŸ— Architecture Overview

Frontend Architecture Pattern: Component-Based SPA (Single Page Application)

  • πŸ“ Pages: Individual page components with render/afterRender lifecycle
  • πŸ“ Routes: Hash-based routing with authentication guards
  • πŸ“ Utils: Reusable utility functions and helpers
  • πŸ“ Data: API abstraction and local storage management
  • πŸ“ Styles: Modular CSS with responsive design principles

πŸ”„ Data Flow:

User Interaction β†’ Page Component β†’ API Layer β†’ Backend β†’ Database
                ↓
            DOM Update ← State Change ← Response Processing

πŸ“„ Pages Documentation

🏠 Landing Page (landing-page.js)

Purpose: Homepage yang memperkenalkan Foodinary kepada pengunjung

πŸ“‹ Sections:

  • Navigation Bar: Responsive menu dengan authentication state
  • Hero Section: Compelling introduction dengan CTA buttons
  • Popular Cuisine: Showcase makanan Indonesia terpopuler
  • Foodinary Experience: Feature highlights dengan badges
  • Footer: Contact info dan quick links

πŸ”§ Key Implementation:

// Dynamic authentication state
const isLoggedIn = token && token !== 'null' && token !== 'undefined';

// Responsive navigation
${isLoggedIn
  ? `<a href="#/dashboard" class="btn-primary">Dashboard</a>`
  : `<a href="#/login" class="btn-outline">Login</a>
     <a href="#/register" class="btn-primary">Sign Up</a>`
}

πŸ” Recipe Page (recipe-page.js)

Purpose: Halaman eksplorasi dan pencarian resep

🌟 Features:

  • Search Bar: Real-time recipe search
  • Taste Filters: Filter berdasarkan rasa (Asin, Gurih, Manis, Pedas, dll.)
  • Recipe Grid: Responsive card layout
  • Quick Actions: Direct link to recipe details

πŸ“Š Data Flow:

getRecipes() β†’ renderRecipeCards() β†’ Event Handlers β†’ User Interaction

πŸ“Έ Check Recipe Page (cek-resep-page.js)

Purpose: AI-powered food recognition system

πŸš€ Advanced Features:

  • Drag & Drop Upload: Intuitive file handling
  • Camera Integration: Real-time photo capture
  • Preview System: Image preview before analysis
  • ML Processing: Backend integration for food recognition

πŸ“± Camera Implementation:

// Camera stream handling
navigator.mediaDevices.getUserMedia({ video: true }).then((stream) => {
  videoElement.srcObject = stream;
});

πŸ‘€ Dashboard Suite

Main Dashboard (dashboard-page.js)

  • User Greeting: Personalized welcome message
  • Statistics Cards: Total History, Total Favorites
  • Quick Navigation: Sidebar dengan active states
  • User Avatar: Profile management access

History Page (history-page.js)

  • Activity Timeline: Chronological recipe interactions
  • Delete Functionality: Remove unwanted history entries
  • Search History: Find specific past activities

Favorites Page (favorite-page.js)

  • Favorites Grid: Visual layout for saved recipes
  • Quick Access: Direct navigation to recipe details
  • Management Tools: Add/remove favorites

πŸ” Authentication Pages

Login (auth/login/login-page.js)

Features:

  • Form Validation: Real-time input validation
  • Remember Me: Persistent login sessions
  • Error Handling: User-friendly error messages
  • Password Toggle: Show/hide password functionality

Register (auth/register/register-page.js)

Features:

  • Complete Registration: Full user profile setup
  • Password Confirmation: Double-password verification
  • Terms Agreement: Terms & conditions acceptance
  • Email Validation: Format and availability checking

Reset Password (auth/reset-password/reset-password-page.js)

Features:

  • Email Recovery: Password reset via email
  • Security Questions: Additional verification steps
  • New Password Setup: Secure password creation

πŸ“– Detail Page (detail-page.js)

Purpose: Comprehensive recipe information display

πŸ“‘ Sections:

  • Recipe Header: Image, name, origin, taste profile
  • Ingredients List: Detailed ingredients dengan quantities
  • Equipment Needed: Required cooking tools
  • Step-by-Step Instructions: Numbered cooking process
  • Source Attribution: Recipe source references

ℹ️ About Page (about-page.js)

Purpose: Platform information dan team showcase

πŸ“‹ Content Sections:

  • Mission Statement: Foodinary's purpose dan vision
  • Team Showcase: Developer profiles dengan social links
  • Contact Information: Multiple communication channels
  • Project Background: Development story dan objectives

πŸ‘₯ Team Integration:

// Dynamic team member rendering
teamMembers
  .map(
    (member) => `
  <div class="team-card">
    <div class="profile-image" style="background-image: url('${member.image}');">
    </div>
    <h3>${member.name}</h3>
    <div class="role">${member.role}</div>
    <p class="description">${member.description}</p>
    <div class="social-links">
      ${member.socialLinks.map((link) => `<a href="${link.url}">${link.icon}</a>`).join("")}
    </div>
  </div>
`
  )
  .join("");

βš™οΈ Account Settings (accountSettings/account-settings-page.js)

Purpose: User preference management

πŸ”§ Settings Options:

  • Profile Information: Update personal details
  • Password Change: Secure password modification
  • Privacy Preferences: Data handling preferences
  • Notification Settings: Communication preferences

🎨 Styling Documentation

πŸ— CSS Architecture

Stylesheet architecture menggunakan BEM methodology dan component-based styling:

/* Block Element Modifier (BEM) Pattern */
.component {
}
.component__element {
}
.component__element--modifier {
}

πŸ“„ Main Stylesheet (styles.css - 2500+ lines)

Organized Sections:

Line Range Section Description
1-200 Navigation Header, menu, responsive navigation
200-400 Hero Section Landing page hero styling
400-600 Recipe Cards Card components dan grid layouts
600-800 Authentication Login/register form styling
800-1000 Buttons & Controls Interactive elements
1000-1400 Dashboard Dashboard layout dan components
1400-1600 Forms Form styling dan validation states
1600-1800 Recipe Finder Search dan filter components
1800-2000 Footer Footer layout dan social links
2000-2200 Utilities Helper classes dan animations
2200-2500+ Responsive Media queries dan breakpoints

πŸ”§ Key CSS Classes:

/* 🧭 Navigation System */
.navigation {
  /* Main navigation container */
  position: fixed;
  top: 0;
  width: 100%;
  z-index: 1000;
}

.nav-container {
  /* Flex container for nav items */
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.hamburger-menu {
  /* Mobile menu trigger */
  display: none;
  flex-direction: column;
  cursor: pointer;
}

/* πŸ“Š Dashboard Layout */
.db-container {
  /* Dashboard grid container */
  display: grid;
  grid-template-columns: 250px 1fr;
  min-height: 100vh;
}

.db-sidebar {
  /* Sidebar navigation */
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  padding: 2rem 1rem;
}

.db-main-content {
  /* Main content area */
  padding: 2rem;
  background-color: #f8f9fa;
}

/* 🍲 Recipe Components */
.recipe-card {
  /* Individual recipe card */
  background: white;
  border-radius: 12px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  transition: transform 0.3s ease;
}

.recipe-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
}

/* πŸ“± Form Components */
.form-group {
  /* Form input groups */
  margin-bottom: 1.5rem;
  position: relative;
}

.form-group input {
  /* Form inputs styling */
  width: 100%;
  padding: 0.75rem 1rem;
  border: 2px solid #e9ecef;
  border-radius: 8px;
  transition: border-color 0.3s ease;
}

.form-group input:focus {
  border-color: #007bff;
  outline: none;
  box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.1);
}

πŸ“± Responsive Design Strategy

Mobile-First Approach:

/* Base styles for mobile */
.container {
  padding: 1rem;
}

/* Tablet styles */
@media (min-width: 768px) {
  .container {
    padding: 2rem;
  }

  .db-container {
    grid-template-columns: 200px 1fr;
  }
}

/* Desktop styles */
@media (min-width: 1024px) {
  .container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 3rem;
  }

  .db-container {
    grid-template-columns: 250px 1fr;
  }
}

/* Large desktop */
@media (min-width: 1440px) {
  .container {
    max-width: 1400px;
  }
}

πŸ“ Breakpoint System:

  • Mobile: < 768px - Single column, hamburger menu
  • Tablet: 768px - 1024px - Collapsed sidebar, grid adjustments
  • Desktop: 1024px - 1440px - Full sidebar, multi-column layouts
  • Large Desktop: > 1440px - Max-width container, optimized spacing

🎨 Design System

Color Palette:

:root {
  /* Primary Colors */
  --primary-blue: #007bff;
  --primary-dark: #0056b3;

  /* Secondary Colors */
  --secondary-gray: #6c757d;
  --light-gray: #f8f9fa;

  /* Accent Colors */
  --success-green: #28a745;
  --danger-red: #dc3545;
  --warning-yellow: #ffc107;

  /* Text Colors */
  --text-primary: #212529;
  --text-secondary: #6c757d;
  --text-muted: #adb5bd;
}

Typography Scale:

/* Heading Hierarchy */
h1 {
  font-size: 2.5rem;
  font-weight: 700;
}
h2 {
  font-size: 2rem;
  font-weight: 600;
}
h3 {
  font-size: 1.75rem;
  font-weight: 600;
}
h4 {
  font-size: 1.5rem;
  font-weight: 500;
}

/* Body Text */
body {
  font-size: 1rem;
  line-height: 1.6;
}
.text-small {
  font-size: 0.875rem;
}
.text-large {
  font-size: 1.125rem;
}

Animation Library:

/* Smooth Transitions */
.animate-fadeInUp {
  animation: fadeInUp 0.6s ease-out;
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(30px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Hover Effects */
.hover-lift {
  transition: transform 0.3s ease;
}

.hover-lift:hover {
  transform: translateY(-2px);
}

πŸ”Œ API Integration

πŸ— API Architecture (data/api.js)

Base Configuration:

// Environment Configuration
const BASE_URL = "https://backend-4lij.onrender.com";
const ACCESS_TOKEN_KEY = "accessToken";

// Request Headers
const getAuthHeaders = () => ({
  "Content-Type": "application/json",
  Authorization: `Bearer ${getAccessToken()}`
});

πŸ“‘ Core API Functions

Authentication Endpoints

// User Registration
const registerUser = async ({ name, email, password }) => {
  const response = await fetch(`${BASE_URL}/auth/register`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ name, email, password })
  });
  return response.json();
};

// User Login
const loginUser = async ({ email, password }) => {
  const response = await fetch(`${BASE_URL}/auth/login`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ email, password })
  });
  return response.json();
};

// Password Reset
const resetPassword = async ({ email }) => {
  const response = await fetch(`${BASE_URL}/auth/reset-password`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ email })
  });
  return response.json();
};

Recipe Management

// Get All Recipes
const getRecipes = async () => {
  const response = await fetch(`${BASE_URL}/recipes`);
  return response.json();
};

// Get Recipe by ID
const getRecipeById = async (id) => {
  const response = await fetch(`${BASE_URL}/recipes/${id}`);
  return response.json();
};

// Search Recipes
const searchRecipes = async (query) => {
  const response = await fetch(`${BASE_URL}/recipes/search?q=${encodeURIComponent(query)}`);
  return response.json();
};

// Filter Recipes by Taste
const filterRecipesByTaste = async (taste) => {
  const response = await fetch(`${BASE_URL}/recipes/filter?taste=${taste}`);
  return response.json();
};

User Data Management

// Get User Profile
const getUserProfile = async () => {
  const response = await fetch(`${BASE_URL}/user/profile`, {
    headers: getAuthHeaders()
  });
  return response.json();
};

// Update User Profile
const updateUserProfile = async (userData) => {
  const response = await fetch(`${BASE_URL}/user/profile`, {
    method: "PUT",
    headers: getAuthHeaders(),
    body: JSON.stringify(userData)
  });
  return response.json();
};

// Get User History
const getUserHistory = async () => {
  const response = await fetch(`${BASE_URL}/user/history`, {
    headers: getAuthHeaders()
  });
  return response.json();
};

// Get User Favorites
const getUserFavorites = async () => {
  const response = await fetch(`${BASE_URL}/user/favorites`, {
    headers: getAuthHeaders()
  });
  return response.json();
};

AI Recognition Service

// Upload Image for Recognition
const uploadImageForRecognition = async (imageFile) => {
  const formData = new FormData();
  formData.append("image", imageFile);

  const response = await fetch(`${BASE_URL}/ai/recognize`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${getAccessToken()}`
    },
    body: formData
  });
  return response.json();
};

// Get Recognition History
const getRecognitionHistory = async () => {
  const response = await fetch(`${BASE_URL}/ai/history`, {
    headers: getAuthHeaders()
  });
  return response.json();
};

πŸ“Š Data Models

Recipe Model

interface Recipe {
  id: number;
  name: string;
  asal_daerah: string;
  rasa_dominan: "Asin" | "Gurih" | "Manis" | "Pedas" | "Asam";
  deskripsi: string;
  bahan: string[];
  alat: string[];
  cara_membuat: string[];
  gambar: string;
  sumber: string;
  created_at?: string;
  updated_at?: string;
}

User Model

interface User {
  id: number;
  name: string;
  email: string;
  avatar?: string;
  created_at: string;
  preferences?: {
    favorite_tastes: string[];
    dietary_restrictions: string[];
  };
}

Recognition Result Model

interface RecognitionResult {
  id: number;
  image_url: string;
  predicted_food: string;
  confidence: number;
  suggested_recipes: Recipe[];
  timestamp: string;
  user_id: number;
}

πŸ” Authentication Flow

// Authentication State Management
class AuthManager {
  static setToken(token) {
    localStorage.setItem(ACCESS_TOKEN_KEY, token);
  }

  static getToken() {
    return localStorage.getItem(ACCESS_TOKEN_KEY);
  }

  static removeToken() {
    localStorage.removeItem(ACCESS_TOKEN_KEY);
  }

  static isAuthenticated() {
    const token = this.getToken();
    return token && token !== "null" && token !== "undefined";
  }
}

// Route Protection
const checkAuthenticatedRoute = (page) => {
  if (!AuthManager.isAuthenticated()) {
    location.hash = "/login";
    return null;
  }
  return page;
};

🚦 Error Handling

// Centralized Error Handler
const handleApiError = (error, context = "") => {
  console.error(`API Error ${context}:`, error);

  if (error.status === 401) {
    // Unauthorized - redirect to login
    AuthManager.removeToken();
    location.hash = "/login";
    return;
  }

  if (error.status === 403) {
    // Forbidden
    showErrorMessage("Access denied. Please check your permissions.");
    return;
  }

  if (error.status >= 500) {
    // Server error
    showErrorMessage("Server error. Please try again later.");
    return;
  }

  // Default error handling
  showErrorMessage(error.message || "An unexpected error occurred.");
};

// API Wrapper with Error Handling
const apiCall = async (apiFunction, ...args) => {
  try {
    const result = await apiFunction(...args);
    return result;
  } catch (error) {
    handleApiError(error, apiFunction.name);
    throw error;
  }
};

πŸ“ˆ Performance Optimization

// Request Caching
const cache = new Map();

const cachedFetch = async (url, options = {}) => {
  const cacheKey = `${url}_${JSON.stringify(options)}`;

  if (cache.has(cacheKey)) {
    return cache.get(cacheKey);
  }

  const response = await fetch(url, options);
  const data = await response.json();

  // Cache for 5 minutes
  cache.set(cacheKey, data);
  setTimeout(() => cache.delete(cacheKey), 300000);

  return data;
};

// Request Debouncing for Search
const debounce = (func, wait) => {
  let timeout;
  return function executedFunction(...args) {
    const later = () => {
      clearTimeout(timeout);
      func(...args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
};

const debouncedSearch = debounce(searchRecipes, 300);

⚑ Installation & Setup

πŸ”§ Prerequisites

Before getting started, ensure you have the following installed:

Requirement Version Download Link
Node.js 16.0+ nodejs.org
npm 8.0+ Included with Node.js
Git Latest git-scm.com

πŸš€ Quick Start

# 1️⃣ Clone the repository
git clone https://github.com/foodinary-project/frontend-backend.git
cd frontend-backend

# 2️⃣ Install dependencies
npm install

# 3️⃣ Start development server
npm run start-dev

# 4️⃣ Open your browser
# Navigate to http://localhost:3000

πŸ“‹ Detailed Installation Steps

1. Repository Setup

# Clone the repository
git clone https://github.com/foodinary-project/frontend-backend.git

# Navigate to project directory
cd frontend-backend

# Verify project structure
ls -la

2. Environment Configuration

# Create environment configuration (if needed)
cp src/scripts/config.example.js src/scripts/config.js

# Edit configuration file
# Update BASE_URL and other environment variables

3. Dependency Installation

# Install all dependencies
npm install

# Verify installation
npm list --depth=0

4. Development Server

# Start development server with hot reload
npm run start-dev

# Server will start on http://localhost:3000
# Hot reload enabled - changes will reflect automatically

πŸ— Build Commands

# πŸ”§ Development
npm run start-dev          # Start dev server with hot reload
                           # Port: 3000
                           # Source maps: enabled
                           # Minification: disabled

# πŸš€ Production Build
npm run build              # Create optimized production build
                           # Output: dist/ directory
                           # Minification: enabled
                           # Source maps: disabled

# 🌐 Serve Production
npm run serve              # Serve production build locally
                           # Port: 8080
                           # Simulates production environment

βš™οΈ Configuration Options

Webpack Development (webpack.dev.js)

module.exports = {
  mode: "development",
  devServer: {
    static: "./dist",
    port: 3000,
    hot: true,
    open: true,
    historyApiFallback: true
  },
  devtool: "eval-source-map"
};

Webpack Production (webpack.prod.js)

module.exports = {
  mode: "production",
  optimization: {
    minimize: true,
    splitChunks: {
      chunks: "all"
    }
  },
  devtool: "source-map"
};

πŸ” Troubleshooting

Common Issues & Solutions

❌ Port 3000 already in use

# Solution: Use different port
npx webpack serve --config webpack.dev.js --port 3001

❌ Module not found errors

# Solution: Clear cache and reinstall
rm -rf node_modules package-lock.json
npm install

❌ Build fails on Windows

# Solution: Use cross-platform commands
npm install --save-dev cross-env
# Update package.json scripts with cross-env

❌ Hot reload not working

# Solution: Check firewall/proxy settings
# Ensure no browser extensions blocking websockets

πŸ“± Platform-Specific Setup

Windows Setup

# Enable script execution
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

# Install Node.js via chocolatey (optional)
choco install nodejs

# Clone and setup
git clone https://github.com/foodinary-project/frontend-backend.git
cd frontend-backend
npm install
npm run start-dev

macOS Setup

# Install Node.js via homebrew (optional)
brew install node

# Clone and setup
git clone https://github.com/foodinary-project/frontend-backend.git
cd frontend-backend
npm install
npm run start-dev

Linux Setup

# Install Node.js (Ubuntu/Debian)
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs

# Clone and setup
git clone https://github.com/foodinary-project/frontend-backend.git
cd frontend-backend
npm install
npm run start-dev

🐳 Docker Setup (Optional)

# Dockerfile
FROM node:18-alpine

WORKDIR /app
COPY package*.json ./
RUN npm install

COPY . .
EXPOSE 3000

CMD ["npm", "run", "start-dev"]
# Build and run with Docker
docker build -t foodinary .
docker run -p 3000:3000 foodinary

πŸ”„ Development Workflow

πŸ— Development Environment

# Start development server
npm run start-dev

# Features enabled:
# βœ… Hot Module Replacement (HMR)
# βœ… Source Maps for debugging
# βœ… Development optimizations
# βœ… Error overlay in browser
# βœ… Automatic browser refresh

Development Features:

  • Port: 3000 (configurable)
  • Hot Reload: Instant code changes reflection
  • Source Maps: Enhanced debugging experience
  • Error Overlay: In-browser error display
  • CSS Hot Reload: Styles update without page refresh

πŸš€ Production Build

# Create optimized production build
npm run build

# Build optimizations:
# βœ… Code minification & compression
# βœ… Asset optimization
# βœ… Bundle splitting
# βœ… Tree shaking (dead code elimination)
# βœ… CSS extraction & optimization

Production Features:

  • Output Directory: dist/
  • Minification: JavaScript & CSS compressed
  • Asset Optimization: Images & fonts optimized
  • Bundle Analysis: Generated bundle stats
  • Source Maps: Production-ready source maps

🌐 Serve Production Locally

# Serve production build
npm run serve

# Server configuration:
# πŸ“ Port: 8080
# πŸ”§ Static file serving
# 🌍 Production environment simulation

βš™οΈ Webpack Configuration Details

Common Configuration (webpack.common.js)

module.exports = {
  entry: {
    app: "./src/scripts/index.js" // Application entry point
  },

  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html" // HTML template
    }),
    new CopyWebpackPlugin({
      patterns: [
        {
          from: "./src/public/", // Static assets
          to: "./dist/"
        }
      ]
    })
  ],

  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif)$/i,
        type: "asset/resource" // Asset handling
      }
    ]
  }
};

Development Configuration (webpack.dev.js)

module.exports = merge(common, {
  mode: "development",

  devServer: {
    static: "./dist",
    port: 3000,
    hot: true, // Hot Module Replacement
    client: {
      overlay: {
        errors: true, // Show errors in browser
        warnings: true
      }
    }
  },

  devtool: "eval-source-map" // Fast source maps
});

Production Configuration (webpack.prod.js)

module.exports = merge(common, {
  mode: "production",

  plugins: [
    new CleanWebpackPlugin(), // Clean dist folder
    new MiniCssExtractPlugin() // Extract CSS
  ],

  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: [
          {
            loader: "babel-loader",
            options: {
              presets: ["@babel/preset-env"] // ES6+ transpilation
            }
          }
        ]
      }
    ]
  }
});

πŸ”§ Development Tools & Scripts

Available Scripts

{
  "scripts": {
    "start-dev": "webpack serve --config webpack.dev.js",
    "build": "webpack --config webpack.prod.js",
    "serve": "http-server dist",
    "lint": "prettier --check src/",
    "format": "prettier --write src/"
  }
}

Code Quality Tools

# Code formatting with Prettier
npm run format                # Format all files
npm run lint                  # Check formatting

# Manual formatting commands
npx prettier --write "src/**/*.{js,css,html}"
npx prettier --check "src/**/*.{js,css,html}"

πŸ“Š Build Analysis

# Analyze bundle size
npm run build -- --analyze

# Bundle composition:
# πŸ“¦ Main bundle: Application code
# πŸ“¦ Vendor bundle: Third-party libraries
# πŸ“¦ CSS bundle: Extracted stylesheets
# πŸ“¦ Assets: Images, fonts, static files

πŸ” Debugging Guide

Development Debugging

// Source maps enabled - use browser DevTools
console.log("Debug info:", data);

// Breakpoints work in original source files
debugger;

// Hot reload preserves state
if (module.hot) {
  module.hot.accept();
}

Production Debugging

# Serve production build locally
npm run serve

# Check production issues
# Source maps available for debugging
# Performance profiling available

🎯 Performance Optimization

Development Performance

  • ⚑ Fast Builds: Optimized for development speed
  • πŸ”„ Incremental Compilation: Only changed files rebuild
  • πŸ“¦ Module Caching: Faster subsequent builds

Production Performance

  • πŸ—œ Code Splitting: Lazy loading for better performance
  • 🌳 Tree Shaking: Remove unused code
  • πŸ“¦ Asset Optimization: Compressed images & fonts
  • πŸ”§ Minification: Reduced bundle sizes

🚨 Common Development Issues

Issue Solution
Port in use npx webpack serve --port 3001
Module not found rm -rf node_modules && npm install
Hot reload broken Check firewall/proxy settings
Build failing Clear cache: rm -rf dist/ && npm run build
CSS not updating Hard refresh: Ctrl+Shift+R

πŸ§ͺ Testing

πŸ”§ Testing Setup (Planned)

# Install testing dependencies
npm install --save-dev jest @testing-library/dom @testing-library/jest-dom

# Run tests
npm test

# Watch mode
npm run test:watch

# Coverage report
npm run test:coverage

πŸ“ Testing Strategy

  • Unit Tests: Component logic testing
  • Integration Tests: API integration testing
  • E2E Tests: User workflow testing
  • Visual Tests: UI component testing

πŸš€ Deployment

🌐 GitHub Pages Deployment

# Build for production
npm run build

# Deploy to GitHub Pages
npm install --save-dev gh-pages
npx gh-pages -d dist

☁️ Cloud Platform Deployment

Netlify

# Build command: npm run build
# Publish directory: dist
# Environment variables: Set in Netlify dashboard

Vercel

# Install Vercel CLI
npm install -g vercel

# Deploy
vercel --prod

AWS S3 + CloudFront

# Build and sync to S3
npm run build
aws s3 sync dist/ s3://your-bucket-name

🀝 Contributing

We welcome contributions from the community! Please follow these guidelines to contribute to Foodinary.

🌟 How to Contribute

  1. 🍴 Fork the Repository

    # Fork the repo on GitHub, then clone your fork
    git clone https://github.com/YOUR_USERNAME/frontend-backend.git
    cd frontend-backend
  2. 🌿 Create a Feature Branch

    # Create and switch to a new branch
    git checkout -b feature/your-feature-name
    # or for bug fixes
    git checkout -b fix/bug-description
  3. πŸ”§ Make Your Changes

    • Follow the existing code style
    • Add comments for complex logic
    • Test your changes thoroughly
  4. βœ… Test Your Changes

    # Run the development server
    npm run start-dev
    
    # Test your changes manually
    # Ensure no console errors
  5. πŸ“ Commit Your Changes

    # Stage your changes
    git add .
    
    # Commit with descriptive message
    git commit -m "feat: add new recipe filter functionality"
  6. πŸš€ Push and Create Pull Request

    # Push to your fork
    git push origin feature/your-feature-name
    
    # Create pull request on GitHub

πŸ“‹ Contribution Guidelines

Code Style

  • Use ES6+ JavaScript features
  • Follow camelCase naming convention
  • Use meaningful variable names
  • Add JSDoc comments for functions
  • Maintain consistent indentation (2 spaces)

Commit Message Format

type(scope): description

Examples:
feat(auth): add password reset functionality
fix(recipe): resolve search filter bug
docs(readme): update installation guide
style(css): improve responsive design
refactor(api): optimize data fetching

Pull Request Guidelines

  • Title: Clear, descriptive title
  • Description: Explain what changes were made and why
  • Screenshots: Include screenshots for UI changes
  • Testing: Describe how you tested the changes
  • Breaking Changes: Highlight any breaking changes

πŸ› Bug Reports

When reporting bugs, please include:

**Bug Description**
A clear description of the bug

**Steps to Reproduce**

1. Go to '...'
2. Click on '...'
3. See error

**Expected Behavior**
What you expected to happen

**Screenshots**
If applicable, add screenshots

**Environment:**

- OS: [e.g. Windows 10]
- Browser: [e.g. Chrome 96]
- Node.js version: [e.g. 16.14.0]

πŸ’‘ Feature Requests

For new features, please include:

**Feature Description**
Clear description of the feature

**Use Case**
Why is this feature needed?

**Proposed Solution**
How should it work?

**Additional Context**
Any other relevant information

πŸ” Development Setup for Contributors

# 1. Clone your fork
git clone https://github.com/YOUR_USERNAME/frontend-backend.git
cd frontend-backend

# 2. Add upstream remote
git remote add upstream https://github.com/foodinary-project/frontend-backend.git

# 3. Install dependencies
npm install

# 4. Start development server
npm run start-dev

# 5. Keep your fork synced
git fetch upstream
git checkout main
git merge upstream/main

πŸ“š Areas for Contribution

🎨 Frontend Improvements

  • UI/UX enhancements
  • Responsive design improvements
  • New page components
  • Animation and interactions

πŸ”§ Feature Development

  • New recipe filters
  • User profile enhancements
  • Social sharing features
  • Offline functionality

πŸ“± Performance Optimization

  • Bundle size optimization
  • Loading speed improvements
  • Caching strategies
  • Progressive Web App features

πŸ“– Documentation

  • API documentation
  • Code comments
  • Tutorial creation
  • Translation

πŸ§ͺ Testing

  • Unit test creation
  • Integration testing
  • E2E test scenarios
  • Performance testing

πŸ† Recognition

Contributors will be:

  • Credited in the project contributors list
  • Mentioned in release notes for significant contributions
  • Featured on our team page for ongoing contributors

πŸ™ Acknowledgments

🌟 Special Thanks

  • Indonesian Culinary Heritage - For the rich cultural inspiration
  • Open Source Community - For the amazing tools and libraries
  • Webpack Team - For the powerful build system
  • SweetAlert2 - For beautiful user interactions
  • Font Awesome - For comprehensive icon library

πŸ“š Resources & Inspiration

  • Indonesian Recipe Database - Traditional recipe sources
  • Cultural Research - Indonesian culinary history
  • Design Inspiration - Modern web design trends
  • Technical Documentation - MDN Web Docs, Webpack Documentation

πŸ›  Technologies We Love

  • JavaScript ES6+ - Modern web development
  • CSS3 - Beautiful styling capabilities
  • HTML5 - Semantic web structure
  • Webpack - Powerful module bundling
  • Node.js - JavaScript runtime excellence

🍲 Made with ❀️ for Indonesian Culinary Heritage

⬆ Back to Top


Β© 2025 Foodinary Team. All rights reserved.

About

This is the repository of website for Foodinary

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •