یک سامانهی کامل، مدرن و ریسپانسیو برای رزرو آنلاین میز در کافهها و رستورانها، به همراه نقشهی تعاملی و احراز هویت پیامکی (OTP).
- 🗺️ نقشهی تعاملی Leaflet با مارکرهای کافهها، نمایش جزئیات روی Popup و حرکت خودکار به کافهی انتخابشده.
- 📱 احراز هویت OTP (پیامکی) — جریان سهمرحلهای: ورود شماره موبایل → دریافت کد ۴ رقمی → تکمیل پروفایل (برای کاربران جدید).
- 🏪 صفحهی جزئیات کافه با گالری تصویر، منو، ساعات کاری و موقعیت روی نقشه.
- 📅 فرم رزرو میز با انتخاب تاریخ شمسی، ساعت و تعداد نفرات، همراه با کد پیگیری یکتا.
- 📊 پنل مدیریت (Dashboard) با جدول رزروها، فیلتر بر اساس کافه/وضعیت، آمار کلی و تغییر وضعیت (تایید/لغو/در انتظار).
- 🎨 رابط کاربری کاملاً RTL و فارسی با فونت Vazirmatn و طراحی مدرن.
- 📱 کاملاً ریسپانسیو — روی موبایل، تبلت و دسکتاپ بهینه شده.
| لایه | تکنولوژی |
|---|---|
| فریمورک | Next.js 14 (App Router) + React 18 |
| زبان | TypeScript |
| استایل | Tailwind CSS 3 |
| نقشه | Leaflet + React-Leaflet + OpenStreetMap |
| دیتابیس | Prisma ORM + SQLite |
| آیکونها | Lucide React |
| احراز هویت | OTP شبیهسازیشده + Cookie/LocalStorage |
- Node.js نسخهی ۱۸ یا بالاتر
- npm یا yarn یا pnpm
# ۱. نصب وابستگیها
npm install
# ۲. ساخت دیتابیس SQLite و اعمال schema
npx prisma db push
# ۳. تولید Prisma Client
npx prisma generate
# ۴. وارد کردن دادههای اولیه (۵ کافه نمونه + ادمین)
npx prisma db seed
# یا: npx tsx prisma/seed.ts💡 فرمان
npm installبهصورت خودکارprisma generateرا اجرا میکند (به لطف hookpostinstall).
# حالت توسعه (Development)
npm run dev
# پروژه روی http://localhost:3000 در دسترس است
# ساخت نسخهی تولید
npm run build
# اجرای نسخهی تولید
npm startپس از اجرای seed، یک حساب ادمین پیشفرض ساخته میشود:
| نقش | شماره موبایل | توضیح |
|---|---|---|
| مدیر (admin) | 09120000000 |
دسترسی به همهی رزروها در پنل مدیریت |
⚠️ نکته دربارهی کد OTP: برای تسهیل تست، کد ۴ رقمی تولیدشده بهجای ارسال پیامک واقعی، در یک Toast (نوتیفیکیشن) در پایین صفحه نمایش داده میشود. به همین دلیل نیازی به پنل پیامک واقعی نیست.
برای ورود با هر شمارهی دلخواه (مثلاً 09123456789) کافیست مراحل را طی کنید؛ کاربر جدید بهصورت خودکار ساخته میشود.
CafeReservation/
├── app/
│ ├── api/
│ │ ├── auth/
│ │ │ ├── otp/route.ts # ارسال، تایید و تکمیل ثبتنام OTP + خروج
│ │ │ └── me/route.ts # دریافت کاربر فعلی از کوکی
│ │ ├── cafes/
│ │ │ ├── route.ts # GET (لیست+جستجو) / POST (ایجاد)
│ │ │ └── [id]/route.ts # GET جزئیات یک کافه
│ │ └── reservations/
│ │ ├── route.ts # GET (لیست+فیلتر) / POST (ثبت رزرو)
│ │ └── [id]/route.ts # PATCH (تغییر وضعیت) / DELETE
│ ├── cafes/
│ │ └── [id]/page.tsx # صفحهی جزئیات کافه + فرم رزرو
│ ├── dashboard/
│ │ └── page.tsx # پنل مدیریت رزروها
│ ├── layout.tsx # ریشهی layout با RTL و Provider ها
│ ├── page.tsx # صفحهی اصلی (نقشه + لیست کافهها)
│ └── globals.css # استایلهای سراسری + Tailwind + Leaflet
├── components/
│ ├── AuthContext.tsx # Context مدیریت نشست کاربر
│ ├── Navbar.tsx # هدر و ناوبری
│ ├── Map.tsx # نقشهی تعاملی Leaflet
│ ├── CafeCard.tsx # کارت نمایش کافه
│ ├── OtpModal.tsx # مودال ورود OTP سهمرحلهای
│ ├── ReservationForm.tsx # فرم رزرو میز
│ ├── Toast.tsx # سیستم نوتیفیکیشن
│ └── PublicMarkerIcon.tsx # آیکون مارکر سفارشی
├── lib/
│ ├── prisma.ts # اتصال singleton به Prisma
│ ├── auth.ts # توابع نشست (getCurrentUser و ...)
│ ├── mockData.ts # دادهی نمونه ۵ کافه
│ ├── phoneUtils.ts # توابع اعتبارسنجی موبایل
│ └── utils.ts # توابع کمکی (تاریخ شمسی، OTP و ...)
├── prisma/
│ ├── schema.prisma # مدلهای User, Cafe, Reservation, OtpCode
│ └── seed.ts # اسکریپت seed دادهی اولیه
├── package.json
├── tailwind.config.ts
├── tsconfig.json
└── next.config.mjs
| فیلد | نوع | توضیح |
|---|---|---|
| id | String | شناسهی یکتا (cuid) |
| phone | String | شماره موبایل (یکتا) |
| name | String? | نام و نام خانوادگی |
| role | String | "user" یا "admin" |
| فیلد | نوع | توضیح |
|---|---|---|
| id | String | شناسهی یکتا |
| name, description, address | String | اطلاعات پایه |
| lat, lng | Float | مختصات جغرافیایی |
| image, menu | String? | تصویر و منو |
| tablesCount, openTime, closeTime | - | ظرفیت و ساعات کاری |
| rating | Float | امتیاز (۰ تا ۵) |
| فیلد | نوع | توضیح |
|---|---|---|
| id | String | شناسهی یکتا |
| trackingCode | String | کد پیگیری یکتا |
| userId, cafeId | String | روابط |
| date | String | تاریخ شمسی (مثل 1403/07/05) |
| time | String | ساعت (مثل 20:30) |
| guests | Int | تعداد نفرات |
| status | String | pending / confirmed / cancelled |
| note | String? | یادداشت اختیاری |
| فیلد | نوع | توضیح |
|---|---|---|
| id | String | شناسهی یکتا |
| phone | String | شماره موبایل |
| code | String | کد ۴ رقمی |
| verified | Boolean | وضعیت تایید |
| expiresAt | DateTime | زمان انقضا (۵ دقیقه) |
- در صفحهی اصلی روی دکمهی «ورود / ثبتنام» کلیک کنید.
- شماره موبایل وارد کنید و کد نمایشدادهشده در Toast را وارد کنید.
- روی نقشه یا لیست، کافهی دلخواه را پیدا کنید.
- وارد صفحهی کافه شوید و فرم رزرو را پر کنید.
- کد پیگیری رزرو را ذخیره کنید!
- با شمارهی
09120000000وارد شوید (نقش ادمین). - به صفحهی «پنل مدیریت» بروید.
- رزروها را فیلتر و مدیریت کنید (تایید، لغو یا بازگرداندن به حالت در انتظار).
- جلوگیری از خطای SSR در Leaflet: کامپوننت
Mapباnext/dynamicو گزینهی{ ssr: false }بارگذاری میشود تا مشکلی در Server-Side Rendering پیش نیاید. - تبدیل تاریخ میلادی به شمسی: تابع
toJalaliدرlib/utils.tsبهصورت دستی پیادهسازی شده و نیازی به کتابخانهی خارجی ندارد. - اتصال singleton به Prisma: برای جلوگیری از باز شدن اتصالهای مکرر در محیط توسعه، از الگوی globalThis استفاده شده است.
- RTL کامل: تمام کامپوننتها راستچین طراحی شدهاند و فونت Vazirmatn از CDN بارگذاری میشود.
- نقشه از OpenStreetMap: نیازی به API key نیست و کاملاً رایگان است.
| فرمان | توضیح |
|---|---|
npm run dev |
اجرای حالت توسعه |
npm run build |
ساخت نسخهی تولید |
npm start |
اجرای نسخهی تولید |
npm run db:push |
اعمال schema روی دیتابیس |
npm run db:seed |
اجرای seed دادهی اولیه |
این پروژه بهعنوان پروژهی پایانی مقطع کارشناسی مهندسی کامپیوتر طراحی شده و نشاندهندهی تسلط بر مفاهیم زیر است:
- توسعهی Full-Stack با Next.js App Router
- طراحی دیتابیس رابطهای با Prisma ORM
- پیادهسازی احراز هویت (OTP)
- کار با نقشههای تعاملی و مختصات جغرافیایی
- طراحی رابط کاربری مدرن و ریسپانسیو (RTL)
- معماری API سمت سرور (Route Handlers)
ساختهشده با ❤️ — موفق باشید! 🎓