From 89a9acd791565c428326269719de6d0247263d3c Mon Sep 17 00:00:00 2001 From: rosy Date: Fri, 30 Jan 2026 22:57:39 +0300 Subject: [PATCH 1/4] add readme file and a way to favorite restaurants --- README.md | 69 ++++ client/README.md | 74 +++- client/src/App.jsx | 2 + client/src/components/common/Popups.jsx | 35 -- client/src/components/home/FeaturedCard.jsx | 8 +- client/src/components/layout/Sidebar.jsx | 2 - .../owner/OwnerAddRestaurantForm.jsx | 107 +++++ .../src/components/owner/OwnerSignupForm.jsx | 2 +- .../components/restaurant/RestaurantCard.jsx | 8 +- .../src/components/restaurant/Reviewcard.jsx | 3 +- client/src/components/user/LoginForm.jsx | 8 +- client/src/context/AuthContext.jsx | 24 +- client/src/context/RestaurantsContext.jsx | 125 ++++-- client/src/pages/Favorites.jsx | 34 +- client/src/pages/OwnerDashboard.jsx | 73 ++++ client/src/pages/OwnerLoginPage.jsx | 4 +- client/src/pages/RestaurantDetailsPage.jsx | 7 +- client/src/pages/RestaurantListPage.jsx | 1 - client/src/pages/UserProfilePage.jsx | 32 +- client/src/pages/WriteReviewPage.jsx | 14 +- package.json | 6 +- server/README.md | 368 ++++++++++++++++++ server/models/Restaurant.js | 2 +- server/models/RestaurantOwner.js | 2 +- server/models/User.js | 2 +- server/routes/RestaurantApp.js | 57 +-- server/routes/RestaurantOwnersApp.js | 22 +- server/routes/UserApp.js | 57 ++- server/server.js | 2 +- server/utils/rating.js | 6 + 30 files changed, 928 insertions(+), 228 deletions(-) create mode 100644 README.md mode change 100755 => 100644 client/README.md delete mode 100644 client/src/components/common/Popups.jsx create mode 100644 client/src/components/owner/OwnerAddRestaurantForm.jsx create mode 100644 client/src/pages/OwnerDashboard.jsx create mode 100644 server/README.md create mode 100644 server/utils/rating.js diff --git a/README.md b/README.md new file mode 100644 index 0000000..debcba7 --- /dev/null +++ b/README.md @@ -0,0 +1,69 @@ +# find-addis + +**Short description:** find-addis is a small React + Express + MongoDB application to discover and review restaurants. The repo contains a `client` (React + Vite) and a `server` (Express + MongoDB) folder. + +--- + +## ⚙️ Structure + +- `client/` — React frontend (Vite) +- `server/` — Express API server (MongoDB) + +--- + +## 🔧 Quick start + +Prerequisites + +- Node 18+ / npm or yarn +- MongoDB (local or Atlas) + +Install + +```bash +# from repository root +npm install +# or install separately under each subfolder +cd client && npm install +cd ../server && npm install +``` + +Development + +Run both services concurrently (recommended) + +```bash +# from repository root (uses npm workspaces + concurrently) +npm install +npm run dev +``` + +Run individually (alternatives) + +```bash +# run server in dev (nodemon) +cd server && npm run dev +# run client in dev (Vite) +cd client && npm run dev +``` + +Production (build & serve frontend + run server) + +```bash +# build frontend +cd client && npm run build +# serve client/build with any static file server (Nginx, serve, etc.) or configure server to serve static files +# run server +cd server && npm start +``` + +--- + +## 📚 Contributing & Notes + +- Follow the existing code style and ESLint in `client/` (use `npm run lint`). +- If you add new env vars, document them in `server/.env.example` (see `server/README.md`). + +--- + +> For more details about usage, roadmap and endpoints, see `client/README.md` and `server/README.md`. diff --git a/client/README.md b/client/README.md old mode 100755 new mode 100644 index 18bc70e..a78d0b3 --- a/client/README.md +++ b/client/README.md @@ -1,16 +1,72 @@ -# React + Vite +# Client (React + Vite) — find-addis (Project README) -This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. +**Purpose:** This file documents how to run and build the frontend for the find-addis project. The app consumes the `find-addis` API (default `http://localhost:3000/api`). -Currently, two official plugins are available: +--- -- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh -- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh +## Functional Highlights -## React Compiler +- Browse restaurants, view details, filter by category/rating. +- Users: signup/login, add favorites, write reviews. +- Owners: signup/login, add restaurants, manage own restaurants. -The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation). +--- -## Expanding the ESLint configuration +## How to run (dev) -If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project. +1. Install + +```bash +cd client +npm install +``` + +2. Start dev server + +```bash +npm run dev +``` + +3. Open the app at the URL printed by Vite (usually `http://localhost:5173`). + +--- + +## Build & Preview (production) + +```bash +npm run build +npm run preview # or npm start +``` + +--- + +## Environment configuration + +- Recommended: add `VITE_API_URL` to `.env` to avoid hard-coded `http://localhost:3000` strings. + +Example `.env` + +``` +VITE_API_URL="http://localhost:3000" +``` + +--- + +## Linting + +```bash +npm run lint +``` + +--- + +--- + +## Configuration hygiene + +- Some files reference the API base URL directly (for example, `http://localhost:3000`). For production, centralize the base URL using `VITE_API_URL` and an HTTP client helper (see suggested `src/utils/api.js` above). +- Images are sent as base64; keep payloads within the server limit (default `5MB`) or use dedicated storage (e.g., S3 or Cloudinary) for large media. + +--- + +If you'd like, I can open a PR to replace the remaining direct API calls with the centralized helper and add `VITE_API_URL` to the repository's environment templates. diff --git a/client/src/App.jsx b/client/src/App.jsx index 4bcd35b..190f90a 100755 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -11,6 +11,7 @@ import SearchResultsPage from "./pages/SearchResultsPage"; import WriteReviewPage from "./pages/WriteReviewPage"; import Login from "./pages/Login"; import OwnerLoginPage from "./pages/OwnerLoginPage" +import OwnerDashboard from "./pages/OwnerDashboard"; import Signup from "./pages/Signup"; import OwnerSignUp from "./pages/OwnerSignup"; import UserProfilePage from "./pages/UserProfilePage"; @@ -46,6 +47,7 @@ function App() { } /> } /> } /> + } /> } /> } /> } /> diff --git a/client/src/components/common/Popups.jsx b/client/src/components/common/Popups.jsx deleted file mode 100644 index 772b4ce..0000000 --- a/client/src/components/common/Popups.jsx +++ /dev/null @@ -1,35 +0,0 @@ -import React, { useState, useRef, useEffect } from "react"; -import { Link } from "react-router-dom"; - -function PopupButton() { - const [open, setOpen] = useState(false); - const containerRef = useRef(null); - - // Close the popup if clicked outside - useEffect(() => { - const handleClickOutside = (event) => { - if (containerRef.current && !containerRef.current.contains(event.target)) { - setOpen(false); - } - }; - document.addEventListener("mousedown", handleClickOutside); - return () => document.removeEventListener("mousedown", handleClickOutside); - }, []); - - return ( -
- setOpen(!open)}>Sign up - - {open && ( -
- User - Owner -
- )} -
- ); -} - -export default PopupButton; \ No newline at end of file diff --git a/client/src/components/home/FeaturedCard.jsx b/client/src/components/home/FeaturedCard.jsx index 4e5422f..5aabf20 100755 --- a/client/src/components/home/FeaturedCard.jsx +++ b/client/src/components/home/FeaturedCard.jsx @@ -11,13 +11,11 @@ import TomocaImg from '../../assets/tomoca.png'; import Placeholder from "../../assets/addis-cafe.jpg"; -function FeaturedCard({ restaurant }) { +function FeaturedCard({ restaurant, showDeleteButton }) { - const { toggleFavorite, isFavorite } = useContext(RestaurantsContext); + const { toggleFavorite, isFavorite, deleteRestaurant } = useContext(RestaurantsContext); const fav = isFavorite ? isFavorite(restaurant._id) : false; - // const inputRef = useRef(null); - // const [uploading, setUploading] = useState(false); // Default images for known restaurants const defaults = { @@ -80,6 +78,8 @@ function FeaturedCard({ restaurant }) {
{restaurant.address &&
{restaurant.address}
} View + {showDeleteButton && } +
diff --git a/client/src/components/layout/Sidebar.jsx b/client/src/components/layout/Sidebar.jsx index f398e35..1caa1db 100755 --- a/client/src/components/layout/Sidebar.jsx +++ b/client/src/components/layout/Sidebar.jsx @@ -2,9 +2,7 @@ import React from "react"; import Dropdown from "../common/Dropdown"; function Sidebar({ filters, setFilters, restaurants }) { - console.log("Sidebar", restaurants) const uniqueCategories = [...new Set(restaurants.map(r => r.category))] - console.log('uniqueCategories', uniqueCategories) return (