Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
ab7096a
Add root .gitignore to ignore secrets and builds
DevByRico Sep 6, 2025
31935db
Replace old scaffold with client/server app; add .gitignore and env e…
DevByRico Sep 6, 2025
83d1fbc
Add netlify spa redirects
DevByRico Sep 6, 2025
e6da951
readme
DevByRico Sep 6, 2025
5e2ce3b
readme fix
DevByRico Sep 6, 2025
84671a8
readme fix1
DevByRico Sep 6, 2025
ee10fd9
readme fix2
DevByRico Sep 6, 2025
601efd7
Refactor: cleaned and organized code structure based on feedback
DevByRico Oct 18, 2025
5e224c4
Fix: added trust proxy for Render
DevByRico Oct 18, 2025
388960b
Cleaned middleware duplicates and finalized trust proxy fix
DevByRico Oct 18, 2025
f61d970
Add Node engine and finalize server config for Render
DevByRico Oct 18, 2025
b907104
Fix: set trust proxy to 1 for safe rate limit handling on Render
DevByRico Oct 18, 2025
257eac3
Fix: updated API base env variable to match Netlify config
DevByRico Oct 18, 2025
29e8e75
Fix: remove duplicate providers and restore navigation
DevByRico Oct 18, 2025
17d7765
Fix: router context error and update react-router-dom
DevByRico Oct 18, 2025
68864a7
Fix: update react-router and react version to resolve navigation bug
DevByRico Oct 18, 2025
8069d8b
Fix router navigation crash (t is not a function)
DevByRico Oct 18, 2025
52e59e9
Fix: remove double BrowserRouter to fix navigation
DevByRico Oct 18, 2025
593371b
Fix: restore providers but keep single BrowserRouter
DevByRico Oct 18, 2025
be2e793
Fix booking navigation and add modern styled DetailsPage with 'Other'…
DevByRico Oct 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 21 additions & 12 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
node_modules
.DS_Store
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
# --- Node ---
node_modules/
npm-debug.log*
yarn.lock
pnpm-lock.yaml

build
# --- Build artifacts ---
client/dist/
server/dist/
*.log

npm-debug.log*
yarn-debug.log*
yarn-error.log*
# --- Env (secrets) ---
.env
*.env
client/.env
server/.env

# --- OS cruft ---
.DS_Store
Thumbs.db

package-lock.json
# --- Editor ---
.vscode/
.idea/
1 change: 0 additions & 1 deletion Procfile

This file was deleted.

13 changes: 0 additions & 13 deletions README.md

This file was deleted.

97 changes: 97 additions & 0 deletions README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Barber Booking – Final Project

A full-stack barber appointment app with real-time slot availability, email confirmations (ICS calendar invite), and a protected admin dashboard.

**Live site:** https://barber-rico.netlify.app
**API (Render):** https://project-final-it0v.onrender.com

---

## ✨ Features
- Fast client (Vite + React + Tailwind)
- Dark/Light theme toggle (persistent)
- Calendar with available time slots (30-min steps)
- Booking flow with confirmation screen
- Email confirmation with .ics calendar attachment
- Admin dashboard (JWT protected): list, toggle status, delete bookings
- Basic rate limiting, Helmet, and CORS
- SEO & PWA essentials (favicons, manifest, social meta)

---

## 🧱 Tech Stack

**Frontend**
- React, React Router
- Tailwind CSS
- Vite

**Backend**
- Node.js, Express
- MongoDB (Mongoose)
- Nodemailer (Mailtrap in dev)
- JWT auth

**Hosting**
- Frontend: Netlify
- Backend: Render

---

## 📁 Project Structure

```bash
project-final/
├─ client/ # React app (Vite)
│ ├─ public/ # favicons, manifest, apple-touch-icon, logo.png
│ ├─ src/
│ │ ├─ components/ # Header, ThemeToggle, ProtectedRoute, ...
│ │ ├─ pages/ # SelectTime, DetailsPage, ConfirmPage, Admin*
│ │ ├─ brand.js, lib.js, main.jsx, App.jsx, index.css, ...
│ └─ index.html
└─ server/ # Express API
├─ index.js # API routes, mail, DB
├─ package.json
└─ .env # 🔒 private environment variables (not in git)
```

**Booking schema:**
```js
// Unique index prevents double-booking
bookingSchema.index({ date: 1, time: 1 }, { unique: true });
```

---

## 🔒 Security
- Admin JWT stored in **sessionStorage** (clears when closing the tab)
- `helmet`, `cors` (restrict origin), `rate-limit`
- Unique DB index on date+time to stop double-booking
- **Never commit `.env`** — include a `.env.example` with placeholders instead

---

## 🌐 SEO & UX
- Proper `<title>`, meta description, Open Graph, `site.webmanifest`
- `apple-touch-icon.png` (180×180) in `client/public/`
- Keep brand images in `public/` (e.g. `/logo.png`)
- Good contrast in dark mode; semantic HTML

---

## 🛠 Troubleshooting

- **Admin login returns blank / no redirect**
Ensure `JWT_SECRET` is set in `server/.env`; restart the server; check `/api/auth/login` in DevTools → Network.

- **CORS errors**
`CLIENT_URL` must match the client origin (e.g. `http://localhost:5173`).

- **MongoDB “EBADNAME / <cluster>”**
Replace placeholder `<cluster>` with the real cluster host in `MONGODB_URI`.

- **Emails not arriving**
Use Mailtrap **Sandbox** in dev; for production use `live.smtp.mailtrap.io:587` with `SMTP_USER=api` and your `SMTP_PASS` (API token). Avoid free Gmail “from” without SPF/DKIM.

- **409 “Time already booked”**
Someone took that slot. Choose another.
5 changes: 0 additions & 5 deletions backend/.babelrc

This file was deleted.

8 changes: 0 additions & 8 deletions backend/README.md

This file was deleted.

20 changes: 0 additions & 20 deletions backend/package.json

This file was deleted.

22 changes: 0 additions & 22 deletions backend/server.js

This file was deleted.

8 changes: 8 additions & 0 deletions client/.env.local
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Var din frontend ska anropa API:t i dev
VITE_API_BASE=http://localhost:5000

# Varumärke i UI och flikar
VITE_BRAND_NAME="Bästa barbern"

# (Valfritt) Om du vill överskrida loggan via URL i stället för import:
# VITE_LOGO_URL=/logo-barber.png
38 changes: 38 additions & 0 deletions client/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!-- client/index.html -->
<!doctype html>
<html lang="sv">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />

<title>Bästa barbern – Boka</title>
<meta name="description" content="Boka klippning hos Bästa barbern. Skin fade, skägg, barnklippning och pensionärspriser. Enkelt bokningsflöde och snabb e-postbekräftelse." />
<link rel="canonical" href="http://localhost:5173/" />
<meta name="robots" content="index,follow" />
<meta property="og:title" content="Bästa barbern – Boka" />
<meta property="og:description" content="Boka klippning hos Bästa barbern. Skin fade, skägg, barnklippning och pensionärspriser." />
<meta property="og:type" content="website" />
<meta property="og:image" content="/web-app-manifest-512x512.png" />
<meta property="og:url" content="http://localhost:5173/" />
<meta name="theme-color" content="#0ea5e9" />

<link rel="icon" href="/favicon.ico" sizes="any" />
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
<link rel="manifest" href="/site.webmanifest" />
</head>
<body>
<div id="root"></div>

<script>
// Starta i ljusläge om inget finns lagrat
(function () {
const saved = localStorage.getItem('theme');
const root = document.documentElement;
if (saved === 'dark') root.classList.add('dark');
else root.classList.remove('dark');
})();
</script>

<script type="module" src="/src/main.jsx"></script>
</body>
</html>
Loading