برنامه نویسی

ساخت یک پلت فرم میزبانی رویداد مقیاس پذیر با NestJS، TypeORM و معماری مدولار

Summarize this content to 400 words in Persian Lang
برای توسعه یک بستر میزبانی رویداد مجازی با استفاده از Next.js 14 و Tailwind CSS، شما نیاز به تفکیک واضحی از ویژگی‌ها و عملکردها برای جنبه‌های جلویی، بک‌اند و برنامه تلفن همراه پروژه خود دارید. در اینجا یک طرح کلی از ویژگی ها و عملکردهای هر جزء آورده شده است:

1. ویژگی های Front-End (Next.js 14 + Tailwind CSS)

ایجاد رویداد:

فرم رویداد: به کاربران امکان می دهد رویدادهایی را با ورودی هایی برای نام رویداد، توضیحات، تاریخ، زمان، قیمت و دسته ایجاد کنند.

بارگذاری رسانه رویداد: ادغام با فضای ذخیره سازی ابری (به عنوان مثال، AWS S3) برای آپلود تصاویر یا ویدیوها برای رویداد.

مدیریت بلیط: انواع مختلف بلیط (پذیرش عمومی، VIP و غیره) را ایجاد کنید، قیمت ها و در دسترس بودن را تعیین کنید.

پیش نمایش رویداد: یک گزینه پیش نمایش که به سازمان دهندگان امکان می دهد قبل از انتشار صفحه رویدادشان را ببینند.

صفحات بهینه شده سئو: هر صفحه رویداد باید دارای ابرداده مناسب برای دید بهتر در موتورهای جستجو باشد.

طراحی واکنشگرا: با استفاده از Tailwind CSS از تجربه یکپارچه در همه دستگاه‌ها اطمینان حاصل کنید و اطمینان حاصل کنید که چیدمان با صفحه‌نمایش‌های موبایل، تبلت و دسکتاپ سازگار است.

خرید بلیط:

احراز هویت: OAuth و ادغام ورود به سیستم اجتماعی برای کاربران برای ایجاد حساب یا ورود به سیستم برای خرید بلیط.

انتخاب بلیط: کاربران می توانند بلیط های رویداد را انتخاب کرده و به پرداخت ادامه دهند.

یکپارچه سازی درگاه پرداخت: ادغام با Stripe، PayPal یا موارد مشابه برای پرداخت های ایمن.

خلاصه سفارش: نمایش انتخاب نهایی بلیط و قیمت با خلاصه سفارش قبل از تایید.

تایید ایمیل: یک ایمیل تأیید با جزئیات بلیط و یک کد QR ارسال کنید.

پخش زنده:

پخش کننده ویدیوی جاسازی شده: پخش‌های زنده را مستقیماً در صفحه رویداد جاسازی کنید، احتمالاً از طریق ادغام با پلتفرم‌های جریان (یوتیوب، ویمئو یا سرور RTMP سفارشی).

پخش در زمان واقعی: از WebRTC یا یک سرویس شخص ثالث (به عنوان مثال، Agora، Twilio) برای پخش جریانی با تاخیر کم و در زمان واقعی استفاده کنید.

چت زنده: چت بیدرنگ در طول رویداد با استفاده از WebSockets (به عنوان مثال، Socket.io یا Pusher).

انتخاب کیفیت جریان: به کاربران اجازه دهید بر اساس پهنای باند خود کیفیت های مختلف پخش (خودکار، 480p، 720p، 1080p) را انتخاب کنند.

2. ویژگی های Back-End (Next.js 14 مسیرهای API / توابع بدون سرور)

مدیریت رویداد:

عملیات CRUD رویداد: سازمان‌دهندگان می‌توانند رویدادها را ایجاد، به‌روزرسانی و حذف کنند. این شامل مدیریت جزئیات رویداد، انواع بلیط، و در دسترس بودن بلیط است.

پردازش پرداخت: اطلاعات پرداخت را ایمن مدیریت کنید، از تراکنش‌های موفق اطمینان حاصل کنید، و رسید پرداخت را ایجاد کنید.

مدیریت کاربر: حساب های کاربری، نمایه ها و کنترل دسترسی مبتنی بر نقش را مدیریت کنید (مثلاً سازمان دهندگان رویداد در مقابل شرکت کنندگان).

داشبورد تجزیه و تحلیل: به سازمان‌دهندگان رویداد اطلاعاتی در مورد فروش بلیت، شرکت‌کنندگان و مشارکت در جریان ارائه دهید.

درگاه پرداخت:

ادغام با Stripe یا PayPal: رسیدگی به تمام تراکنش های پرداخت با بازپرداخت و اختلافات.

گزارش پرداخت: جزئیات تراکنش، از جمله وضعیت پرداخت، روش، مبلغ و جزئیات مشتری را ذخیره کنید.

اعتبار سنجی بلیط: به صورت خودکار کدهای QR یا بارکدهای منحصر به فرد را برای هر بلیط خریداری شده برای دسترسی به رویداد ایجاد کنید.

اطلاعیه ها:

اعلان های ایمیل: هشدارهای ایمیلی را برای به روز رسانی رویداد، خرید بلیط و یادآوری رویداد (به عنوان مثال، SendGrid یا AWS SES) راه اندازی کنید.

اعلان های پیامکی: با Twilio یا خدمات مشابه یکپارچه شوید تا اعلان های پیامکی برای تأیید بلیط یا یادآوری رویداد ارسال شود.

Push Notifications: برای به‌روزرسانی رویدادها و یادآوری‌ها برای کاربرانی که انتخاب می‌کنند، با Firebase Cloud Messaging ادغام شود.

3. ویژگی های اپلیکیشن موبایل (React Native یا Expo)

مرور رویداد:

لیست رویدادها: نمایش تمام رویدادهای آینده و گذشته با گزینه های جستجو و فیلتر.

صفحه جزئیات رویداد: نمایش اطلاعات دقیق برای هر رویداد، از جمله گزینه خرید بلیط.

رابط کاربری پاسخگو: برنامه باید با اندازه های مختلف صفحه نمایش دستگاه تلفن همراه سازگار شود.

مشارکت در رویداد:

به رویداد مجازی بپیوندید: به کاربران اجازه می دهد تا مستقیماً از طریق برنامه از طریق جریان جاسازی شده به یک رویداد زنده بپیوندند.

بلیط درون برنامه ای: کاربران می توانند با یک فرآیند پرداخت ساده، بلیط را از طریق برنامه خریداری کنند.

پرسش و پاسخ زنده: بخش اختصاصی برای ارسال سوالات در طول رویدادهای زنده (WebSockets یا یک سرویس شخص ثالث).

نظرسنجی و نظرسنجی زنده: ویژگی‌های تعامل بی‌درنگ مانند نظرسنجی در طول رویداد برای افزایش تعامل.

اطلاعیه ها:

یادآوری رویداد: قبل از زمان شروع رویداد، اعلان‌ها را برای یادآوری رویداد فشار دهید.

به روز رسانی در زمان واقعی: اعلان‌های فشاری برای به‌روزرسانی رویداد یا اعلان‌های تعامل زنده در طول رویداد.

4. ویژگی های عمومی

جستجو و فیلتر کردن: جستجوی متن کامل در رویدادها و فیلترها بر اساس طبقه بندی، قیمت، تاریخ و محبوبیت.

احراز هویت کاربر و پروفایل ها: ادغام با ارائه دهندگان OAuth (گوگل، فیسبوک و غیره) برای احراز هویت کاربر. کاربران می توانند نمایه های خود را به روز کنند، تاریخچه خرید را مشاهده کنند و اعلان ها را مدیریت کنند.

داشبورد مدیریت: بخش اختصاصی برای سرپرستان برای نظارت بر کل پلتفرم (مدیریت کاربر، نظارت رویداد، تجزیه و تحلیل).

امنیت و مقیاس پذیری: پیاده سازی OAuth برای مدیریت کاربر و راه حل های مقیاس پذیر برای پخش و تهیه بلیط.

5. اسناد و منابع برای پیاده سازی

Next.js 14:

استفاده کنید روتر برنامه برای ساخت مسیرهای پویا و رندر صفحات با استفاده از مؤلفه های سرور و کلاینت 【7†source】.
پیاده سازی کنید Tailwind CSS برای یک ظاهر طراحی شده (Next.js پشتیبانی داخلی از Tailwind CSS را ارائه می دهد)【7†منبع】.
دنبال کنید Next.js بهترین شیوه ها برای سئو، رندر سمت سرور (SSR)، تولید استاتیک (SSG)، و رندر سمت مشتری (CSR)【7†منبع】.

Tailwind CSS:

طراحی پاسخگو و اولین رویکرد کاربردی برای ساده سازی ساخت UI در سراسر پلتفرم.

پخش جریانی:

به خدماتی مانند در حال حاضر، تویلیو، یا WebRTC برای اجرای جریان بلادرنگ【6†منبع】.

API:

می توانید استفاده کنید مسیرهای API Next.js برای مدیریت منطق بک‌اند برای خرید بلیط، مدیریت رویداد، و اعلان‌ها【7†منبع】.

با این تفکیک، اکنون می توانید ساختن پلتفرم میزبانی رویداد مجازی خود را با تمرکز بر تجربه کاربر، تعامل در زمان واقعی و مقیاس پذیری شروع کنید.

برای پیشانی از پلتفرم میزبانی رویداد مجازی خود با استفاده از Next.js 14 و Tailwind CSS، ساختار پوشه باید از قراردادهای مدولار بودن، مقیاس پذیری و قابلیت نگهداری پیروی کند. در اینجا یک ساختار پوشه پیشنهادی وجود دارد:

/your-project-name

├── /app # Main directory for Next.js App Router (used for routes and pages)
│ ├── /(event) # Event-related routes grouped here
│ │ ├── create # Event creation page
│ │ │ ├── page.tsx # Main page file for creating events
│ │ ├── [eventId] # Dynamic route for a specific event’s details
│ │ │ ├── page.tsx # Event details page
│ │ ├── live # Page for live streaming
│ │ │ ├── page.tsx # Live streaming page
│ │ ├── list # List of all events
│ │ │ ├── page.tsx # Event listing page
│ │ ├── qna # Page for live Q&A during events
│ │ ├── page.tsx # Live Q&A page
│ │
│ ├── /(user) # Group for user-related routes
│ │ ├── profile # User profile page
│ │ │ ├── page.tsx # Profile page component
│ │ ├── login # User login page
│ │ │ ├── page.tsx # Login page component
│ │ ├── register # User registration page
│ │ ├── page.tsx # Registration page component
│ │
│ ├── layout.tsx # Global layout for shared UI (header, footer, etc.)
│ ├── global.css # Global CSS (where Tailwind’s @import goes)
│ └── _app.tsx # Custom App component for handling global state

├── /components # Reusable UI components
│ ├── EventCard.tsx # Card component for displaying event info
│ ├── Navbar.tsx # Navigation bar component
│ ├── Footer.tsx # Footer component
│ ├── Button.tsx # Generic Button component
│ ├── Modal.tsx # Modal component for popups
│ └── Loader.tsx # Loader component for loading states

├── /hooks # Custom React hooks
│ ├── useAuth.ts # Hook for authentication management
│ ├── useEvent.ts # Hook for fetching and managing event data
│ └── useStream.ts # Hook for handling live stream interactions

├── /lib # Utilities and helper functions
│ ├── api.ts # API calls to back-end services
│ └── validators.ts # Validation functions for forms

├── /public # Static assets like images, icons, and fonts
│ ├── /images # Image assets for events, logos, etc.
│ ├── favicon.ico # Favicon for the app
│ └── logo.png # Application logo

├── /styles # Additional global styles (if needed)
│ ├── tailwind.config.js # Tailwind CSS configuration file
│ ├── globals.css # Global styles (optional, Tailwind CSS covers most)

├── /types # TypeScript types
│ ├── event.ts # Type definitions for event-related data
│ └── user.ts # Type definitions for user data

├── next.config.js # Next.js configuration file
├── tailwind.config.js # Tailwind CSS configuration file
├── tsconfig.json # TypeScript configuration
├── package.json # Dependencies and scripts
├── .eslintrc.js # ESLint configuration for linting
├── .prettierrc # Prettier configuration for code formatting
└── .gitignore # Files to be ignored by Git

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

تفکیک ساختار پوشه:

/app:

روتر برنامه ساختار پوشه توصیه شده برای Next.js است. هر پوشه در اینجا نشان دهنده یک مسیر است. را (event) و (user) گروه ها به ترتیب گروه های مسیری برای مسیرهای رویداد و مسیرهای مرتبط با کاربر هستند.

layout.tsx: یک فایل طرح بندی جهانی که می تواند اجزای مشترکی مانند نوار ناوبری و پاورقی را برای همه صفحات تعریف کند.

/components:

شامل تمام اجزای رابط کاربری قابل استفاده مجدد مانند دکمه ها، کارت ها و مدال ها است.
این امر استفاده مجدد و ماژولار بودن کد را تشویق می کند و مقیاس پروژه را آسان تر می کند.

/hooks:

قلاب‌های سفارشی را برای مدیریت منطق مانند احراز هویت، واکشی داده‌های رویداد و تعاملات پخش زنده ذخیره می‌کند.

/lib:

توابع و کمک‌کننده‌های ابزار، مانند فراخوانی‌های API یا تأییدکننده‌های فرم، که می‌توانند مجدداً در اجزای مختلف استفاده شوند.

/public:

حاوی دارایی های ثابت مانند تصاویر و نمادها است که مستقیماً توسط Next.js بدون پردازش ارائه می شوند.

/styles:

این پوشه حاوی هر سبک دیگری است که ممکن است به آن نیاز داشته باشید، اگرچه بیشتر استایل ها از طریق Tailwind CSS انجام می شود.
فایل پیکربندی Tailwind برای سفارشی سازی در اینجا زندگی می کند.

/types:

تعاریف نوع TypeScript را ذخیره می کند تا از تایپ قوی در سراسر برنامه برای نهادهایی مانند اطمینان حاصل کند event، userو غیره

فایل های پیکربندی:

next.config.js: پیکربندی مخصوص Next.js مانند بهینه سازی تصاویر، بسته وب سفارشی یا تنظیمات مسیریابی.

tailwind.config.js: برای پیکربندی Tailwind CSS برای گسترش آن با رنگ‌ها، فاصله‌ها و تم‌های سفارشی.

tsconfig.json: فایل پیکربندی TypeScript برای تنظیم قوانین برای کامپایل TypeScript.

package.json: وابستگی ها، اسکریپت ها و متا اطلاعات پروژه را مدیریت می کند.

نکات کلیدی:

روتر برنامه برای Next.js 14 استفاده می شود، پشتیبانی می کند اجزای سرور و مشتری، مسیریابی پویا، و جریان.

Tailwind CSS یک ظاهر طراحی شده را ساده می کند و طراحی واکنشگرا را در خارج از جعبه ترویج می کند.
گروه بندی پوشه (event، user) به سازماندهی منطقی مسیرهای مختلف کمک می کند که برای برنامه های بزرگ ضروری است.

این ساختار یک راه‌اندازی مدولار و مقیاس‌پذیر را فراهم می‌کند که نگهداری و گسترش آن را با رشد پلت فرم شما آسان می‌کند.

برای توسعه باطن برای شما بستر میزبانی رویداد مجازی با استفاده از NestJS و PostgreSQL، بسیار مهم است که پروژه خود را برای مقیاس پذیری، مدولار بودن و قابلیت نگهداری ساختار دهید. در زیر ساختار پوشه‌ای وجود دارد که کد شما را در ماژول‌های مبتنی بر ویژگی سازماندهی می‌کند و در عین حال به بهترین شیوه‌های NestJS پایبند است.

ساختار پوشه پیشنهادی برای NestJS Backend:

/your-backend-project

├── /src # Main source folder for the backend
│ ├── /auth # Module for authentication
│ │ ├── auth.controller.ts
│ │ ├── auth.module.ts
│ │ ├── auth.service.ts
│ │ ├── jwt.strategy.ts
│ │ ├── local.strategy.ts
│ │ ├── dto # DTOs for request validation
│ │ │ ├── login.dto.ts
│ │ │ ├── register.dto.ts
│ │ ├── guards # Guards for role-based access
│ │ │ ├── jwt-auth.guard.ts
│ │ │ ├── roles.guard.ts
│ │ ├── decorators # Custom decorators like roles
│ │ ├── roles.decorator.ts
│ ├── /users # User module for managing users
│ │ ├── users.controller.ts
│ │ ├── users.module.ts
│ │ ├── users.service.ts
│ │ ├── entities # TypeORM entity for users
│ │ │ ├── user.entity.ts
│ │ ├── dto # User-related DTOs
│ │ ├── create-user.dto.ts
│ │ ├── update-user.dto.ts
│ ├── /events # Event module for managing events
│ │ ├── events.controller.ts
│ │ ├── events.module.ts
│ │ ├── events.service.ts
│ │ ├── entities # TypeORM entity for events
│ │ │ ├── event.entity.ts
│ │ ├── dto # Event-related DTOs
│ │ ├── create-event.dto.ts
│ │ ├── update-event.dto.ts
│ ├── /tickets # Ticketing module for event tickets
│ │ ├── tickets.controller.ts
│ │ ├── tickets.module.ts
│ │ ├── tickets.service.ts
│ │ ├── entities # TypeORM entity for tickets
│ │ │ ├── ticket.entity.ts
│ │ ├── dto # DTOs for ticket-related operations
│ │ ├── create-ticket.dto.ts
│ │ ├── update-ticket.dto.ts
│ ├── /payments # Payment module for managing transactions
│ │ ├── payments.controller.ts
│ │ ├── payments.module.ts
│ │ ├── payments.service.ts
│ │ ├── entities # TypeORM entity for payments
│ │ │ ├── payment.entity.ts
│ │ ├── dto # Payment-related DTOs
│ │ ├── create-payment.dto.ts
│ ├── /notifications # Notifications module for email, SMS, and push notifications
│ │ ├── notifications.controller.ts
│ │ ├── notifications.module.ts
│ │ ├── notifications.service.ts
│ │ ├── dto # Notification-related DTOs
│ │ ├── create-notification.dto.ts
│ ├── /database # Database module for TypeORM configurations
│ │ ├── database.module.ts
│ │ ├── database.service.ts
│ │ ├── ormconfig.ts # TypeORM configuration
│ ├── /common # Shared utilities, guards, interceptors, and exceptions
│ │ ├── /filters # Global exception filters
│ │ │ ├── all-exceptions.filter.ts
│ │ ├── /interceptors # Interceptors for response transformation, logging, etc.
│ │ │ ├── transform.interceptor.ts
│ │ ├── /decorators # Reusable decorators
│ │ │ ├── api-response.decorator.ts
│ │ ├── /pipes # Global pipes for validation, etc.
│ │ │ ├── validation.pipe.ts
│ ├── app.module.ts # Root application module
│ ├── main.ts # Main entry point of the application

├── /test # Tests for the application
│ ├── /e2e # End-to-end tests
│ ├── /unit # Unit tests

├── /config # Configuration files for different environments
│ ├── config.ts # Configuration for database, security, etc.
├── .env # Environment variables
├── .eslintrc.js # ESLint configuration for linting
├── .prettierrc # Prettier configuration for code formatting
├── tsconfig.json # TypeScript configuration
├── package.json # Dependencies and scripts
├── README.md # Project documentation
└── .gitignore # Files and folders to ignore in Git

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

تفکیک ساختار پوشه:

/src:

دایرکتوری اصلی برای کل برنامه، همه ماژول‌ها، خدمات، کنترل‌کننده‌ها و موجودیت‌ها را در خود جای می‌دهد.

/auth:

دستگیره ها احراز هویت و مجوز.
شامل استراتژی هایی برای JWT و احراز هویت محلی، همراه با نگهبانان و دکوراتورهای سفارشی مانند @Roles.

/users:

دستگیره ها مدیریت کاربر، از جمله عملیات CRUD کاربر.
فروشگاه ها نهادهای کاربر و مرتبط DTO ها برای اعتبار سنجی درخواست

/events:

مدیریت می کند رویدادها از جمله ایجاد رویداد، به روز رسانی، و بازیابی.
حاوی رویداد خاص است نهادها و DTO ها.

/tickets:

مدیریت می کند بلیط رویداداز جمله ایجاد، به‌روزرسانی و بازیابی بلیط‌ها.
شامل نهادهای مخصوص بلیط و DTOها می شود.

/payments:

مدیریت می کند پردازش پرداخت و ادغام با درگاه های پرداخت مانند راه راه یا پی پال.
دستگیره ها ثبت تراکنش ها و عملیات مربوط به پرداخت

/notifications:

دستگیره ها ایمیل، اس ام اس و اعلان های فشاری.
با خدماتی مانند ادغام می شود تویلیو، Firebase، یا SendGrid برای اطلاعیه ها

/database:

مدیریت می کند اتصالات و تنظیمات پایگاه داده با استفاده از TypeORM.
فروشگاه ها تنظیمات ORM و ماژول پایگاه داده راه اندازی

/common:

حاوی خدمات مشترک مانند جهانی فیلترهای استثنا، رهگیرها، لوله ها، و دکوراتورها که می تواند دوباره در سراسر برنامه استفاده شود.

/test:

سازماندهی می کند تست های واحد و تست های پایان به انتها (e2e). با استفاده از است.

/config:

پیکربندی های خاص محیط را مدیریت می کند، از جمله رشته های اتصال پایگاه داده، کلیدهای API، و تنظیمات امنیتی.
استفاده می کند .env فایل هایی برای اطلاعات حساس

فایل های ریشه:

app.module.ts: ماژول ریشه که همه ماژول های دیگر را وارد می کند.

main.ts: نقطه ورود برنامه ای که سرور NestJS در آن بوت استرپ شده است.

.env: متغیرهای محیطی مانند اعتبار پایگاه داده، کلیدهای مخفی و غیره را ذخیره می کند.

مفاهیم کلیدی:

ماژول های ویژگی: NestJS ماژول های ویژگی را ارتقا می دهد، جایی که هر دامنه (به عنوان مثال، auth، users، events) دارای ماژول ایزوله شده خود است که برنامه را مقیاس پذیر و نگهداری آسان تر می کند.

TypeORM: برای مدیریت پایگاه داده، از جمله تعریف موجودیت ها (مانند User، Event، Ticket، Payment) و اجرای پرس و جوها با پایگاه داده PostgreSQL.

DTO ها: برای اعتبارسنجی ورودی و انتقال داده بین کنترلرها و سرویس ها استفاده می شود.

نگهبانان و رهگیران: به مدیریت احراز هویت درخواست، نقش‌ها و تبدیل‌های پاسخ کمک کنید.

تست کردن: شامل تست‌های واحد و e2e برای کنترل‌کننده‌ها، سرویس‌ها و ماژول‌ها برای اطمینان از عملکرد برنامه همانطور که انتظار می‌رود.

این ساختار تضمین می‌کند که باطن شما مقیاس‌پذیر، مدولار و نگهداری آسان در حین ساختن پلتفرم خود باشد.

در زیر ساختار کد کامل برای هر فایل ذکر شده در درخواست شما با استفاده از آن آمده است Next.js 14 و TypeScript. این شامل ایجاد رویدادها، نمایش جزئیات رویداد، مدیریت پخش زنده، فهرست کردن رویدادها، و صفحه پرسش و پاسخ برای رویدادهای مجازی است. این ساختار به دنبال دارد روتر برنامه Next.js کنوانسیون ها

نمای کلی ساختار پوشه

/app
├── /(event)
│ ├── create
│ │ └── page.tsx
│ ├── [eventId] │ │ └── page.tsx
│ ├── live
│ │ └── page.tsx
│ ├── list
│ │ └── page.tsx
│ ├── qna
│ └── page.tsx

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

1. صفحه ایجاد رویداد – /app/(event)/create/page.tsx

// /app/(event)/create/page.tsx
import React, { useState } from ‘react’;

const CreateEventPage: React.FC = () => {
const [formData, setFormData] = useState({
name: ”,
description: ”,
date: ”,
time: ”,
price: ”,
});

const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
const { name, value } = e.target;
setFormData((prevData) => ({
…prevData,
[name]: value,
}));
};

const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
console.log(‘Event Data:’, formData);
// Call an API to create the event
};

return (
<div className=”container mx-auto p-4″>
<h1 className=”text-2xl font-bold mb-4″>Create New Eventh1>
<form onSubmit={handleSubmit} className=”space-y-4″>
<div>
<label className=”block”>Event Namelabel>
<input
name=”name”
type=”text”
className=”w-full p-2 border rounded”
value={formData.name}
onChange={handleInputChange}
required
/>
div>
<div>
<label className=”block”>Descriptionlabel>
<textarea
name=”description”
className=”w-full p-2 border rounded”
value={formData.description}
onChange={handleInputChange}
required
/>
div>
<div>
<label className=”block”>Datelabel>
<input
name=”date”
type=”date”
className=”w-full p-2 border rounded”
value={formData.date}
onChange={handleInputChange}
required
/>
div>
<div>
<label className=”block”>Timelabel>
<input
name=”time”
type=”time”
className=”w-full p-2 border rounded”
value={formData.time}
onChange={handleInputChange}
required
/>
div>
<div>
<label className=”block”>Pricelabel>
<input
name=”price”
type=”number”
className=”w-full p-2 border rounded”
value={formData.price}
onChange={handleInputChange}
required
/>
div>
<button type=”submit” className=”bg-blue-500 text-white p-2 rounded”>Create Eventbutton>
form>
div>
);
};

export default CreateEventPage;

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

2. صفحه جزئیات رویداد – /app/(event)/[eventId]/page.tsx

// /app/(event)/[eventId]/page.tsx
import { useRouter } from ‘next/router’;
import React from ‘react’;

const EventDetailsPage: React.FC = () => {
const router = useRouter();
const { eventId } = router.query; // Accessing eventId from the route

// Fetch event details using eventId (replace with actual API call)
const event = {
id: eventId,
name: ‘Sample Event’,
description: ‘This is a description of the event.’,
date: ‘2024-10-30′,
time: ’14:00’,
price: 20,
};

return (
<div className=”container mx-auto p-4″>
<h1 className=”text-3xl font-bold”>{event.name}h1>
<p className=”mt-2″>{event.description}p>
<p className=”mt-4″>Date: {event.date}p>
<p className=”mt-1″>Time: {event.time}p>
<p className=”mt-4″>Price: ${event.price}p>
<button className=”bg-green-500 text-white p-2 rounded mt-4″>Buy Ticketsbutton>
div>
);
};

export default EventDetailsPage;

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

3. صفحه پخش زنده – /app/(event)/live/page.tsx

// /app/(event)/live/page.tsx
import React from ‘react’;

const LiveStreamPage: React.FC = () => {
// Placeholder: Replace with actual live stream integration
const liveStreamUrl = ‘https://www.example.com/livestream’; // Replace with actual stream URL

return (
<div className=”container mx-auto p-4″>
<h1 className=”text-3xl font-bold”>Live Event Streamh1>
<div className=”mt-4″>
<iframe
width=”100%”
height=”500″
src={liveStreamUrl}
frameBorder=”0″
allow=”accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture”
allowFullScreen
>iframe>
div>
div>
);
};

export default LiveStreamPage;

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

4. صفحه فهرست رویداد – /app/(event)/list/page.tsx

// /app/(event)/list/page.tsx
import Link from ‘next/link’;
import React from ‘react’;

const EventListPage: React.FC = () => {
// Placeholder: Replace with actual event list from API
const events = [
{ id: ‘1’, name: ‘Event 1’, date: ‘2024-11-01’, price: 30 },
{ id: ‘2’, name: ‘Event 2’, date: ‘2024-11-05’, price: 20 },
];

return (
<div className=”container mx-auto p-4″>
<h1 className=”text-2xl font-bold”>Upcoming Eventsh1>
<ul className=”mt-4″>
{events.map((event) => (
<li key={event.id} className=”mb-4″>
<Link href={`/event/${event.id}`}>
<a className=”block p-4 border rounded hover:bg-gray-100″>
<h2 className=”text-xl”>{event.name}h2>
<p>Date: {event.date}p>
<p>Price: ${event.price}p>
a>
Link>
li>
))}
ul>
div>
);
};

export default EventListPage;

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

5. صفحه پرسش و پاسخ زنده – /app/(event)/qna/page.tsx

// /app/(event)/qna/page.tsx
import React, { useState } from ‘react’;

const QnAPage: React.FC = () => {
const [question, setQuestion] = useState(”);
const [questions, setQuestions] = useState<string[]>([]);

const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
setQuestions((prevQuestions) => […prevQuestions, question]);
setQuestion(”);
};

return (
<div className=”container mx-auto p-4″>
<h1 className=”text-2xl font-bold mb-4″>Live Q&Ah1>
<form onSubmit={handleSubmit} className=”mb-6″>
<input
type=”text”
className=”w-full p-2 border rounded mb-2″
placeholder=”Ask your question”
value={question}
onChange={(e) => setQuestion(e.target.value)}
required
/>
<button type=”submit” className=”bg-blue-500 text-white p-2 rounded”>Submit Questionbutton>
form>
<ul>
{questions.map((q, index) => (
<li key={index} className=”mb-2 border p-2 rounded”>
{q}
li>
))}
ul>
div>
);
};

export default QnAPage;

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نکات کلیدی:

ایجاد رویداد: فرمی که کاربران می توانند جزئیات رویداد (نام، توضیحات، تاریخ و غیره) را وارد کرده و رویداد را ارسال کنند.

جزئیات رویداد: یک مسیر پویا با استفاده از [eventId] برای نمایش جزئیات هر رویداد. داده های رویداد را بر اساس واکشی می کند eventId.

پخش زنده: یک iframe تعبیه شده برای نمایش پخش زنده ویدیو.

لیست رویداد: فهرست ساده ای از رویدادها که به صفحه جزئیات هر رویداد پیوند می دهد

.

پرسش و پاسخ: یک بخش پرسش و پاسخ زنده که در آن کاربران می توانند سوالات خود را ارسال کنند و به صورت پویا لیست سوالات را به روز می کند.

می‌توانید این کد را با یکپارچه‌سازی APIها برای واکشی داده‌های رویداد، مدیریت پخش‌های زنده و ارسال سؤالات پرسش و پاسخ به پشتیبان، بیشتر گسترش دهید.

در اینجا کد کامل برای مسیرهای مربوط به کاربر و اجزای مشترک اضافی در الف Next.js 14 پروژه این شامل صفحه پروفایل، صفحه ورود، صفحه ثبت نامو اجزای مشترک مانند چیدمان جهانی و CSS جهانی فایل این صفحات نیز استفاده خواهند کرد Tailwind CSS برای یک ظاهر طراحی شده

نمای کلی ساختار پوشه

/app
├── /(user) # User-related routes
│ ├── profile # User profile page
│ │ └── page.tsx # Profile page component
│ ├── login # User login page
│ │ └── page.tsx # Login page component
│ ├── register # User registration page
│ └── page.tsx # Registration page component

├── layout.tsx # Global layout for shared UI (header, footer, etc.)
├── global.css # Global CSS (Tailwind CSS imports)
└── _app.tsx # Custom App component for global state or context

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

1. صفحه نمایه کاربر – /app/(user)/profile/page.tsx

// /app/(user)/profile/page.tsx
import React from ‘react’;

const ProfilePage: React.FC = () => {
// Placeholder user data (fetch real user data via an API)
const user = {
name: ‘John Doe’,
email: ‘john.doe@example.com’,
joined: ‘2023-01-01’,
};

return (
<div className=”container mx-auto p-4″>
<h1 className=”text-3xl font-bold”>User Profileh1>
<div className=”mt-4″>
<p><strong>Name:strong> {user.name}p>
<p><strong>Email:strong> {user.email}p>
<p><strong>Joined:strong> {user.joined}p>
div>
<button className=”bg-blue-500 text-white p-2 mt-4 rounded”>Edit Profilebutton>
div>
);
};

export default ProfilePage;

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

2. صفحه ورود کاربر – /app/(user)/login/page.tsx

// /app/(user)/login/page.tsx
import React, { useState } from ‘react’;
import { useRouter } from ‘next/router’;

const LoginPage: React.FC = () => {
const [email, setEmail] = useState(”);
const [password, setPassword] = useState(”);
const router = useRouter();

const handleLogin = (e: React.FormEvent) => {
e.preventDefault();
// Placeholder login logic (replace with API call)
console.log(‘Logging in:’, { email, password });
router.push(‘/’); // Redirect to homepage after login
};

return (
<div className=”container mx-auto p-4″>
<h1 className=”text-2xl font-bold mb-4″>Loginh1>
<form onSubmit={handleLogin} className=”space-y-4″>
<div>
<label className=”block”>Emaillabel>
<input
type=”email”
className=”w-full p-2 border rounded”
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
div>
<div>
<label className=”block”>Passwordlabel>
<input
type=”password”
className=”w-full p-2 border rounded”
value={password}
onChange={(e) => setPassword(e.target.value)}
required
/>
div>
<button type=”submit” className=”bg-blue-500 text-white p-2 rounded”>
Login
button>
form>
<p className=”mt-4″>
Don’t have an account?{‘ ‘}
<a href=”/user/register” className=”text-blue-500″>Register herea>.
p>
div>
);
};

export default LoginPage;

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

3. صفحه ثبت نام کاربر – /app/(user)/register/page.tsx

// /app/(user)/register/page.tsx
import React, { useState } from ‘react’;
import { useRouter } from ‘next/router’;

const RegisterPage: React.FC = () => {
const [formData, setFormData] = useState({
name: ”,
email: ”,
password: ”,
});
const router = useRouter();

const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setFormData((prevData) => ({
…prevData,
[name]: value,
}));
};

const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
// Placeholder registration logic (replace with API call)
console.log(‘Registering user:’, formData);
router.push(‘/user/login’); // Redirect to login page after registration
};

return (
<div className=”container mx-auto p-4″>
<h1 className=”text-2xl font-bold mb-4″>Registerh1>
<form onSubmit={handleSubmit} className=”space-y-4″>
<div>
<label className=”block”>Namelabel>
<input
name=”name”
type=”text”
className=”w-full p-2 border rounded”
value={formData.name}
onChange={handleInputChange}
required
/>
div>
<div>
<label className=”block”>Emaillabel>
<input
name=”email”
type=”email”
className=”w-full p-2 border rounded”
value={formData.email}
onChange={handleInputChange}
required
/>
div>
<div>
<label className=”block”>Passwordlabel>
<input
name=”password”
type=”password”
className=”w-full p-2 border rounded”
value={formData.password}
onChange={handleInputChange}
required
/>
div>
<button type=”submit” className=”bg-green-500 text-white p-2 rounded”>
Register
button>
form>
<p className=”mt-4″>
Already have an account?{‘ ‘}
<a href=”/user/login” className=”text-blue-500″>Login herea>.
p>
div>
);
};

export default RegisterPage;

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

4. طرح بندی جهانی – /app/layout.tsx

این طرح کلی شامل یک هدر و پاورقی که در تمام صفحات نمایش داده می شود.

// /app/layout.tsx
import React from ‘react’;

export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang=”en”>
<body className=”bg-gray-50 text-gray-900″>
<Header />
<main className=”min-h-screen”>{children}main>
<Footer />
body>
html>
);
}

const Header: React.FC = () => (
<header className=”bg-blue-500 text-white p-4″>
<div className=”container mx-auto”>
<a href=”https://dev.to/” className=”text-xl font-bold”>Event Hosting Platforma>
<nav className=”mt-2″>
<a href=”/user/profile” className=”mr-4″>Profilea>
<a href=”/user/login”>Logina>
nav>
div>
header>
);

const Footer: React.FC = () => (
<footer className=”bg-gray-800 text-white p-4 mt-8″>
<div className=”container mx-auto text-center”>
<p>© 2024 Event Hosting Platform. All rights reserved.p>
div>
footer>
);

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

5. CSS جهانی – /app/global.css

این فایل جایی است که شما وارد می کنید Tailwind CSS و هر سبک جهانی را اعمال کنید. از آن اطمینان حاصل کنید Tailwind CSS به درستی در پروژه شما پیکربندی شده است (tailwind.config.js).

/* /app/global.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

/* Additional custom styles if needed */
body {
font-family: ‘Inter’, sans-serif;
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

6. جزء برنامه سفارشی – /app/_app.tsx

در Next.js 14+، می توانید از برنامه کامپوننت برای مدیریت مواردی مانند حالت جهانی، ارائه دهندگان زمینه، و غیره. این اختیاری است که بسته به نیاز برنامه شماست.

// /app/_app.tsx
import React from ‘react’;

export default function MyApp({ Component, pageProps }: any) {
return (
<Component {…pageProps} />
);
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نکات کلیدی:

صفحه نمایه: اطلاعات کاربر را نمایش می دهد و دارای دکمه ای برای ویرایش نمایه است (آن را با فراخوانی API برای داده های واقعی گسترش دهید).

صفحه ورود: فرم ورود ساده که کاربر را وارد کرده و او را تغییر مسیر می دهد.

صفحه ثبت نام: فرم ثبت نام که اطلاعات کاربر را جمع آوری می کند و پس از ثبت نام موفقیت آمیز به صفحه ورود هدایت می شود.

طرح بندی جهانی: حاوی سرصفحه و پاورقی است که در تمام صفحات به اشتراک گذاشته خواهد شد.

Tailwind CSS:

در سطح جهانی با @tailwind base، @tailwind components، و @tailwind utilities.

این کد یک راه اندازی اولیه برای صفحات احراز هویت کاربر و اجزای اشتراک گذاری شده در شما فراهم می کند Next.js پروژه، و می توان آن را با احراز هویت واقعی و یکپارچه سازی API گسترش داد.

در اینجا اجرای کامل کامپوننت ها، قلاب ها، ابزارهای کمکی و سایر فایل های مرتبط برای شما آورده شده است Next.js پروژه همانطور که در ساختار پوشه شما مشخص شده است.

1. اجزای UI قابل استفاده مجدد

EventCard.tsx

// /components/EventCard.tsx
import React from ‘react’;

interface EventCardProps {
name: string;
description: string;
date: string;
price: number;
imageUrl: string;
}

const EventCard: React.FC<EventCardProps> = ({ name, description, date, price, imageUrl }) => {
return (
<div className=”max-w-sm rounded overflow-hidden shadow-lg”>
<img className=”w-full h-48 object-cover” src={imageUrl} alt={name} />
<div className=”px-6 py-4″>
<h2 className=”font-bold text-xl mb-2″>{name}h2>
<p className=”text-gray-700 text-base”>{description}p>
<p className=”text-gray-600 mt-2″>Date: {date}p>
<p className=”text-gray-600″>Price: ${price}p>
div>
div>
);
};

export default EventCard;

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

Navbar.tsx

// /components/Navbar.tsx
import React from ‘react’;

const Navbar: React.FC = () => {
return (
<nav className=”bg-blue-500 text-white p-4″>
<div className=”container mx-auto flex justify-between items-center”>
<a href=”https://dev.to/” className=”text-xl font-bold”>Event Hosting Platforma>
<div>
<a href=”/user/profile” className=”mr-4″>Profilea>
<a href=”/user/login” className=”mr-4″>Logina>
div>
div>
nav>
);
};

export default Navbar;

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

Footer.tsx

// /components/Footer.tsx
import React from ‘react’;

const Footer: React.FC = () => {
return (
<footer className=”bg-gray-800 text-white text-center p-4 mt-8″>
<div className=”container mx-auto”>
<p>© 2024 Event Hosting Platform. All rights reserved.p>
div>
footer>
);
};

export default Footer;

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

Button.tsx

// /components/Button.tsx
import React from ‘react’;

interface ButtonProps {
label: string;
onClick: () => void;
className?: string;
}

const Button: React.FC<ButtonProps> = ({ label, onClick, className }) => {
return (
<button
className={`bg-blue-500 text-white p-2 rounded ${className}`}
onClick={onClick}
>
{label}
button>
);
};

export default Button;

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

Modal.tsx

// /components/Modal.tsx
import React from ‘react’;

interface ModalProps {
isOpen: boolean;
title: string;
children: React.ReactNode;
onClose: () => void;
}

const Modal: React.FC<ModalProps> = ({ isOpen, title, children, onClose }) => {
if (!isOpen) return null;

return (
<div className=”fixed inset-0 flex items-center justify-center z-50″>
<div className=”bg-white p-4 rounded shadow-lg”>
<h2 className=”text-xl font-bold mb-2″>{title}h2>
<div>{children}div>
<button
className=”bg-red-500 text-white p-2 rounded mt-4″
onClick={onClose}
>
Close
button>
div>
<div className=”fixed inset-0 bg-black opacity-50″ onClick={onClose}>div>
div>
);
};

export default Modal;

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

Loader.tsx

// /components/Loader.tsx
import React from ‘react’;

const Loader: React.FC = () => {
return (
<div className=”flex justify-center items-center”>
<div className=”spinner-border animate-spin inline-block w-8 h-8 border-4 rounded-full border-t-transparent border-blue-500″>div>
div>
);
};

export default Loader;

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

2. قلاب های سفارشی

useAuth.ts

// /hooks/useAuth.ts
import { useState, useEffect } from ‘react’;

export const useAuth = () => {
const [isAuthenticated, setIsAuthenticated] = useState(false);

useEffect(() => {
// Example: check localStorage or make an API call to verify authentication
const token = localStorage.getItem(‘token’);
setIsAuthenticated(!!token);
}, []);

const login = (token: string) => {
localStorage.setItem(‘token’, token);
setIsAuthenticated(true);
};

const logout = () => {
localStorage.removeItem(‘token’);
setIsAuthenticated(false);
};

return { isAuthenticated, login, logout };
};

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

useEvent.ts

// /hooks/useEvent.ts
import { useState, useEffect } from ‘react’;
import { Event } from ‘../types/event’;
import { fetchEvents } from ‘../lib/api’;

export const useEvent = () => {
const [events, setEvents] = useState<Event[]>([]);
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);

useEffect(() => {
const loadEvents = async () => {
try {
const data = await fetchEvents();
setEvents(data);
} catch (err) {
setError(‘Failed to load events’);
} finally {
setLoading(false);
}
};

loadEvents();
}, []);

return { events, loading, error };
};

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

useStream.ts

// /hooks/useStream.ts
import { useState } from ‘react’;

export const useStream = () => {
const [isStreaming, setIsStreaming] = useState(false);

const startStream = () => {
setIsStreaming(true);
// Trigger actual live stream logic here
};

const stopStream = () => {
setIsStreaming(false);
// Stop live stream logic here
};

return { isStreaming, startStream, stopStream };
};

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

3. ابزارهای کمکی و توابع کمکی

api.ts

// /lib/api.ts
import { Event } from ‘../types/event’;

const API_URL = ‘https://api.example.com’;

export const fetchEvents = async (): Promise<Event[]> => {
const response = await fetch(`${API_URL}/events`);
if (!response.ok) {
throw new Error(‘Failed to fetch events’);
}
return response.json();
};

export const loginUser = async (email: string, password: string): Promise<string> => {
const response = await fetch(`${API_URL}/login`, {
method: ‘POST’,
headers: { ‘Content-Type’: ‘application/json’ },
body: JSON.stringify({ email, password }),
});

if (!response.ok) {
throw new Error(‘Failed to log in’);
}

const { token } = await response.json();
return token;
};

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

validators.ts

// /lib/validators.ts
export const validateEmail = (email: string): boolean => {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return regex.test(email);
};

export const validatePassword = (password: string): boolean => {
// Example validation: password must be at least 6 characters
return password.length >= 6;
};

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

4. دارایی های ایستا

/عمومی/تصاویر: تصاویر ثابت خود را مانند بنرهای رویداد یا آرم اضافه کنید.

favicon.ico: فاویکون خود را اینجا قرار دهید.

logo.png: لوگوی برنامه خود را در اینجا اضافه کنید.

ساختار نمونه:

/public
├── /images
│ ├── event1.jpg
│ ├── event2.jpg
│ └── logo.png
├── favicon.ico

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

5. سبک ها

tailwind.config.js

مطمئن شوید Tailwind CSS به درستی تنظیم شده است. در اینجا فایل پیکربندی برای فعال کردن Tailwind در پروژه شما است.

// /styles/tailwind.config.js
module.exports = {
content: [‘./app/**/*.{js,ts,jsx,tsx}’, ‘./components/**/*.{js,ts,jsx,tsx}’],
theme: {
extend: {},
},
plugins: [],
};

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

globals.css

این یک فایل اختیاری برای هر CSS جهانی اضافی است. Tailwind CSS اکثر نیازهای یک ظاهر طراحی را پوشش خواهد داد.

/* /styles/globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

/* Additional global styles can go here */

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

6. انواع TypeScript

رویداد.ts

// /types/event.ts
export interface Event {
id: string;
name: string;
description: string;
date: string;
price: number;
imageUrl: string;
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

user.ts

// /types/user.ts
export interface User {

id: string;
name: string;
email: string;
joined: string;
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

خلاصه:

این ساختار یک به خوبی سازماندهی شده است و مقیاس پذیر معماری برای ساختن شما Next.js برنامه با اجزای قابل استفاده مجدد، قلاب های سفارشی، و توابع ابزار مدولار.

را اجزاء مانند EventCard، Navbar، و Button قابل استفاده مجدد در سراسر برنامه شما هستند.

قلاب های سفارشی مانند useAuth، useEvent، و useStream منطق را کپسوله کنید و تعامل با وضعیت برنامه و APIها را ساده کنید.

توابع سودمند رسیدگی به درخواست‌ها و اعتبارسنجی‌های API

در اینجا اجرای کامل برای احراز هویت و کاربر ماژول ها در a NestJS برنامه با استفاده از TypeORM و احراز هویت مبتنی بر JWT.

نمای کلی ساختار پوشه

/src
├── /auth
│ ├── auth.controller.ts
│ ├── auth.module.ts
│ ├── auth.service.ts
│ ├── jwt.strategy.ts
│ ├── local.strategy.ts
│ ├── dto
│ │ ├── login.dto.ts
│ │ ├── register.dto.ts
│ ├── guards
│ │ ├── jwt-auth.guard.ts
│ │ ├── roles.guard.ts
│ ├── decorators
│ ├── roles.decorator.ts
├── /users
│ ├── users.controller.ts
│ ├── users.module.ts
│ ├── users.service.ts
│ ├── entities
│ │ ├── user.entity.ts
│ ├── dto
│ ├── create-user.dto.ts
│ ├── update-user.dto.ts

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

1. ماژول احراز هویت

auth.controller.ts

ورود و ثبت نام کاربر را کنترل می کند.

// /src/auth/auth.controller.ts
import { Controller, Post, Body, UseGuards, Request } from ‘@nestjs/common’;
import { AuthService } from ‘./auth.service’;
import { LoginDto } from ‘./dto/login.dto’;
import { RegisterDto } from ‘./dto/register.dto’;
import { LocalAuthGuard } from ‘./guards/local-auth.guard’;
import { JwtAuthGuard } from ‘./guards/jwt-auth.guard’;

@Controller(‘auth’)
export class AuthController {
constructor(private readonly authService: AuthService) {}

@Post(‘login’)
@UseGuards(LocalAuthGuard)
async login(@Request() req, @Body() loginDto: LoginDto) {
return this.authService.login(req.user);
}

@Post(‘register’)
async register(@Body() registerDto: RegisterDto) {
return this.authService.register(registerDto);
}

@UseGuards(JwtAuthGuard)
@Post(‘profile’)
getProfile(@Request() req) {
return req.user;
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

auth.module.ts

وابستگی ها و واردات مورد نیاز برای ماژول احراز هویت را تعریف می کند.

// /src/auth/auth.module.ts
import { Module } from ‘@nestjs/common’;
import { JwtModule } from ‘@nestjs/jwt’;
import { PassportModule } from ‘@nestjs/passport’;
import { AuthService } from ‘./auth.service’;
import { AuthController } from ‘./auth.controller’;
import { UsersModule } from ‘../users/users.module’;
import { JwtStrategy } from ‘./jwt.strategy’;
import { LocalStrategy } from ‘./local.strategy’;
import { JwtAuthGuard } from ‘./guards/jwt-auth.guard’;

@Module({
imports: [
UsersModule,
PassportModule,
JwtModule.register({
secret: ‘jwt_secret’, // Use environment variable for production
signOptions: { expiresIn: ‘1d’ },
}),
],
controllers: [AuthController],
providers: [AuthService, LocalStrategy, JwtStrategy, JwtAuthGuard],
})
export class AuthModule {}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

auth.service.ts

منطق ثبت نام کاربران، اعتبارسنجی اعتبارنامه ها و تولید توکن های JWT را مدیریت می کند.

// /src/auth/auth.service.ts
import { Injectable, UnauthorizedException } from ‘@nestjs/common’;
import { JwtService } from ‘@nestjs/jwt’;
import { UsersService } from ‘../users/users.service’;
import { RegisterDto } from ‘./dto/register.dto’;
import { User } from ‘../users/entities/user.entity’;

@Injectable()
export class AuthService {
constructor(
private usersService: UsersService,
private jwtService: JwtService,
) {}

async validateUser(email: string, pass: string): Promise<any> {
const user = await this.usersService.findByEmail(email);
if (user && user.password === pass) {
const { password, …result } = user;
return result;
}
return null;
}

async login(user: any) {
const payload = { email: user.email, sub: user.id };
return {
access_token: this.jwtService.sign(payload),
};
}

async register(registerDto: RegisterDto): Promise<User> {
return this.usersService.create(registerDto);
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

jwt.strategy.ts

تأیید رمز JWT را کنترل می کند.

// /src/auth/jwt.strategy.ts
import { Injectable } from ‘@nestjs/common’;
import { PassportStrategy } from ‘@nestjs/passport’;
import { ExtractJwt, Strategy } from ‘passport-jwt’;

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: ‘jwt_secret’, // Use environment variable for production
});
}

async validate(payload: any) {
return { userId: payload.sub, email: payload.email };
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

local.strategy.ts

تأیید نام کاربری/رمز عبور را کنترل می کند.

// /src/auth/local.strategy.ts
import { Strategy } from ‘passport-local’;
import { PassportStrategy } from ‘@nestjs/passport’;
import { Injectable, UnauthorizedException } from ‘@nestjs/common’;
import { AuthService } from ‘./auth.service’;

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
constructor(private authService: AuthService) {
super({ usernameField: ’email’ });
}

async validate(email: string, password: string): Promise<any> {
const user = await this.authService.validateUser(email, password);
if (!user) {
throw new UnauthorizedException();
}
return user;
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

login.dto.ts

شی انتقال داده برای درخواست های ورود به سیستم.

// /src/auth/dto/login.dto.ts
import { IsEmail, IsNotEmpty, MinLength } from ‘class-validator’;

export class LoginDto {
@IsEmail()
email: string;

@IsNotEmpty()
@MinLength(6)
password: string;
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

register.dto.ts

شی انتقال داده برای درخواست های ثبت نام.

// /src/auth/dto/register.dto.ts
import { IsEmail, IsNotEmpty, MinLength } from ‘class-validator’;

export class RegisterDto {
@IsNotEmpty()
name: string;

@IsEmail()
email: string;

@IsNotEmpty()
@MinLength(6)
password: string;
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

jwt-auth.guard.ts

محافظ برای محافظت از مسیرها با احراز هویت JWT.

// /src/auth/guards/jwt-auth.guard.ts
import { Injectable } from ‘@nestjs/common’;
import { AuthGuard } from ‘@nestjs/passport’;

@Injectable()
export class JwtAuthGuard extends AuthGuard(‘jwt’) {}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نقش ها.نگهبان.تس

محافظ برای کنترل دسترسی مبتنی بر نقش.

// /src/auth/guards/roles.guard.ts
import { CanActivate, ExecutionContext, Injectable } from ‘@nestjs/common’;
import { Reflector } from ‘@nestjs/core’;

@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}

canActivate(context: ExecutionContext): boolean {
const roles = this.reflector.get<string[]>(‘roles’, context.getHandler());
if (!roles) {
return true;
}
const request = context.switchToHttp().getRequest();
const user = request.user;
return roles.includes(user.role);
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نقش ها.دکوراتور.تس

دکوراتور سفارشی برای تعیین نقش به مسیرها.

// /src/auth/decorators/roles.decorator.ts
import { SetMetadata } from ‘@nestjs/common’;

export const Roles = (…roles: string[]) => SetMetadata(‘roles’, roles);

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

2. ماژول کاربر

users.controller.ts

درخواست های مربوط به کاربر را رسیدگی می کند.

// /src/users/users.controller.ts
import { Controller, Get, Post, Body, Param, Patch } from ‘@nestjs/common’;
import { UsersService } from ‘./users.service’;
import { CreateUserDto } from ‘./dto/create-user.dto’;
import { UpdateUserDto } from ‘./dto/update-user.dto’;

@Controller(‘users’)
export class UsersController {
constructor(private readonly usersService: UsersService) {}

@Post()
create(@Body() createUserDto: CreateUserDto) {
return this.usersService.create(createUserDto);
}

@Get(‘:id’)
findOne(@Param(‘id’) id: string) {
return this.usersService.findOne(id);
}

@Patch(‘:id’)
update(@Param(‘id’) id: string, @Body() updateUserDto: UpdateUserDto) {
return this.usersService.update(id, updateUserDto);
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

users.module.ts

ماژول ها و خدمات لازم را برای ماژول کاربر وارد می کند.

// /src/users/users.module.ts
import { Module } from ‘@nestjs/common’;
import { TypeOrmModule } from ‘@nestjs/typeorm’;
import { UsersService } from ‘./users.service’;
import { UsersController } from ‘./users.controller’;
import { User } from ‘./entities/user.entity’;

@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService],
})
export class UsersModule {}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

users.service.ts

منطق مدیریت داده های کاربر را مدیریت می کند.

// /src/users/users.service.ts
import { Injectable } from ‘@nestjs/common’;
import { InjectRepository } from

‘@nestjs/typeorm’;
import { Repository } from ‘typeorm’;
import { CreateUserDto } from ‘./dto/create-user.dto’;
import { UpdateUserDto } from ‘./dto/update-user.dto’;
import { User } from ‘./entities/user.entity’;

@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private usersRepository: Repository<User>,
) {}

async create(createUserDto: CreateUserDto): Promise<User> {
const user = this.usersRepository.create(createUserDto);
return this.usersRepository.save(user);
}

async findOne(id: string): Promise<User> {
return this.usersRepository.findOneBy({ id });
}

async findByEmail(email: string): Promise<User> {
return this.usersRepository.findOneBy({ email });
}

async update(id: string, updateUserDto: UpdateUserDto): Promise<User> {
await this.usersRepository.update(id, updateUserDto);
return this.findOne(id);
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

user.entity.ts

طرح کاربر را برای TypeORM تعریف می کند.

// /src/users/entities/user.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from ‘typeorm’;

@Entity()
export class User {
@PrimaryGeneratedColumn(‘uuid’)
id: string;

@Column()
name: string;

@Column({ unique: true })
email: string;

@Column()
password: string;

@Column({ default: ‘user’ })
role: string;
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

create-user.dto.ts

شی انتقال داده برای ایجاد کاربر.

// /src/users/dto/create-user.dto.ts
import { IsEmail, IsNotEmpty, MinLength } from ‘class-validator’;

export class CreateUserDto {
@IsNotEmpty()
name: string;

@IsEmail()
email: string;

@IsNotEmpty()
@MinLength(6)
password: string;
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

update-user.dto.ts

شی انتقال داده برای به روز رسانی یک کاربر.

// /src/users/dto/update-user.dto.ts
import { IsOptional, MinLength } from ‘class-validator’;

export class UpdateUserDto {
@IsOptional()
name?: string;

@IsOptional()
@MinLength(6)
password?: string;
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

خلاصه

این راه اندازی فراهم می کند احراز هویت مدولار و سیستم مدیریت کاربر در NestJS. شامل:

ماژول احراز هویت: ورود و ثبت نام کاربر را با احراز هویت JWT و محافظ های مبتنی بر نقش کنترل می کند.

ماژول کاربر: داده های کاربر را با استفاده از TypeORM با عملیات CRUD مدیریت می کند.

DTOها و نگهبانان: از ایمنی نوع و تأیید اعتبار درخواست اطمینان حاصل کنید، در حالی که از مسیرها با توکن های JWT محافظت می کنید.

شما می توانید این کد را برای ادغام با پایگاه داده PostgreSQL خود با استفاده از آن گسترش دهید TypeORMو راز JWT را می توان به طور ایمن در متغیرهای محیطی برای استفاده در تولید ذخیره کرد.

در اینجا اجرای کامل کد برای رویداد و تهیه بلیط ماژول ها در a NestJS استفاده از باطن TypeORM برای مدیریت داده های رویداد و بلیط.

نمای کلی ساختار پوشه

/src
├── /events # Event module
│ ├── events.controller.ts
│ ├── events.module.ts
│ ├── events.service.ts
│ ├── entities
│ │ ├── event.entity.ts
│ ├── dto
│ ├── create-event.dto.ts
│ ├── update-event.dto.ts
├── /tickets # Ticket module
│ ├── tickets.controller.ts
│ ├── tickets.module.ts
│ ├── tickets.service.ts
│ ├── entities
│ │ ├── ticket.entity.ts
│ ├── dto
│ ├── create-ticket.dto.ts
│ ├── update-ticket.dto.ts

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

1. ماژول رویداد

events.controller.ts

درخواست‌های HTTP مربوط به رویدادها (مانند ایجاد، به‌روزرسانی، فهرست کردن رویدادها) را مدیریت می‌کند.

// /src/events/events.controller.ts
import { Controller, Get, Post, Body, Param, Patch, Delete } from ‘@nestjs/common’;
import { EventsService } from ‘./events.service’;
import { CreateEventDto } from ‘./dto/create-event.dto’;
import { UpdateEventDto } from ‘./dto/update-event.dto’;

@Controller(‘events’)
export class EventsController {
constructor(private readonly eventsService: EventsService) {}

@Post()
create(@Body() createEventDto: CreateEventDto) {
return this.eventsService.create(createEventDto);
}

@Get()
findAll() {
return this.eventsService.findAll();
}

@Get(‘:id’)
findOne(@Param(‘id’) id: string) {
return this.eventsService.findOne(id);
}

@Patch(‘:id’)
update(@Param(‘id’) id: string, @Body() updateEventDto: UpdateEventDto) {
return this.eventsService.update(id, updateEventDto);
}

@Delete(‘:id’)
remove(@Param(‘id’) id: string) {
return this.eventsService.remove(id);
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

event.module.ts

ماژول Event را تعریف می کند که خدمات و کنترلرهای لازم را وارد می کند.

// /src/events/events.module.ts
import { Module } from ‘@nestjs/common’;
import { TypeOrmModule } from ‘@nestjs/typeorm’;
import { EventsService } from ‘./events.service’;
import { EventsController } from ‘./events.controller’;
import { Event } from ‘./entities/event.entity’;

@Module({
imports: [TypeOrmModule.forFeature([Event])],
controllers: [EventsController],
providers: [EventsService],
})
export class EventsModule {}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

events.service.ts

شامل منطق تجاری برای مدیریت رویدادها، مانند ایجاد، به روز رسانی، و یافتن رویدادها است.

// /src/events/events.service.ts
import { Injectable, NotFoundException } from ‘@nestjs/common’;
import { InjectRepository } from ‘@nestjs/typeorm’;
import { Repository } from ‘typeorm’;
import { CreateEventDto } from ‘./dto/create-event.dto’;
import { UpdateEventDto } from ‘./dto/update-event.dto’;
import { Event } from ‘./entities/event.entity’;

@Injectable()
export class EventsService {
constructor(
@InjectRepository(Event)
private eventsRepository: Repository<Event>,
) {}

create(createEventDto: CreateEventDto): Promise<Event> {
const event = this.eventsRepository.create(createEventDto);
return this.eventsRepository.save(event);
}

findAll(): Promise<Event[]> {
return this.eventsRepository.find();
}

async findOne(id: string): Promise<Event> {
const event = await this.eventsRepository.findOneBy({ id });
if (!event) {
throw new NotFoundException(`Event with ID ${id} not found`);
}
return event;
}

async update(id: string, updateEventDto: UpdateEventDto): Promise<Event> {
await this.eventsRepository.update(id, updateEventDto);
return this.findOne(id);
}

async remove(id: string): Promise<void> {
await this.findOne(id); // Ensure event exists
await this.eventsRepository.delete(id);
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

event.entity.ts

طرح واره پایگاه داده را برای رویدادها با استفاده تعریف می کند TypeORM.

// /src/events/entities/event.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from ‘typeorm’;

@Entity()
export class Event {
@PrimaryGeneratedColumn(‘uuid’)
id: string;

@Column()
name: string;

@Column()
description: string;

@Column()
date: string;

@Column(‘decimal’)
price: number;

@Column({ nullable: true })
imageUrl: string;
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

create-event.dto.ts

شی انتقال داده برای ایجاد یک رویداد جدید.

// /src/events/dto/create-event.dto.ts
import { IsNotEmpty, IsString, IsDecimal, IsOptional } from ‘class-validator’;

export class CreateEventDto {
@IsNotEmpty()
@IsString()
name: string;

@IsNotEmpty()
@IsString()
description: string;

@IsNotEmpty()
date: string;

@IsNotEmpty()
@IsDecimal()
price: number;

@IsOptional()
@IsString()
imageUrl?: string;
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

update-event.dto.ts

شی انتقال داده برای به روز رسانی یک رویداد.

// /src/events/dto/update-event.dto.ts
import { PartialType } from ‘@nestjs/mapped-types’;
import { CreateEventDto } from ‘./create-event.dto’;

export class UpdateEventDto extends PartialType(CreateEventDto) {}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

2. ماژول تهیه بلیط

بلیط.controller.ts

درخواست های HTTP مربوط به بلیط ها (به عنوان مثال، ایجاد، به روز رسانی، لیست بلیط ها) را مدیریت می کند.

// /src/tickets/tickets.controller.ts
import { Controller, Get, Post, Body, Param, Patch, Delete } from ‘@nestjs/common’;
import { TicketsService } from ‘./tickets.service’;
import { CreateTicketDto } from ‘./dto/create-ticket.dto’;
import { UpdateTicketDto } from ‘./dto/update-ticket.dto’;

@Controller(‘tickets’)
export class TicketsController {
constructor(private readonly ticketsService: TicketsService) {}

@Post()
create(@Body() createTicketDto: CreateTicketDto) {
return this.ticketsService.create(createTicketDto);
}

@Get()
findAll() {
return this.ticketsService.findAll();
}

@Get(‘:id’)
findOne(@Param(‘id’) id: string) {
return this.ticketsService.findOne(id);
}

@Patch(‘:id’)
update(@Param(‘id’) id: string, @Body() updateTicketDto: UpdateTicketDto) {
return this.ticketsService.update(id, updateTicketDto);
}

@Delete(‘:id’)
remove(@Param(‘id’) id: string) {
return this.ticketsService.remove(id);
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

بلیط.module.ts

ماژول Ticket را تعریف می کند که خدمات و کنترلرهای لازم را وارد می کند.

// /src/tickets/tickets.module.ts
import { Module } from ‘@nestjs/common’;
import { TypeOrmModule } from ‘@nestjs/typeorm’;
import { TicketsService } from ‘./tickets.service’;
import { TicketsController } from ‘./tickets.controller’;
import { Ticket } from ‘./entities/ticket.entity’;

@Module({
imports: [TypeOrmModule.forFeature([Ticket])],
controllers: [TicketsController],
providers: [TicketsService],
})
export class TicketsModule {}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

بلیط.سرویس.تس

شامل منطق تجاری برای مدیریت بلیط ها، مانند ایجاد، به روز رسانی، و یافتن بلیط.

// /src/tickets/tickets.service.ts
import { Injectable, NotFoundException } from ‘@nestjs/common’;
import { InjectRepository } from ‘@nestjs/typeorm’;
import { Repository } from ‘typeorm’;
import { CreateTicketDto } from ‘./dto/create-ticket.dto’;
import { UpdateTicketDto } from ‘./dto/update-ticket.dto’;
import { Ticket } from ‘./entities/ticket.entity’;

@Injectable()
export class TicketsService {
constructor(
@InjectRepository(Ticket)
private ticketsRepository: Repository<Ticket>,
) {}

create(createTicketDto: CreateTicketDto): Promise<Ticket> {
const ticket = this.ticketsRepository.create(createTicketDto);
return this.ticketsRepository.save(ticket);
}

findAll(): Promise<Ticket[]> {
return this.ticketsRepository.find();
}

async findOne(id: string): Promise<Ticket> {
const ticket = await this.ticketsRepository.findOneBy({ id });
if (!ticket) {
throw new NotFoundException(`Ticket with ID ${id} not found`);
}
return ticket;
}

async update(id: string, updateTicketDto: UpdateTicketDto): Promise<Ticket> {
await this.ticketsRepository.update(id, updateTicketDto);
return this.findOne(id);
}

async remove(id: string): Promise<void> {
await this.findOne(id); // Ensure ticket exists
await this.ticketsRepository.delete(id);
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ticket.entity.ts

طرح پایگاه داده را برای استفاده از بلیط ها تعریف می کند TypeORM.

// /src/tickets/entities/ticket.entity.ts
import { Entity, Column, PrimaryGeneratedColumn, ManyToOne } from ‘typeorm’;
import { Event } from ‘../../events/entities/event.entity’;

@Entity()
export class Ticket {
@PrimaryGeneratedColumn(‘uuid’)
id: string

;

@Column()
seatNumber: string;

@Column(‘decimal’)
price: number;

@ManyToOne(() => Event, (event) => event.id)
event: Event;
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

create-ticket.dto.ts

شی انتقال داده برای ایجاد یک بلیط جدید.

// /src/tickets/dto/create-ticket.dto.ts
import { IsNotEmpty, IsDecimal, IsString } from ‘class-validator’;

export class CreateTicketDto {
@IsNotEmpty()
@IsString()
seatNumber: string;

@IsNotEmpty()
@IsDecimal()
price: number;

@IsNotEmpty()
@IsString()
eventId: string;
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

update-ticket.dto.ts

شیء انتقال داده برای به روز رسانی بلیط.

// /src/tickets/dto/update-ticket.dto.ts
import { PartialType } from ‘@nestjs/mapped-types’;
import { CreateTicketDto } from ‘./create-ticket.dto’;

export class UpdateTicketDto extends PartialType(CreateTicketDto) {}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

خلاصه

این تنظیمات دو ماژول را ارائه می دهد:

ماژول رویداد:

ایجاد، به‌روزرسانی و بازیابی رویدادها را مدیریت می‌کند.
استفاده می کند TypeORM برای تعامل با PostgreSQL پایگاه داده
اجرا می کند DTO ها برای اعتبار سنجی

ماژول تهیه بلیط:

ایجاد بلیط و مدیریت مربوط به رویدادها را انجام می دهد.
استفاده می کند TypeORM برای طرح پایگاه داده بلیط.
هر بلیط با یک رویداد مرتبط است.

هر دو ماژول به گونه‌ای طراحی شده‌اند که توسعه‌پذیر و مقیاس‌پذیر باشند و ویژگی‌های بیشتری مانند خرید بلیط، مدیریت در دسترس بودن، و درخواست‌های پیچیده‌تر در رویدادها و بلیط‌ها را امکان‌پذیر می‌سازند.

در اینجا اجرای کامل کد برای پرداخت و اطلاع رسانی ماژول ها در a NestJS استفاده از باطن TypeORM برای مدیریت تراکنش‌های پرداخت و ارسال اعلان‌ها از طریق ایمیل، پیامک یا اعلان‌های فشاری.

نمای کلی ساختار پوشه

/src
├── /payments # Payment module
│ ├── payments.controller.ts
│ ├── payments.module.ts
│ ├── payments.service.ts
│ ├── entities
│ │ ├── payment.entity.ts
│ ├── dto
│ ├── create-payment.dto.ts
├── /notifications # Notification module
│ ├── notifications.controller.ts
│ ├── notifications.module.ts
│ ├── notifications.service.ts
│ ├── dto
│ ├── create-notification.dto.ts

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

1. ماژول پرداخت

payments.controller.ts

درخواست‌های HTTP مربوط به پرداخت‌ها (به عنوان مثال، پردازش پرداخت، واکشی جزئیات پرداخت) را مدیریت می‌کند.

// /src/payments/payments.controller.ts
import { Controller, Get, Post, Body, Param } from ‘@nestjs/common’;
import { PaymentsService } from ‘./payments.service’;
import { CreatePaymentDto } from ‘./dto/create-payment.dto’;

@Controller(‘payments’)
export class PaymentsController {
constructor(private readonly paymentsService: PaymentsService) {}

@Post()
processPayment(@Body() createPaymentDto: CreatePaymentDto) {
return this.paymentsService.processPayment(createPaymentDto);
}

@Get(‘:id’)
findOne(@Param(‘id’) id: string) {
return this.paymentsService.findOne(id);
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

pays.module.ts

ماژول Payment را تعریف می کند که خدمات و کنترلرهای لازم را وارد می کند.

// /src/payments/payments.module.ts
import { Module } from ‘@nestjs/common’;
import { TypeOrmModule } from ‘@nestjs/typeorm’;
import { PaymentsService } from ‘./payments.service’;
import { PaymentsController } from ‘./payments.controller’;
import { Payment } from ‘./entities/payment.entity’;

@Module({
imports: [TypeOrmModule.forFeature([Payment])],
controllers: [PaymentsController],
providers: [PaymentsService],
})
export class PaymentsModule {}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

pays.service.ts

حاوی منطق تجاری برای مدیریت پرداخت‌ها، مانند پردازش و بازیابی پرداخت‌ها.

// /src/payments/payments.service.ts
import { Injectable, NotFoundException } from ‘@nestjs/common’;
import { InjectRepository } from ‘@nestjs/typeorm’;
import { Repository } from ‘typeorm’;
import { CreatePaymentDto } from ‘./dto/create-payment.dto’;
import { Payment } from ‘./entities/payment.entity’;

@Injectable()
export class PaymentsService {
constructor(
@InjectRepository(Payment)
private paymentsRepository: Repository<Payment>,
) {}

async processPayment(createPaymentDto: CreatePaymentDto): Promise<Payment> {
// Placeholder logic for payment processing (integrate with a real payment provider like Stripe or PayPal)
const payment = this.paymentsRepository.create(createPaymentDto);
return this.paymentsRepository.save(payment);
}

async findOne(id: string): Promise<Payment> {
const payment = await this.paymentsRepository.findOneBy({ id });
if (!payment) {
throw new NotFoundException(`Payment with ID ${id} not found`);
}
return payment;
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

Payment.entity.ts

طرح پایگاه داده را برای پرداخت ها با استفاده از تعریف می کند TypeORM.

// /src/payments/entities/payment.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from ‘typeorm’;

@Entity()
export class Payment {
@PrimaryGeneratedColumn(‘uuid’)
id: string;

@Column()
userId: string;

@Column()
eventId: string;

@Column(‘decimal’)
amount: number;

@Column()
paymentMethod: string; // e.g., ‘credit card’, ‘paypal’

@Column()
status: string; // e.g., ‘pending’, ‘completed’, ‘failed’

@Column({ type: ‘timestamp’, default: () => ‘CURRENT_TIMESTAMP’ })
createdAt: Date;
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

create-payment.dto.ts

شی انتقال داده برای ایجاد یک پرداخت جدید.

// /src/payments/dto/create-payment.dto.ts
import { IsNotEmpty, IsDecimal } from ‘class-validator’;

export class CreatePaymentDto {
@IsNotEmpty()
userId: string;

@IsNotEmpty()
eventId: string;

@IsNotEmpty()
@IsDecimal()
amount: number;

@IsNotEmpty()
paymentMethod: string; // e.g., ‘credit card’, ‘paypal’
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

2. ماژول اطلاع رسانی

notifications.controller.ts

درخواست‌های HTTP مربوط به اعلان‌ها (به عنوان مثال، ارسال ایمیل یا پیامک اعلان) را مدیریت می‌کند.

// /src/notifications/notifications.controller.ts
import { Controller, Post, Body } from ‘@nestjs/common’;
import { NotificationsService } from ‘./notifications.service’;
import { CreateNotificationDto } from ‘./dto/create-notification.dto’;

@Controller(‘notifications’)
export class NotificationsController {
constructor(private readonly notificationsService: NotificationsService) {}

@Post()
sendNotification(@Body() createNotificationDto: CreateNotificationDto) {
return this.notificationsService.sendNotification(createNotificationDto);
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

notifications.module.ts

ماژول Notification را تعریف می کند که خدمات و کنترلرهای لازم را وارد می کند.

// /src/notifications/notifications.module.ts
import { Module } from ‘@nestjs/common’;
import { NotificationsService } from ‘./notifications.service’;
import { NotificationsController } from ‘./notifications.controller’;

@Module({
controllers: [NotificationsController],
providers: [NotificationsService],
})
export class NotificationsModule {}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

notifications.service.ts

حاوی منطق تجاری برای ارسال اعلان‌هایی مانند ایمیل، پیامک یا اعلان‌های فشاری است.

// /src/notifications/notifications.service.ts
import { Injectable } from ‘@nestjs/common’;
import { CreateNotificationDto } from ‘./dto/create-notification.dto’;
import * as nodemailer from ‘nodemailer’; // For email notifications (use an actual provider for SMS)

@Injectable()
export class NotificationsService {
async sendNotification(createNotificationDto: CreateNotificationDto): Promise<any> {
const { recipient, message, type } = createNotificationDto;

if (type === ’email’) {
return this.sendEmail(recipient, message);
}

if (type === ‘sms’) {
return this.sendSms(recipient, message);
}

if (type === ‘push’) {
return this.sendPushNotification(recipient, message);
}
}

private async sendEmail(recipient: string, message: string) {
const transporter = nodemailer.createTransport({
service: ‘Gmail’, // Use your actual email service provider here
auth: {
user: ‘your-email@gmail.com’,
pass: ‘your-email-password’,
},
});

const mailOptions = {
from: ‘your-email@gmail.com’,
to: recipient,
subject: ‘Notification’,
text: message,
};

return transporter.sendMail(mailOptions);
}

private async sendSms(recipient: string, message: string) {
// Implement SMS sending logic (e.g., using Twilio)
console.log(`Sending SMS to ${recipient}: ${message}`);
return { success: true };
}

private async sendPushNotification(recipient: string, message: string) {
// Implement push notification logic (e.g., using Firebase Cloud Messaging)
console.log(`Sending push notification to ${recipient}: ${message}`);
return { success: true };
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

create-notification.dto.ts

شی انتقال داده برای ایجاد درخواست اعلان.

// /src/notifications/dto/create-notification.dto.ts
import { IsNotEmpty, IsEmail, IsIn } from ‘class-validator’;

export class CreateNotificationDto {
@IsNotEmpty()
@IsEmail()
recipient: string; // Can be email or phone number depending on the type

@IsNotEmpty()
message: string;

@IsNotEmpty()
@IsIn([’email’, ‘sms’, ‘push’])
type: string; // e.g., ’email’, ‘sms’, ‘push’
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

خلاصه

این تنظیمات دو ماژول را ارائه می دهد:

ماژول پرداخت:

ایجاد و بازیابی پرداخت ها را مدیریت می کند.
استفاده می کند TypeORM برای تعامل با PostgreSQL پایگاه داده
اجرا می کند DTO ها برای اعتبارسنجی داده های پرداخت دریافتی

ماژول اطلاع رسانی:

ارسال ایمیل، پیامک و اعلان‌های فشاری را کنترل می‌کند.
استفاده می کند nodemailer برای اعلان‌های ایمیل (می‌توانید آن را گسترش دهید تا از Twilio برای SMS یا Firebase برای اعلان‌های فشاری استفاده کنید).
اجرا می کند DTO ها برای تایید درخواست های اطلاع رسانی

شما می توانید این راه حل را با ادغام با درگاه های پرداخت (به عنوان مثال، Stripe، PayPal) و خدمات اعلان (به عنوان مثال، Twilio برای SMS، Firebase برای اعلان های فشار) گسترش دهید.

در اینجا اجرای کامل آن است ماژول پایگاه داده و خدمات عمومی مانند فیلترهای استثنایی، رهگیرها، دکوراتورها و لوله ها در الف NestJS کاربرد.

نمای کلی ساختار پوشه

/src
├── /database # Database module
│ ├── database.module.ts
│ ├── database.service.ts
│ ├── ormconfig.ts # TypeORM configuration
├── /common # Shared utilities, guards, interceptors, and exceptions
│ ├── /filters # Global exception filters
│ │ ├── all-exceptions.filter.ts
│ ├── /interceptors # Interceptors for response transformation, logging, etc.
│ │ ├── transform.interceptor.ts
│ ├── /decorators # Reusable decorators
│ │ ├── api-response.decorator.ts
│ ├── /pipes # Global pipes for validation, etc.
│ │ ├── validation.pipe.ts
├── app.module.ts # Root application module
├── main.ts # Main entry point of the application

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

1. ماژول پایگاه داده

database.module.ts

این ماژول پیکربندی می کند TypeORM برای اتصال به پایگاه داده جزئیات اتصال از وارد شده است ormconfig.ts فایل

// /src/database/database.module.ts
import { Module } from ‘@nestjs/common’;
import { TypeOrmModule } from ‘@nestjs/typeorm’;
import { DatabaseService } from ‘./database.service’;
import ormconfig from ‘./ormconfig’;

@Module({
imports: [TypeOrmModule.forRoot(ormconfig)],
providers: [DatabaseService],
exports: [DatabaseService],
})
export class DatabaseModule {}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

database.service.ts

در صورت نیاز می توان از این سرویس برای انجام عملیات پایگاه داده خام استفاده کرد. به طور معمول، برای اکثر موارد، شما از مخازن TypeORM استفاده خواهید کرد.

// /src/database/database.service.ts
import { Injectable } from ‘@nestjs/common’;
import { DataSource } from ‘typeorm’;

@Injectable()
export class DatabaseService {
constructor(private readonly dataSource: DataSource) {}

async runRawQuery(query: string): Promise<any> {
return this.dataSource.query(query);
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ormconfig.ts

را TypeORM فایل پیکربندی، که در آن جزئیات و موجودیت های اتصال پایگاه داده خود را تعریف می کنید.

// /src/database/ormconfig.ts
import { TypeOrmModuleOptions } from ‘@nestjs/typeorm’;
import { User } from ‘../users/entities/user.entity’;
import { Event } from ‘../events/entities/event.entity’;
import { Ticket } from ‘../tickets/entities/ticket.entity’;
import { Payment } from ‘../payments/entities/payment.entity’;

const ormconfig: TypeOrmModuleOptions = {
type: ‘postgres’,
host: process.env.DB_HOST || ‘localhost’,
port: Number(process.env.DB_PORT) || 5432,
username: process.env.DB_USERNAME || ‘postgres’,
password: process.env.DB_PASSWORD || ‘postgres’,
database: process.env.DB_NAME || ‘event_platform’,
entities: [User, Event, Ticket, Payment],
synchronize: true, // Set to false in production
};

export default ormconfig;

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

2. ماژول مشترک

فیلترهای استثنایی

all-exceptions.filter.ts

یک فیلتر استثنای جهانی برای گرفتن و رسیدگی به همه استثناها به روشی یکسان.

// /src/common/filters/all-exceptions.filter.ts
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
HttpStatus,
} from ‘@nestjs/common’;
import { Request, Response } from ‘express’;

@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
catch(exception: unknown, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();

const status =
exception instanceof HttpException
? exception.getStatus()
: HttpStatus.INTERNAL_SERVER_ERROR;

const message =
exception instanceof HttpException
? exception.getResponse()
: ‘Internal server error’;

response.status(status).json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
message,
});
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

رهگیرها

transform.interceptor.ts

این رهگیر به طور خودکار پاسخ ها را قبل از ارسال به مشتری تغییر می دهد و استاندارد کردن پاسخ های API را آسان تر می کند.

// /src/common/interceptors/transform.interceptor.ts
import {
Injectable,
NestInterceptor,
ExecutionContext,
CallHandler,
} from ‘@nestjs/common’;
import { Observable } from ‘rxjs’;
import { map } from ‘rxjs/operators’;

@Injectable()
export class TransformInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next.handle().pipe(
map((data) => ({
success: true,
data,
})),
);
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

دکوراتورها

api-response.decorator.ts

این دکوراتور قابل استفاده مجدد را می توان برای حاشیه نویسی پاسخ های API با ساختاری ثابت استفاده کرد.

// /src/common/decorators/api-response.decorator.ts
import { applyDecorators } from ‘@nestjs/common’;
import { ApiResponse, ApiOperation } from ‘@nestjs/swagger’;

export const ApiStandardResponse = (description: string) => {
return applyDecorators(
ApiOperation({ description }),
ApiResponse({
status: 200,
description: ‘Request was successful’,
}),
ApiResponse({
status: 400,
description: ‘Bad Request’,
}),
ApiResponse({
status: 500,
description: ‘Internal Server Error’,
}),
);
};

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

لوله ها

validation.pipe.ts

یک لوله اعتبارسنجی جهانی که درخواست های دریافتی را در برابر DTO ها با استفاده از اعتبارسنجی می کند اعتبار سنجی کلاس.

// /src/common/pipes/validation.pipe.ts
import {
ArgumentMetadata,
BadRequestException,
Injectable,
PipeTransform,
} from ‘@nestjs/common’;
import { plainToInstance } from ‘class-transformer’;
import { validate } from ‘class-validator’;

@Injectable()
export class ValidationPipe implements PipeTransform {
async transform(value: any, { metatype }: ArgumentMetadata) {
if (!metatype || !this.toValidate(metatype)) {
return value;
}

const object = plainToInstance(metatype, value);
const errors = await validate(object);
if (errors.length > 0) {
throw new BadRequestException(‘Validation failed’);
}
return value;
}

private toValidate(metatype: Function): boolean {
const types: Function[] = [String, Boolean, Number, Array, Object];
return !types.includes(metatype);
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

3. ماژول برنامه و نقطه ورودی اصلی

app.module.ts

ماژول ریشه برنامه شما که همه ماژول های ویژگی را وارد می کند، از جمله ماژول پایگاه داده و CommonModule.

// /src/app.module.ts
import { Module } from ‘@nestjs/common’;
import { DatabaseModule } from ‘./database/database.module’;
import { EventsModule } from ‘./events/events.module’;
import { TicketsModule } from ‘./tickets/tickets.module’;
import { PaymentsModule } from ‘./payments/payments.module’;
import { NotificationsModule } from ‘./notifications/notifications.module’;
import { APP_FILTER, APP_INTERCEPTOR, APP_PIPE } from ‘@nestjs/core’;
import { AllExceptionsFilter } from ‘./common/filters/all-exceptions.filter’;
import { TransformInterceptor } from ‘./common/interceptors/transform.interceptor’;
import { ValidationPipe } from ‘./common/pipes/validation.pipe’;

@Module({
imports: [
DatabaseModule,
EventsModule,
TicketsModule,
PaymentsModule,
NotificationsModule,
],
providers: [
{
provide: APP_FILTER,
useClass: AllExceptionsFilter,
},
{
provide: APP_INTERCEPTOR,
useClass: TransformInterceptor,
},
{
provide: APP_PIPE,
useClass: ValidationPipe,
},
],
})
export class AppModule {}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

main.ts

نقطه ورود اصلی برنامه این فایل فیلترهای سراسری، لوله‌ها را پیکربندی می‌کند و آن را راه‌اندازی می‌کند NestJS سرور

// /src/main.ts
import { NestFactory } from ‘@nestjs/core’;
import { AppModule } from ‘./app.module’;
import { ValidationPipe } from ‘./common/pipes/validation.pipe’;
import { AllExceptionsFilter } from ‘./common/filters/all-exceptions.filter’;
import { TransformInterceptor } from ‘./common/interceptors/transform.interceptor’;

async function bootstrap() {
const app = await NestFactory.create(AppModule);

// Apply global validation pipe
app.useGlobalPipes(new ValidationPipe());

// Apply global exception filter
app.useGlobalFilters(new AllExceptionsFilter());

// Apply global transform interceptor
app.useGlobalInterceptors(new TransformInterceptor());

await app.listen(3000);
}
bootstrap();

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

خلاصه

این ساختار شامل:

ماژول پایگاه داده:

پیکربندی می کند TypeORM با جزئیات و نهادهای اتصال.
می توان آن را برای انجام پرس و جوهای پایگاه داده خام یا عملیات سفارشی گسترش داد.

ابزارهای مشترک:

فیلتر استثنای جهانی: همه استثناها را به طور یکنواخت می گیرد و مدیریت می کند.

رهگیرها: به طور خودکار پاسخ های API را به یک ساختار سازگار تبدیل کنید.

لوله اعتبار سنجی: درخواست های دریافتی را با استفاده از DTO و class-validator اعتبار سنجی می کند.

دکوراتورها: تزئینات قابل استفاده مجدد برای حاشیه نویسی API ها.

AppModule و Main Entry:

ریشه NestJS ماژول برنامه ای که همه چیز را به هم پیوند می دهد.
پیکربندی می کند لوله های جهانی، فیلترها، و

رهگیرها برای اطمینان از رفتار سازگار در سراسر برنامه.

این تنظیمات بسیار ماژولار، قابل نگهداری و به شرح زیر است NestJS بهترین شیوه ها اکنون می توانید ماژول های اضافی اضافه کنید یا ماژول های موجود را با این پایه گسترش دهید.

اگر از مطالب من لذت می برید و می خواهید از کار من حمایت کنید، می توانید یک قهوه برای من بخرید. حمایت شما بسیار قدردانی می شود!

سلب مسئولیت: این محتوا توسط هوش مصنوعی تولید شده است.

برای توسعه یک بستر میزبانی رویداد مجازی با استفاده از Next.js 14 و Tailwind CSS، شما نیاز به تفکیک واضحی از ویژگی‌ها و عملکردها برای جنبه‌های جلویی، بک‌اند و برنامه تلفن همراه پروژه خود دارید. در اینجا یک طرح کلی از ویژگی ها و عملکردهای هر جزء آورده شده است:

فهرست مطالب

1. ویژگی های Front-End (Next.js 14 + Tailwind CSS)

ایجاد رویداد:

  • فرم رویداد: به کاربران امکان می دهد رویدادهایی را با ورودی هایی برای نام رویداد، توضیحات، تاریخ، زمان، قیمت و دسته ایجاد کنند.
  • بارگذاری رسانه رویداد: ادغام با فضای ذخیره سازی ابری (به عنوان مثال، AWS S3) برای آپلود تصاویر یا ویدیوها برای رویداد.
  • مدیریت بلیط: انواع مختلف بلیط (پذیرش عمومی، VIP و غیره) را ایجاد کنید، قیمت ها و در دسترس بودن را تعیین کنید.
  • پیش نمایش رویداد: یک گزینه پیش نمایش که به سازمان دهندگان امکان می دهد قبل از انتشار صفحه رویدادشان را ببینند.
  • صفحات بهینه شده سئو: هر صفحه رویداد باید دارای ابرداده مناسب برای دید بهتر در موتورهای جستجو باشد.
  • طراحی واکنشگرا: با استفاده از Tailwind CSS از تجربه یکپارچه در همه دستگاه‌ها اطمینان حاصل کنید و اطمینان حاصل کنید که چیدمان با صفحه‌نمایش‌های موبایل، تبلت و دسکتاپ سازگار است.

خرید بلیط:

  • احراز هویت: OAuth و ادغام ورود به سیستم اجتماعی برای کاربران برای ایجاد حساب یا ورود به سیستم برای خرید بلیط.
  • انتخاب بلیط: کاربران می توانند بلیط های رویداد را انتخاب کرده و به پرداخت ادامه دهند.
  • یکپارچه سازی درگاه پرداخت: ادغام با Stripe، PayPal یا موارد مشابه برای پرداخت های ایمن.
  • خلاصه سفارش: نمایش انتخاب نهایی بلیط و قیمت با خلاصه سفارش قبل از تایید.
  • تایید ایمیل: یک ایمیل تأیید با جزئیات بلیط و یک کد QR ارسال کنید.

پخش زنده:

  • پخش کننده ویدیوی جاسازی شده: پخش‌های زنده را مستقیماً در صفحه رویداد جاسازی کنید، احتمالاً از طریق ادغام با پلتفرم‌های جریان (یوتیوب، ویمئو یا سرور RTMP سفارشی).
  • پخش در زمان واقعی: از WebRTC یا یک سرویس شخص ثالث (به عنوان مثال، Agora، Twilio) برای پخش جریانی با تاخیر کم و در زمان واقعی استفاده کنید.
  • چت زنده: چت بیدرنگ در طول رویداد با استفاده از WebSockets (به عنوان مثال، Socket.io یا Pusher).
  • انتخاب کیفیت جریان: به کاربران اجازه دهید بر اساس پهنای باند خود کیفیت های مختلف پخش (خودکار، 480p، 720p، 1080p) را انتخاب کنند.

2. ویژگی های Back-End (Next.js 14 مسیرهای API / توابع بدون سرور)

مدیریت رویداد:

  • عملیات CRUD رویداد: سازمان‌دهندگان می‌توانند رویدادها را ایجاد، به‌روزرسانی و حذف کنند. این شامل مدیریت جزئیات رویداد، انواع بلیط، و در دسترس بودن بلیط است.
  • پردازش پرداخت: اطلاعات پرداخت را ایمن مدیریت کنید، از تراکنش‌های موفق اطمینان حاصل کنید، و رسید پرداخت را ایجاد کنید.
  • مدیریت کاربر: حساب های کاربری، نمایه ها و کنترل دسترسی مبتنی بر نقش را مدیریت کنید (مثلاً سازمان دهندگان رویداد در مقابل شرکت کنندگان).
  • داشبورد تجزیه و تحلیل: به سازمان‌دهندگان رویداد اطلاعاتی در مورد فروش بلیت، شرکت‌کنندگان و مشارکت در جریان ارائه دهید.

درگاه پرداخت:

  • ادغام با Stripe یا PayPal: رسیدگی به تمام تراکنش های پرداخت با بازپرداخت و اختلافات.
  • گزارش پرداخت: جزئیات تراکنش، از جمله وضعیت پرداخت، روش، مبلغ و جزئیات مشتری را ذخیره کنید.
  • اعتبار سنجی بلیط: به صورت خودکار کدهای QR یا بارکدهای منحصر به فرد را برای هر بلیط خریداری شده برای دسترسی به رویداد ایجاد کنید.

اطلاعیه ها:

  • اعلان های ایمیل: هشدارهای ایمیلی را برای به روز رسانی رویداد، خرید بلیط و یادآوری رویداد (به عنوان مثال، SendGrid یا AWS SES) راه اندازی کنید.
  • اعلان های پیامکی: با Twilio یا خدمات مشابه یکپارچه شوید تا اعلان های پیامکی برای تأیید بلیط یا یادآوری رویداد ارسال شود.
  • Push Notifications: برای به‌روزرسانی رویدادها و یادآوری‌ها برای کاربرانی که انتخاب می‌کنند، با Firebase Cloud Messaging ادغام شود.

3. ویژگی های اپلیکیشن موبایل (React Native یا Expo)

مرور رویداد:

  • لیست رویدادها: نمایش تمام رویدادهای آینده و گذشته با گزینه های جستجو و فیلتر.
  • صفحه جزئیات رویداد: نمایش اطلاعات دقیق برای هر رویداد، از جمله گزینه خرید بلیط.
  • رابط کاربری پاسخگو: برنامه باید با اندازه های مختلف صفحه نمایش دستگاه تلفن همراه سازگار شود.

مشارکت در رویداد:

  • به رویداد مجازی بپیوندید: به کاربران اجازه می دهد تا مستقیماً از طریق برنامه از طریق جریان جاسازی شده به یک رویداد زنده بپیوندند.
  • بلیط درون برنامه ای: کاربران می توانند با یک فرآیند پرداخت ساده، بلیط را از طریق برنامه خریداری کنند.
  • پرسش و پاسخ زنده: بخش اختصاصی برای ارسال سوالات در طول رویدادهای زنده (WebSockets یا یک سرویس شخص ثالث).
  • نظرسنجی و نظرسنجی زنده: ویژگی‌های تعامل بی‌درنگ مانند نظرسنجی در طول رویداد برای افزایش تعامل.

اطلاعیه ها:

  • یادآوری رویداد: قبل از زمان شروع رویداد، اعلان‌ها را برای یادآوری رویداد فشار دهید.
  • به روز رسانی در زمان واقعی: اعلان‌های فشاری برای به‌روزرسانی رویداد یا اعلان‌های تعامل زنده در طول رویداد.

4. ویژگی های عمومی

  • جستجو و فیلتر کردن: جستجوی متن کامل در رویدادها و فیلترها بر اساس طبقه بندی، قیمت، تاریخ و محبوبیت.
  • احراز هویت کاربر و پروفایل ها: ادغام با ارائه دهندگان OAuth (گوگل، فیسبوک و غیره) برای احراز هویت کاربر. کاربران می توانند نمایه های خود را به روز کنند، تاریخچه خرید را مشاهده کنند و اعلان ها را مدیریت کنند.
  • داشبورد مدیریت: بخش اختصاصی برای سرپرستان برای نظارت بر کل پلتفرم (مدیریت کاربر، نظارت رویداد، تجزیه و تحلیل).
  • امنیت و مقیاس پذیری: پیاده سازی OAuth برای مدیریت کاربر و راه حل های مقیاس پذیر برای پخش و تهیه بلیط.

5. اسناد و منابع برای پیاده سازی

Next.js 14:

  • استفاده کنید روتر برنامه برای ساخت مسیرهای پویا و رندر صفحات با استفاده از مؤلفه های سرور و کلاینت 【7†source】.
  • پیاده سازی کنید Tailwind CSS برای یک ظاهر طراحی شده (Next.js پشتیبانی داخلی از Tailwind CSS را ارائه می دهد)【7†منبع】.
  • دنبال کنید Next.js بهترین شیوه ها برای سئو، رندر سمت سرور (SSR)، تولید استاتیک (SSG)، و رندر سمت مشتری (CSR)【7†منبع】.

Tailwind CSS:

  • طراحی پاسخگو و اولین رویکرد کاربردی برای ساده سازی ساخت UI در سراسر پلتفرم.

پخش جریانی:

  • به خدماتی مانند در حال حاضر، تویلیو، یا WebRTC برای اجرای جریان بلادرنگ【6†منبع】.

API:

  • می توانید استفاده کنید مسیرهای API Next.js برای مدیریت منطق بک‌اند برای خرید بلیط، مدیریت رویداد، و اعلان‌ها【7†منبع】.

با این تفکیک، اکنون می توانید ساختن پلتفرم میزبانی رویداد مجازی خود را با تمرکز بر تجربه کاربر، تعامل در زمان واقعی و مقیاس پذیری شروع کنید.

برای پیشانی از پلتفرم میزبانی رویداد مجازی خود با استفاده از Next.js 14 و Tailwind CSS، ساختار پوشه باید از قراردادهای مدولار بودن، مقیاس پذیری و قابلیت نگهداری پیروی کند. در اینجا یک ساختار پوشه پیشنهادی وجود دارد:

/your-project-name
│
├── /app                 # Main directory for Next.js App Router (used for routes and pages)
│   ├── /(event)         # Event-related routes grouped here
│   │   ├── create       # Event creation page
│   │   │   ├── page.tsx # Main page file for creating events
│   │   ├── [eventId]    # Dynamic route for a specific event's details
│   │   │   ├── page.tsx # Event details page
│   │   ├── live         # Page for live streaming
│   │   │   ├── page.tsx # Live streaming page
│   │   ├── list         # List of all events
│   │   │   ├── page.tsx # Event listing page
│   │   ├── qna          # Page for live Q&A during events
│   │       ├── page.tsx # Live Q&A page
│   │
│   ├── /(user)          # Group for user-related routes
│   │   ├── profile      # User profile page
│   │   │   ├── page.tsx # Profile page component
│   │   ├── login        # User login page
│   │   │   ├── page.tsx # Login page component
│   │   ├── register     # User registration page
│   │       ├── page.tsx # Registration page component
│   │
│   ├── layout.tsx       # Global layout for shared UI (header, footer, etc.)
│   ├── global.css       # Global CSS (where Tailwind's @import goes)
│   └── _app.tsx         # Custom App component for handling global state
│
├── /components          # Reusable UI components
│   ├── EventCard.tsx    # Card component for displaying event info
│   ├── Navbar.tsx       # Navigation bar component
│   ├── Footer.tsx       # Footer component
│   ├── Button.tsx       # Generic Button component
│   ├── Modal.tsx        # Modal component for popups
│   └── Loader.tsx       # Loader component for loading states
│
├── /hooks               # Custom React hooks
│   ├── useAuth.ts       # Hook for authentication management
│   ├── useEvent.ts      # Hook for fetching and managing event data
│   └── useStream.ts     # Hook for handling live stream interactions
│
├── /lib                 # Utilities and helper functions
│   ├── api.ts           # API calls to back-end services
│   └── validators.ts    # Validation functions for forms
│
├── /public              # Static assets like images, icons, and fonts
│   ├── /images          # Image assets for events, logos, etc.
│   ├── favicon.ico      # Favicon for the app
│   └── logo.png         # Application logo
│
├── /styles              # Additional global styles (if needed)
│   ├── tailwind.config.js # Tailwind CSS configuration file
│   ├── globals.css      # Global styles (optional, Tailwind CSS covers most)
│
├── /types               # TypeScript types
│   ├── event.ts         # Type definitions for event-related data
│   └── user.ts          # Type definitions for user data
│
├── next.config.js       # Next.js configuration file
├── tailwind.config.js   # Tailwind CSS configuration file
├── tsconfig.json        # TypeScript configuration
├── package.json         # Dependencies and scripts
├── .eslintrc.js         # ESLint configuration for linting
├── .prettierrc          # Prettier configuration for code formatting
└── .gitignore           # Files to be ignored by Git
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

تفکیک ساختار پوشه:

  1. /app:

    • روتر برنامه ساختار پوشه توصیه شده برای Next.js است. هر پوشه در اینجا نشان دهنده یک مسیر است. را (event) و (user) گروه ها به ترتیب گروه های مسیری برای مسیرهای رویداد و مسیرهای مرتبط با کاربر هستند.
    • layout.tsx: یک فایل طرح بندی جهانی که می تواند اجزای مشترکی مانند نوار ناوبری و پاورقی را برای همه صفحات تعریف کند.
  2. /components:

    • شامل تمام اجزای رابط کاربری قابل استفاده مجدد مانند دکمه ها، کارت ها و مدال ها است.
    • این امر استفاده مجدد و ماژولار بودن کد را تشویق می کند و مقیاس پروژه را آسان تر می کند.
  3. /hooks:

    • قلاب‌های سفارشی را برای مدیریت منطق مانند احراز هویت، واکشی داده‌های رویداد و تعاملات پخش زنده ذخیره می‌کند.
  4. /lib:

    • توابع و کمک‌کننده‌های ابزار، مانند فراخوانی‌های API یا تأییدکننده‌های فرم، که می‌توانند مجدداً در اجزای مختلف استفاده شوند.
  5. /public:

    • حاوی دارایی های ثابت مانند تصاویر و نمادها است که مستقیماً توسط Next.js بدون پردازش ارائه می شوند.
  6. /styles:

    • این پوشه حاوی هر سبک دیگری است که ممکن است به آن نیاز داشته باشید، اگرچه بیشتر استایل ها از طریق Tailwind CSS انجام می شود.
    • فایل پیکربندی Tailwind برای سفارشی سازی در اینجا زندگی می کند.
  7. /types:

    • تعاریف نوع TypeScript را ذخیره می کند تا از تایپ قوی در سراسر برنامه برای نهادهایی مانند اطمینان حاصل کند event، userو غیره
  8. فایل های پیکربندی:

    • next.config.js: پیکربندی مخصوص Next.js مانند بهینه سازی تصاویر، بسته وب سفارشی یا تنظیمات مسیریابی.
    • tailwind.config.js: برای پیکربندی Tailwind CSS برای گسترش آن با رنگ‌ها، فاصله‌ها و تم‌های سفارشی.
    • tsconfig.json: فایل پیکربندی TypeScript برای تنظیم قوانین برای کامپایل TypeScript.
    • package.json: وابستگی ها، اسکریپت ها و متا اطلاعات پروژه را مدیریت می کند.

نکات کلیدی:

  • روتر برنامه برای Next.js 14 استفاده می شود، پشتیبانی می کند اجزای سرور و مشتری، مسیریابی پویا، و جریان.
  • Tailwind CSS یک ظاهر طراحی شده را ساده می کند و طراحی واکنشگرا را در خارج از جعبه ترویج می کند.
  • گروه بندی پوشه (event، user) به سازماندهی منطقی مسیرهای مختلف کمک می کند که برای برنامه های بزرگ ضروری است.

این ساختار یک راه‌اندازی مدولار و مقیاس‌پذیر را فراهم می‌کند که نگهداری و گسترش آن را با رشد پلت فرم شما آسان می‌کند.

برای توسعه باطن برای شما بستر میزبانی رویداد مجازی با استفاده از NestJS و PostgreSQL، بسیار مهم است که پروژه خود را برای مقیاس پذیری، مدولار بودن و قابلیت نگهداری ساختار دهید. در زیر ساختار پوشه‌ای وجود دارد که کد شما را در ماژول‌های مبتنی بر ویژگی سازماندهی می‌کند و در عین حال به بهترین شیوه‌های NestJS پایبند است.

ساختار پوشه پیشنهادی برای NestJS Backend:

/your-backend-project
│
├── /src                     # Main source folder for the backend
│   ├── /auth                # Module for authentication
│   │   ├── auth.controller.ts
│   │   ├── auth.module.ts
│   │   ├── auth.service.ts
│   │   ├── jwt.strategy.ts
│   │   ├── local.strategy.ts
│   │   ├── dto              # DTOs for request validation
│   │   │   ├── login.dto.ts
│   │   │   ├── register.dto.ts
│   │   ├── guards           # Guards for role-based access
│   │   │   ├── jwt-auth.guard.ts
│   │   │   ├── roles.guard.ts
│   │   ├── decorators       # Custom decorators like roles
│   │       ├── roles.decorator.ts
│   ├── /users               # User module for managing users
│   │   ├── users.controller.ts
│   │   ├── users.module.ts
│   │   ├── users.service.ts
│   │   ├── entities         # TypeORM entity for users
│   │   │   ├── user.entity.ts
│   │   ├── dto              # User-related DTOs
│   │       ├── create-user.dto.ts
│   │       ├── update-user.dto.ts
│   ├── /events              # Event module for managing events
│   │   ├── events.controller.ts
│   │   ├── events.module.ts
│   │   ├── events.service.ts
│   │   ├── entities         # TypeORM entity for events
│   │   │   ├── event.entity.ts
│   │   ├── dto              # Event-related DTOs
│   │       ├── create-event.dto.ts
│   │       ├── update-event.dto.ts
│   ├── /tickets             # Ticketing module for event tickets
│   │   ├── tickets.controller.ts
│   │   ├── tickets.module.ts
│   │   ├── tickets.service.ts
│   │   ├── entities         # TypeORM entity for tickets
│   │   │   ├── ticket.entity.ts
│   │   ├── dto              # DTOs for ticket-related operations
│   │       ├── create-ticket.dto.ts
│   │       ├── update-ticket.dto.ts
│   ├── /payments            # Payment module for managing transactions
│   │   ├── payments.controller.ts
│   │   ├── payments.module.ts
│   │   ├── payments.service.ts
│   │   ├── entities         # TypeORM entity for payments
│   │   │   ├── payment.entity.ts
│   │   ├── dto              # Payment-related DTOs
│   │       ├── create-payment.dto.ts
│   ├── /notifications       # Notifications module for email, SMS, and push notifications
│   │   ├── notifications.controller.ts
│   │   ├── notifications.module.ts
│   │   ├── notifications.service.ts
│   │   ├── dto              # Notification-related DTOs
│   │       ├── create-notification.dto.ts
│   ├── /database            # Database module for TypeORM configurations
│   │   ├── database.module.ts
│   │   ├── database.service.ts
│   │   ├── ormconfig.ts      # TypeORM configuration
│   ├── /common              # Shared utilities, guards, interceptors, and exceptions
│   │   ├── /filters         # Global exception filters
│   │   │   ├── all-exceptions.filter.ts
│   │   ├── /interceptors    # Interceptors for response transformation, logging, etc.
│   │   │   ├── transform.interceptor.ts
│   │   ├── /decorators      # Reusable decorators
│   │   │   ├── api-response.decorator.ts
│   │   ├── /pipes           # Global pipes for validation, etc.
│   │   │   ├── validation.pipe.ts
│   ├── app.module.ts        # Root application module
│   ├── main.ts              # Main entry point of the application
│
├── /test                    # Tests for the application
│   ├── /e2e                 # End-to-end tests
│   ├── /unit                # Unit tests
│
├── /config                  # Configuration files for different environments
│   ├── config.ts            # Configuration for database, security, etc.
├── .env                     # Environment variables
├── .eslintrc.js             # ESLint configuration for linting
├── .prettierrc              # Prettier configuration for code formatting
├── tsconfig.json            # TypeScript configuration
├── package.json             # Dependencies and scripts
├── README.md                # Project documentation
└── .gitignore               # Files and folders to ignore in Git
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

تفکیک ساختار پوشه:

  1. /src:

    • دایرکتوری اصلی برای کل برنامه، همه ماژول‌ها، خدمات، کنترل‌کننده‌ها و موجودیت‌ها را در خود جای می‌دهد.
  2. /auth:

    • دستگیره ها احراز هویت و مجوز.
    • شامل استراتژی هایی برای JWT و احراز هویت محلی، همراه با نگهبانان و دکوراتورهای سفارشی مانند @Roles.
  3. /users:

    • دستگیره ها مدیریت کاربر، از جمله عملیات CRUD کاربر.
    • فروشگاه ها نهادهای کاربر و مرتبط DTO ها برای اعتبار سنجی درخواست
  4. /events:

    • مدیریت می کند رویدادها از جمله ایجاد رویداد، به روز رسانی، و بازیابی.
    • حاوی رویداد خاص است نهادها و DTO ها.
  5. /tickets:

    • مدیریت می کند بلیط رویداداز جمله ایجاد، به‌روزرسانی و بازیابی بلیط‌ها.
    • شامل نهادهای مخصوص بلیط و DTOها می شود.
  6. /payments:

    • مدیریت می کند پردازش پرداخت و ادغام با درگاه های پرداخت مانند راه راه یا پی پال.
    • دستگیره ها ثبت تراکنش ها و عملیات مربوط به پرداخت
  7. /notifications:

    • دستگیره ها ایمیل، اس ام اس و اعلان های فشاری.
    • با خدماتی مانند ادغام می شود تویلیو، Firebase، یا SendGrid برای اطلاعیه ها
  8. /database:

    • مدیریت می کند اتصالات و تنظیمات پایگاه داده با استفاده از TypeORM.
    • فروشگاه ها تنظیمات ORM و ماژول پایگاه داده راه اندازی
  9. /common:

    • حاوی خدمات مشترک مانند جهانی فیلترهای استثنا، رهگیرها، لوله ها، و دکوراتورها که می تواند دوباره در سراسر برنامه استفاده شود.
  10. /test:

    • سازماندهی می کند تست های واحد و تست های پایان به انتها (e2e). با استفاده از است.
  11. /config:

    • پیکربندی های خاص محیط را مدیریت می کند، از جمله رشته های اتصال پایگاه داده، کلیدهای API، و تنظیمات امنیتی.
    • استفاده می کند .env فایل هایی برای اطلاعات حساس
  12. فایل های ریشه:

    • app.module.ts: ماژول ریشه که همه ماژول های دیگر را وارد می کند.
    • main.ts: نقطه ورود برنامه ای که سرور NestJS در آن بوت استرپ شده است.
    • .env: متغیرهای محیطی مانند اعتبار پایگاه داده، کلیدهای مخفی و غیره را ذخیره می کند.

مفاهیم کلیدی:

  • ماژول های ویژگی: NestJS ماژول های ویژگی را ارتقا می دهد، جایی که هر دامنه (به عنوان مثال، auth، users، events) دارای ماژول ایزوله شده خود است که برنامه را مقیاس پذیر و نگهداری آسان تر می کند.
  • TypeORM: برای مدیریت پایگاه داده، از جمله تعریف موجودیت ها (مانند User، Event، Ticket، Payment) و اجرای پرس و جوها با پایگاه داده PostgreSQL.
  • DTO ها: برای اعتبارسنجی ورودی و انتقال داده بین کنترلرها و سرویس ها استفاده می شود.
  • نگهبانان و رهگیران: به مدیریت احراز هویت درخواست، نقش‌ها و تبدیل‌های پاسخ کمک کنید.
  • تست کردن: شامل تست‌های واحد و e2e برای کنترل‌کننده‌ها، سرویس‌ها و ماژول‌ها برای اطمینان از عملکرد برنامه همانطور که انتظار می‌رود.

این ساختار تضمین می‌کند که باطن شما مقیاس‌پذیر، مدولار و نگهداری آسان در حین ساختن پلتفرم خود باشد.

در زیر ساختار کد کامل برای هر فایل ذکر شده در درخواست شما با استفاده از آن آمده است Next.js 14 و TypeScript. این شامل ایجاد رویدادها، نمایش جزئیات رویداد، مدیریت پخش زنده، فهرست کردن رویدادها، و صفحه پرسش و پاسخ برای رویدادهای مجازی است. این ساختار به دنبال دارد روتر برنامه Next.js کنوانسیون ها

نمای کلی ساختار پوشه

/app
├── /(event)
│   ├── create
│   │   └── page.tsx
│   ├── [eventId]
│   │   └── page.tsx
│   ├── live
│   │   └── page.tsx
│   ├── list
│   │   └── page.tsx
│   ├── qna
│       └── page.tsx
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

1. صفحه ایجاد رویداد/app/(event)/create/page.tsx

// /app/(event)/create/page.tsx
import React, { useState } from 'react';

const CreateEventPage: React.FC = () => {
  const [formData, setFormData] = useState({
    name: '',
    description: '',
    date: '',
    time: '',
    price: '',
  });

  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
    const { name, value } = e.target;
    setFormData((prevData) => ({
      ...prevData,
      [name]: value,
    }));
  };

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    console.log('Event Data:', formData);
    // Call an API to create the event
  };

  return (
    <div className="container mx-auto p-4">
      <h1 className="text-2xl font-bold mb-4">Create New Eventh1>
      <form onSubmit={handleSubmit} className="space-y-4">
        <div>
          <label className="block">Event Namelabel>
          <input
            name="name"
            type="text"
            className="w-full p-2 border rounded"
            value={formData.name}
            onChange={handleInputChange}
            required
          />
        div>
        <div>
          <label className="block">Descriptionlabel>
          <textarea
            name="description"
            className="w-full p-2 border rounded"
            value={formData.description}
            onChange={handleInputChange}
            required
          />
        div>
        <div>
          <label className="block">Datelabel>
          <input
            name="date"
            type="date"
            className="w-full p-2 border rounded"
            value={formData.date}
            onChange={handleInputChange}
            required
          />
        div>
        <div>
          <label className="block">Timelabel>
          <input
            name="time"
            type="time"
            className="w-full p-2 border rounded"
            value={formData.time}
            onChange={handleInputChange}
            required
          />
        div>
        <div>
          <label className="block">Pricelabel>
          <input
            name="price"
            type="number"
            className="w-full p-2 border rounded"
            value={formData.price}
            onChange={handleInputChange}
            required
          />
        div>
        <button type="submit" className="bg-blue-500 text-white p-2 rounded">Create Eventbutton>
      form>
    div>
  );
};

export default CreateEventPage;
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

2. صفحه جزئیات رویداد/app/(event)/[eventId]/page.tsx

// /app/(event)/[eventId]/page.tsx
import { useRouter } from 'next/router';
import React from 'react';

const EventDetailsPage: React.FC = () => {
  const router = useRouter();
  const { eventId } = router.query; // Accessing eventId from the route

  // Fetch event details using eventId (replace with actual API call)
  const event = {
    id: eventId,
    name: 'Sample Event',
    description: 'This is a description of the event.',
    date: '2024-10-30',
    time: '14:00',
    price: 20,
  };

  return (
    <div className="container mx-auto p-4">
      <h1 className="text-3xl font-bold">{event.name}h1>
      <p className="mt-2">{event.description}p>
      <p className="mt-4">Date: {event.date}p>
      <p className="mt-1">Time: {event.time}p>
      <p className="mt-4">Price: ${event.price}p>
      <button className="bg-green-500 text-white p-2 rounded mt-4">Buy Ticketsbutton>
    div>
  );
};

export default EventDetailsPage;
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

3. صفحه پخش زنده/app/(event)/live/page.tsx

// /app/(event)/live/page.tsx
import React from 'react';

const LiveStreamPage: React.FC = () => {
  // Placeholder: Replace with actual live stream integration
  const liveStreamUrl = 'https://www.example.com/livestream'; // Replace with actual stream URL

  return (
    <div className="container mx-auto p-4">
      <h1 className="text-3xl font-bold">Live Event Streamh1>
      <div className="mt-4">
        <iframe
          width="100%"
          height="500"
          src={liveStreamUrl}
          frameBorder="0"
          allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
          allowFullScreen
        >iframe>
      div>
    div>
  );
};

export default LiveStreamPage;
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

4. صفحه فهرست رویداد/app/(event)/list/page.tsx

// /app/(event)/list/page.tsx
import Link from 'next/link';
import React from 'react';

const EventListPage: React.FC = () => {
  // Placeholder: Replace with actual event list from API
  const events = [
    { id: '1', name: 'Event 1', date: '2024-11-01', price: 30 },
    { id: '2', name: 'Event 2', date: '2024-11-05', price: 20 },
  ];

  return (
    <div className="container mx-auto p-4">
      <h1 className="text-2xl font-bold">Upcoming Eventsh1>
      <ul className="mt-4">
        {events.map((event) => (
          <li key={event.id} className="mb-4">
            <Link href={`/event/${event.id}`}>
              <a className="block p-4 border rounded hover:bg-gray-100">
                <h2 className="text-xl">{event.name}h2>
                <p>Date: {event.date}p>
                <p>Price: ${event.price}p>
              a>
            Link>
          li>
        ))}
      ul>
    div>
  );
};

export default EventListPage;
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

5. صفحه پرسش و پاسخ زنده/app/(event)/qna/page.tsx

// /app/(event)/qna/page.tsx
import React, { useState } from 'react';

const QnAPage: React.FC = () => {
  const [question, setQuestion] = useState('');
  const [questions, setQuestions] = useState<string[]>([]);

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    setQuestions((prevQuestions) => [...prevQuestions, question]);
    setQuestion('');
  };

  return (
    <div className="container mx-auto p-4">
      <h1 className="text-2xl font-bold mb-4">Live Q&Ah1>
      <form onSubmit={handleSubmit} className="mb-6">
        <input
          type="text"
          className="w-full p-2 border rounded mb-2"
          placeholder="Ask your question"
          value={question}
          onChange={(e) => setQuestion(e.target.value)}
          required
        />
        <button type="submit" className="bg-blue-500 text-white p-2 rounded">Submit Questionbutton>
      form>
      <ul>
        {questions.map((q, index) => (
          <li key={index} className="mb-2 border p-2 rounded">
            {q}
          li>
        ))}
      ul>
    div>
  );
};

export default QnAPage;
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نکات کلیدی:

  1. ایجاد رویداد: فرمی که کاربران می توانند جزئیات رویداد (نام، توضیحات، تاریخ و غیره) را وارد کرده و رویداد را ارسال کنند.
  2. جزئیات رویداد: یک مسیر پویا با استفاده از [eventId] برای نمایش جزئیات هر رویداد. داده های رویداد را بر اساس واکشی می کند eventId.
  3. پخش زنده: یک iframe تعبیه شده برای نمایش پخش زنده ویدیو.
  4. لیست رویداد: فهرست ساده ای از رویدادها که به صفحه جزئیات هر رویداد پیوند می دهد

.

  1. پرسش و پاسخ: یک بخش پرسش و پاسخ زنده که در آن کاربران می توانند سوالات خود را ارسال کنند و به صورت پویا لیست سوالات را به روز می کند.

می‌توانید این کد را با یکپارچه‌سازی APIها برای واکشی داده‌های رویداد، مدیریت پخش‌های زنده و ارسال سؤالات پرسش و پاسخ به پشتیبان، بیشتر گسترش دهید.

در اینجا کد کامل برای مسیرهای مربوط به کاربر و اجزای مشترک اضافی در الف Next.js 14 پروژه این شامل صفحه پروفایل، صفحه ورود، صفحه ثبت نامو اجزای مشترک مانند چیدمان جهانی و CSS جهانی فایل این صفحات نیز استفاده خواهند کرد Tailwind CSS برای یک ظاهر طراحی شده

نمای کلی ساختار پوشه

/app
├── /(user)             # User-related routes
│   ├── profile         # User profile page
│   │   └── page.tsx    # Profile page component
│   ├── login           # User login page
│   │   └── page.tsx    # Login page component
│   ├── register        # User registration page
│       └── page.tsx    # Registration page component
│
├── layout.tsx          # Global layout for shared UI (header, footer, etc.)
├── global.css          # Global CSS (Tailwind CSS imports)
└── _app.tsx            # Custom App component for global state or context
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

1. صفحه نمایه کاربر/app/(user)/profile/page.tsx

// /app/(user)/profile/page.tsx
import React from 'react';

const ProfilePage: React.FC = () => {
  // Placeholder user data (fetch real user data via an API)
  const user = {
    name: 'John Doe',
    email: 'john.doe@example.com',
    joined: '2023-01-01',
  };

  return (
    <div className="container mx-auto p-4">
      <h1 className="text-3xl font-bold">User Profileh1>
      <div className="mt-4">
        <p><strong>Name:strong> {user.name}p>
        <p><strong>Email:strong> {user.email}p>
        <p><strong>Joined:strong> {user.joined}p>
      div>
      <button className="bg-blue-500 text-white p-2 mt-4 rounded">Edit Profilebutton>
    div>
  );
};

export default ProfilePage;
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

2. صفحه ورود کاربر/app/(user)/login/page.tsx

// /app/(user)/login/page.tsx
import React, { useState } from 'react';
import { useRouter } from 'next/router';

const LoginPage: React.FC = () => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const router = useRouter();

  const handleLogin = (e: React.FormEvent) => {
    e.preventDefault();
    // Placeholder login logic (replace with API call)
    console.log('Logging in:', { email, password });
    router.push('/'); // Redirect to homepage after login
  };

  return (
    <div className="container mx-auto p-4">
      <h1 className="text-2xl font-bold mb-4">Loginh1>
      <form onSubmit={handleLogin} className="space-y-4">
        <div>
          <label className="block">Emaillabel>
          <input
            type="email"
            className="w-full p-2 border rounded"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            required
          />
        div>
        <div>
          <label className="block">Passwordlabel>
          <input
            type="password"
            className="w-full p-2 border rounded"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            required
          />
        div>
        <button type="submit" className="bg-blue-500 text-white p-2 rounded">
          Login
        button>
      form>
      <p className="mt-4">
        Don't have an account?{' '}
        <a href="/user/register" className="text-blue-500">Register herea>.
      p>
    div>
  );
};

export default LoginPage;
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

3. صفحه ثبت نام کاربر/app/(user)/register/page.tsx

// /app/(user)/register/page.tsx
import React, { useState } from 'react';
import { useRouter } from 'next/router';

const RegisterPage: React.FC = () => {
  const [formData, setFormData] = useState({
    name: '',
    email: '',
    password: '',
  });
  const router = useRouter();

  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = e.target;
    setFormData((prevData) => ({
      ...prevData,
      [name]: value,
    }));
  };

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    // Placeholder registration logic (replace with API call)
    console.log('Registering user:', formData);
    router.push('/user/login'); // Redirect to login page after registration
  };

  return (
    <div className="container mx-auto p-4">
      <h1 className="text-2xl font-bold mb-4">Registerh1>
      <form onSubmit={handleSubmit} className="space-y-4">
        <div>
          <label className="block">Namelabel>
          <input
            name="name"
            type="text"
            className="w-full p-2 border rounded"
            value={formData.name}
            onChange={handleInputChange}
            required
          />
        div>
        <div>
          <label className="block">Emaillabel>
          <input
            name="email"
            type="email"
            className="w-full p-2 border rounded"
            value={formData.email}
            onChange={handleInputChange}
            required
          />
        div>
        <div>
          <label className="block">Passwordlabel>
          <input
            name="password"
            type="password"
            className="w-full p-2 border rounded"
            value={formData.password}
            onChange={handleInputChange}
            required
          />
        div>
        <button type="submit" className="bg-green-500 text-white p-2 rounded">
          Register
        button>
      form>
      <p className="mt-4">
        Already have an account?{' '}
        <a href="/user/login" className="text-blue-500">Login herea>.
      p>
    div>
  );
};

export default RegisterPage;
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

4. طرح بندی جهانی/app/layout.tsx

این طرح کلی شامل یک هدر و پاورقی که در تمام صفحات نمایش داده می شود.

// /app/layout.tsx
import React from 'react';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className="bg-gray-50 text-gray-900">
        <Header />
        <main className="min-h-screen">{children}main>
        <Footer />
      body>
    html>
  );
}

const Header: React.FC = () => (
  <header className="bg-blue-500 text-white p-4">
    <div className="container mx-auto">
      <a href="https://dev.to/" className="text-xl font-bold">Event Hosting Platforma>
      <nav className="mt-2">
        <a href="/user/profile" className="mr-4">Profilea>
        <a href="/user/login">Logina>
      nav>
    div>
  header>
);

const Footer: React.FC = () => (
  <footer className="bg-gray-800 text-white p-4 mt-8">
    <div className="container mx-auto text-center">
      <p>© 2024 Event Hosting Platform. All rights reserved.p>
    div>
  footer>
);
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

5. CSS جهانی/app/global.css

این فایل جایی است که شما وارد می کنید Tailwind CSS و هر سبک جهانی را اعمال کنید. از آن اطمینان حاصل کنید Tailwind CSS به درستی در پروژه شما پیکربندی شده است (tailwind.config.js).

/* /app/global.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

/* Additional custom styles if needed */
body {
  font-family: 'Inter', sans-serif;
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

6. جزء برنامه سفارشی/app/_app.tsx

در Next.js 14+، می توانید از برنامه کامپوننت برای مدیریت مواردی مانند حالت جهانی، ارائه دهندگان زمینه، و غیره. این اختیاری است که بسته به نیاز برنامه شماست.

// /app/_app.tsx
import React from 'react';

export default function MyApp({ Component, pageProps }: any) {
  return (
    <Component {...pageProps} />
  );
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نکات کلیدی:

  1. صفحه نمایه: اطلاعات کاربر را نمایش می دهد و دارای دکمه ای برای ویرایش نمایه است (آن را با فراخوانی API برای داده های واقعی گسترش دهید).
  2. صفحه ورود: فرم ورود ساده که کاربر را وارد کرده و او را تغییر مسیر می دهد.
  3. صفحه ثبت نام: فرم ثبت نام که اطلاعات کاربر را جمع آوری می کند و پس از ثبت نام موفقیت آمیز به صفحه ورود هدایت می شود.
  4. طرح بندی جهانی: حاوی سرصفحه و پاورقی است که در تمام صفحات به اشتراک گذاشته خواهد شد.
  5. Tailwind CSS:

در سطح جهانی با @tailwind base، @tailwind components، و @tailwind utilities.

این کد یک راه اندازی اولیه برای صفحات احراز هویت کاربر و اجزای اشتراک گذاری شده در شما فراهم می کند Next.js پروژه، و می توان آن را با احراز هویت واقعی و یکپارچه سازی API گسترش داد.

در اینجا اجرای کامل کامپوننت ها، قلاب ها، ابزارهای کمکی و سایر فایل های مرتبط برای شما آورده شده است Next.js پروژه همانطور که در ساختار پوشه شما مشخص شده است.

1. اجزای UI قابل استفاده مجدد

EventCard.tsx

// /components/EventCard.tsx
import React from 'react';

interface EventCardProps {
  name: string;
  description: string;
  date: string;
  price: number;
  imageUrl: string;
}

const EventCard: React.FC<EventCardProps> = ({ name, description, date, price, imageUrl }) => {
  return (
    <div className="max-w-sm rounded overflow-hidden shadow-lg">
      <img className="w-full h-48 object-cover" src={imageUrl} alt={name} />
      <div className="px-6 py-4">
        <h2 className="font-bold text-xl mb-2">{name}h2>
        <p className="text-gray-700 text-base">{description}p>
        <p className="text-gray-600 mt-2">Date: {date}p>
        <p className="text-gray-600">Price: ${price}p>
      div>
    div>
  );
};

export default EventCard;
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

Navbar.tsx

// /components/Navbar.tsx
import React from 'react';

const Navbar: React.FC = () => {
  return (
    <nav className="bg-blue-500 text-white p-4">
      <div className="container mx-auto flex justify-between items-center">
        <a href="https://dev.to/" className="text-xl font-bold">Event Hosting Platforma>
        <div>
          <a href="/user/profile" className="mr-4">Profilea>
          <a href="/user/login" className="mr-4">Logina>
        div>
      div>
    nav>
  );
};

export default Navbar;
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

Footer.tsx

// /components/Footer.tsx
import React from 'react';

const Footer: React.FC = () => {
  return (
    <footer className="bg-gray-800 text-white text-center p-4 mt-8">
      <div className="container mx-auto">
        <p>© 2024 Event Hosting Platform. All rights reserved.p>
      div>
    footer>
  );
};

export default Footer;
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

Button.tsx

// /components/Button.tsx
import React from 'react';

interface ButtonProps {
  label: string;
  onClick: () => void;
  className?: string;
}

const Button: React.FC<ButtonProps> = ({ label, onClick, className }) => {
  return (
    <button
      className={`bg-blue-500 text-white p-2 rounded ${className}`}
      onClick={onClick}
    >
      {label}
    button>
  );
};

export default Button;
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

Modal.tsx

// /components/Modal.tsx
import React from 'react';

interface ModalProps {
  isOpen: boolean;
  title: string;
  children: React.ReactNode;
  onClose: () => void;
}

const Modal: React.FC<ModalProps> = ({ isOpen, title, children, onClose }) => {
  if (!isOpen) return null;

  return (
    <div className="fixed inset-0 flex items-center justify-center z-50">
      <div className="bg-white p-4 rounded shadow-lg">
        <h2 className="text-xl font-bold mb-2">{title}h2>
        <div>{children}div>
        <button
          className="bg-red-500 text-white p-2 rounded mt-4"
          onClick={onClose}
        >
          Close
        button>
      div>
      <div className="fixed inset-0 bg-black opacity-50" onClick={onClose}>div>
    div>
  );
};

export default Modal;
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

Loader.tsx

// /components/Loader.tsx
import React from 'react';

const Loader: React.FC = () => {
  return (
    <div className="flex justify-center items-center">
      <div className="spinner-border animate-spin inline-block w-8 h-8 border-4 rounded-full border-t-transparent border-blue-500">div>
    div>
  );
};

export default Loader;
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


2. قلاب های سفارشی

useAuth.ts

// /hooks/useAuth.ts
import { useState, useEffect } from 'react';

export const useAuth = () => {
  const [isAuthenticated, setIsAuthenticated] = useState(false);

  useEffect(() => {
    // Example: check localStorage or make an API call to verify authentication
    const token = localStorage.getItem('token');
    setIsAuthenticated(!!token);
  }, []);

  const login = (token: string) => {
    localStorage.setItem('token', token);
    setIsAuthenticated(true);
  };

  const logout = () => {
    localStorage.removeItem('token');
    setIsAuthenticated(false);
  };

  return { isAuthenticated, login, logout };
};
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

useEvent.ts

// /hooks/useEvent.ts
import { useState, useEffect } from 'react';
import { Event } from '../types/event';
import { fetchEvents } from '../lib/api';

export const useEvent = () => {
  const [events, setEvents] = useState<Event[]>([]);
  const [loading, setLoading] = useState<boolean>(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    const loadEvents = async () => {
      try {
        const data = await fetchEvents();
        setEvents(data);
      } catch (err) {
        setError('Failed to load events');
      } finally {
        setLoading(false);
      }
    };

    loadEvents();
  }, []);

  return { events, loading, error };
};
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

useStream.ts

// /hooks/useStream.ts
import { useState } from 'react';

export const useStream = () => {
  const [isStreaming, setIsStreaming] = useState(false);

  const startStream = () => {
    setIsStreaming(true);
    // Trigger actual live stream logic here
  };

  const stopStream = () => {
    setIsStreaming(false);
    // Stop live stream logic here
  };

  return { isStreaming, startStream, stopStream };
};
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


3. ابزارهای کمکی و توابع کمکی

api.ts

// /lib/api.ts
import { Event } from '../types/event';

const API_URL = 'https://api.example.com';

export const fetchEvents = async (): Promise<Event[]> => {
  const response = await fetch(`${API_URL}/events`);
  if (!response.ok) {
    throw new Error('Failed to fetch events');
  }
  return response.json();
};

export const loginUser = async (email: string, password: string): Promise<string> => {
  const response = await fetch(`${API_URL}/login`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ email, password }),
  });

  if (!response.ok) {
    throw new Error('Failed to log in');
  }

  const { token } = await response.json();
  return token;
};
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

validators.ts

// /lib/validators.ts
export const validateEmail = (email: string): boolean => {
  const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return regex.test(email);
};

export const validatePassword = (password: string): boolean => {
  // Example validation: password must be at least 6 characters
  return password.length >= 6;
};
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


4. دارایی های ایستا

  • /عمومی/تصاویر: تصاویر ثابت خود را مانند بنرهای رویداد یا آرم اضافه کنید.
  • favicon.ico: فاویکون خود را اینجا قرار دهید.
  • logo.png: لوگوی برنامه خود را در اینجا اضافه کنید.

ساختار نمونه:

/public
├── /images
│   ├── event1.jpg
│   ├── event2.jpg
│   └── logo.png
├── favicon.ico
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


5. سبک ها

tailwind.config.js

مطمئن شوید Tailwind CSS به درستی تنظیم شده است. در اینجا فایل پیکربندی برای فعال کردن Tailwind در پروژه شما است.

// /styles/tailwind.config.js
module.exports = {
  content: ['./app/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
  theme: {
    extend: {},
  },
  plugins: [],
};
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

globals.css

این یک فایل اختیاری برای هر CSS جهانی اضافی است. Tailwind CSS اکثر نیازهای یک ظاهر طراحی را پوشش خواهد داد.

/* /styles/globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

/* Additional global styles can go here */
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


6. انواع TypeScript

رویداد.ts

// /types/event.ts
export interface Event {
  id: string;
  name: string;
  description: string;
  date: string;
  price: number;
  imageUrl: string;
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

user.ts

// /types/user.ts
export interface User {


  id: string;
  name: string;
  email: string;
  joined: string;
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


خلاصه:

این ساختار یک به خوبی سازماندهی شده است و مقیاس پذیر معماری برای ساختن شما Next.js برنامه با اجزای قابل استفاده مجدد، قلاب های سفارشی، و توابع ابزار مدولار.

  • را اجزاء مانند EventCard، Navbar، و Button قابل استفاده مجدد در سراسر برنامه شما هستند.
  • قلاب های سفارشی مانند useAuth، useEvent، و useStream منطق را کپسوله کنید و تعامل با وضعیت برنامه و APIها را ساده کنید.
  • توابع سودمند رسیدگی به درخواست‌ها و اعتبارسنجی‌های API

در اینجا اجرای کامل برای احراز هویت و کاربر ماژول ها در a NestJS برنامه با استفاده از TypeORM و احراز هویت مبتنی بر JWT.

نمای کلی ساختار پوشه

/src
├── /auth
│   ├── auth.controller.ts
│   ├── auth.module.ts
│   ├── auth.service.ts
│   ├── jwt.strategy.ts
│   ├── local.strategy.ts
│   ├── dto
│   │   ├── login.dto.ts
│   │   ├── register.dto.ts
│   ├── guards
│   │   ├── jwt-auth.guard.ts
│   │   ├── roles.guard.ts
│   ├── decorators
│       ├── roles.decorator.ts
├── /users
│   ├── users.controller.ts
│   ├── users.module.ts
│   ├── users.service.ts
│   ├── entities
│   │   ├── user.entity.ts
│   ├── dto
│       ├── create-user.dto.ts
│       ├── update-user.dto.ts
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


1. ماژول احراز هویت

auth.controller.ts

ورود و ثبت نام کاربر را کنترل می کند.

// /src/auth/auth.controller.ts
import { Controller, Post, Body, UseGuards, Request } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LoginDto } from './dto/login.dto';
import { RegisterDto } from './dto/register.dto';
import { LocalAuthGuard } from './guards/local-auth.guard';
import { JwtAuthGuard } from './guards/jwt-auth.guard';

@Controller('auth')
export class AuthController {
  constructor(private readonly authService: AuthService) {}

  @Post('login')
  @UseGuards(LocalAuthGuard)
  async login(@Request() req, @Body() loginDto: LoginDto) {
    return this.authService.login(req.user);
  }

  @Post('register')
  async register(@Body() registerDto: RegisterDto) {
    return this.authService.register(registerDto);
  }

  @UseGuards(JwtAuthGuard)
  @Post('profile')
  getProfile(@Request() req) {
    return req.user;
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

auth.module.ts

وابستگی ها و واردات مورد نیاز برای ماژول احراز هویت را تعریف می کند.

// /src/auth/auth.module.ts
import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UsersModule } from '../users/users.module';
import { JwtStrategy } from './jwt.strategy';
import { LocalStrategy } from './local.strategy';
import { JwtAuthGuard } from './guards/jwt-auth.guard';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: 'jwt_secret',  // Use environment variable for production
      signOptions: { expiresIn: '1d' },
    }),
  ],
  controllers: [AuthController],
  providers: [AuthService, LocalStrategy, JwtStrategy, JwtAuthGuard],
})
export class AuthModule {}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

auth.service.ts

منطق ثبت نام کاربران، اعتبارسنجی اعتبارنامه ها و تولید توکن های JWT را مدیریت می کند.

// /src/auth/auth.service.ts
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { UsersService } from '../users/users.service';
import { RegisterDto } from './dto/register.dto';
import { User } from '../users/entities/user.entity';

@Injectable()
export class AuthService {
  constructor(
    private usersService: UsersService,
    private jwtService: JwtService,
  ) {}

  async validateUser(email: string, pass: string): Promise<any> {
    const user = await this.usersService.findByEmail(email);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }

  async login(user: any) {
    const payload = { email: user.email, sub: user.id };
    return {
      access_token: this.jwtService.sign(payload),
    };
  }

  async register(registerDto: RegisterDto): Promise<User> {
    return this.usersService.create(registerDto);
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

jwt.strategy.ts

تأیید رمز JWT را کنترل می کند.

// /src/auth/jwt.strategy.ts
import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: 'jwt_secret', // Use environment variable for production
    });
  }

  async validate(payload: any) {
    return { userId: payload.sub, email: payload.email };
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

local.strategy.ts

تأیید نام کاربری/رمز عبور را کنترل می کند.

// /src/auth/local.strategy.ts
import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service';

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private authService: AuthService) {
    super({ usernameField: 'email' });
  }

  async validate(email: string, password: string): Promise<any> {
    const user = await this.authService.validateUser(email, password);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

login.dto.ts

شی انتقال داده برای درخواست های ورود به سیستم.

// /src/auth/dto/login.dto.ts
import { IsEmail, IsNotEmpty, MinLength } from 'class-validator';

export class LoginDto {
  @IsEmail()
  email: string;

  @IsNotEmpty()
  @MinLength(6)
  password: string;
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

register.dto.ts

شی انتقال داده برای درخواست های ثبت نام.

// /src/auth/dto/register.dto.ts
import { IsEmail, IsNotEmpty, MinLength } from 'class-validator';

export class RegisterDto {
  @IsNotEmpty()
  name: string;

  @IsEmail()
  email: string;

  @IsNotEmpty()
  @MinLength(6)
  password: string;
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

jwt-auth.guard.ts

محافظ برای محافظت از مسیرها با احراز هویت JWT.

// /src/auth/guards/jwt-auth.guard.ts
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نقش ها.نگهبان.تس

محافظ برای کنترل دسترسی مبتنی بر نقش.

// /src/auth/guards/roles.guard.ts
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const roles = this.reflector.get<string[]>('roles', context.getHandler());
    if (!roles) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    return roles.includes(user.role);
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نقش ها.دکوراتور.تس

دکوراتور سفارشی برای تعیین نقش به مسیرها.

// /src/auth/decorators/roles.decorator.ts
import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


2. ماژول کاربر

users.controller.ts

درخواست های مربوط به کاربر را رسیدگی می کند.

// /src/users/users.controller.ts
import { Controller, Get, Post, Body, Param, Patch } from '@nestjs/common';
import { UsersService } from './users.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Post()
  create(@Body() createUserDto: CreateUserDto) {
    return this.usersService.create(createUserDto);
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.usersService.findOne(id);
  }

  @Patch(':id')
  update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {
    return this.usersService.update(id, updateUserDto);
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

users.module.ts

ماژول ها و خدمات لازم را برای ماژول کاربر وارد می کند.

// /src/users/users.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
import { User } from './entities/user.entity';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  controllers: [UsersController],
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

users.service.ts

منطق مدیریت داده های کاربر را مدیریت می کند.

// /src/users/users.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from

 '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { User } from './entities/user.entity';

@Injectable()
export class UsersService {
  constructor(
    @InjectRepository(User)
    private usersRepository: Repository<User>,
  ) {}

  async create(createUserDto: CreateUserDto): Promise<User> {
    const user = this.usersRepository.create(createUserDto);
    return this.usersRepository.save(user);
  }

  async findOne(id: string): Promise<User> {
    return this.usersRepository.findOneBy({ id });
  }

  async findByEmail(email: string): Promise<User> {
    return this.usersRepository.findOneBy({ email });
  }

  async update(id: string, updateUserDto: UpdateUserDto): Promise<User> {
    await this.usersRepository.update(id, updateUserDto);
    return this.findOne(id);
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

user.entity.ts

طرح کاربر را برای TypeORM تعریف می کند.

// /src/users/entities/user.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class User {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  name: string;

  @Column({ unique: true })
  email: string;

  @Column()
  password: string;

  @Column({ default: 'user' })
  role: string;
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

create-user.dto.ts

شی انتقال داده برای ایجاد کاربر.

// /src/users/dto/create-user.dto.ts
import { IsEmail, IsNotEmpty, MinLength } from 'class-validator';

export class CreateUserDto {
  @IsNotEmpty()
  name: string;

  @IsEmail()
  email: string;

  @IsNotEmpty()
  @MinLength(6)
  password: string;
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

update-user.dto.ts

شی انتقال داده برای به روز رسانی یک کاربر.

// /src/users/dto/update-user.dto.ts
import { IsOptional, MinLength } from 'class-validator';

export class UpdateUserDto {
  @IsOptional()
  name?: string;

  @IsOptional()
  @MinLength(6)
  password?: string;
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


خلاصه

این راه اندازی فراهم می کند احراز هویت مدولار و سیستم مدیریت کاربر در NestJS. شامل:

  • ماژول احراز هویت: ورود و ثبت نام کاربر را با احراز هویت JWT و محافظ های مبتنی بر نقش کنترل می کند.
  • ماژول کاربر: داده های کاربر را با استفاده از TypeORM با عملیات CRUD مدیریت می کند.
  • DTOها و نگهبانان: از ایمنی نوع و تأیید اعتبار درخواست اطمینان حاصل کنید، در حالی که از مسیرها با توکن های JWT محافظت می کنید.

شما می توانید این کد را برای ادغام با پایگاه داده PostgreSQL خود با استفاده از آن گسترش دهید TypeORMو راز JWT را می توان به طور ایمن در متغیرهای محیطی برای استفاده در تولید ذخیره کرد.

در اینجا اجرای کامل کد برای رویداد و تهیه بلیط ماژول ها در a NestJS استفاده از باطن TypeORM برای مدیریت داده های رویداد و بلیط.

نمای کلی ساختار پوشه

/src
├── /events               # Event module
│   ├── events.controller.ts
│   ├── events.module.ts
│   ├── events.service.ts
│   ├── entities
│   │   ├── event.entity.ts
│   ├── dto
│       ├── create-event.dto.ts
│       ├── update-event.dto.ts
├── /tickets              # Ticket module
│   ├── tickets.controller.ts
│   ├── tickets.module.ts
│   ├── tickets.service.ts
│   ├── entities
│   │   ├── ticket.entity.ts
│   ├── dto
│       ├── create-ticket.dto.ts
│       ├── update-ticket.dto.ts
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


1. ماژول رویداد

events.controller.ts

درخواست‌های HTTP مربوط به رویدادها (مانند ایجاد، به‌روزرسانی، فهرست کردن رویدادها) را مدیریت می‌کند.

// /src/events/events.controller.ts
import { Controller, Get, Post, Body, Param, Patch, Delete } from '@nestjs/common';
import { EventsService } from './events.service';
import { CreateEventDto } from './dto/create-event.dto';
import { UpdateEventDto } from './dto/update-event.dto';

@Controller('events')
export class EventsController {
  constructor(private readonly eventsService: EventsService) {}

  @Post()
  create(@Body() createEventDto: CreateEventDto) {
    return this.eventsService.create(createEventDto);
  }

  @Get()
  findAll() {
    return this.eventsService.findAll();
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.eventsService.findOne(id);
  }

  @Patch(':id')
  update(@Param('id') id: string, @Body() updateEventDto: UpdateEventDto) {
    return this.eventsService.update(id, updateEventDto);
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return this.eventsService.remove(id);
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

event.module.ts

ماژول Event را تعریف می کند که خدمات و کنترلرهای لازم را وارد می کند.

// /src/events/events.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { EventsService } from './events.service';
import { EventsController } from './events.controller';
import { Event } from './entities/event.entity';

@Module({
  imports: [TypeOrmModule.forFeature([Event])],
  controllers: [EventsController],
  providers: [EventsService],
})
export class EventsModule {}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

events.service.ts

شامل منطق تجاری برای مدیریت رویدادها، مانند ایجاد، به روز رسانی، و یافتن رویدادها است.

// /src/events/events.service.ts
import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { CreateEventDto } from './dto/create-event.dto';
import { UpdateEventDto } from './dto/update-event.dto';
import { Event } from './entities/event.entity';

@Injectable()
export class EventsService {
  constructor(
    @InjectRepository(Event)
    private eventsRepository: Repository<Event>,
  ) {}

  create(createEventDto: CreateEventDto): Promise<Event> {
    const event = this.eventsRepository.create(createEventDto);
    return this.eventsRepository.save(event);
  }

  findAll(): Promise<Event[]> {
    return this.eventsRepository.find();
  }

  async findOne(id: string): Promise<Event> {
    const event = await this.eventsRepository.findOneBy({ id });
    if (!event) {
      throw new NotFoundException(`Event with ID ${id} not found`);
    }
    return event;
  }

  async update(id: string, updateEventDto: UpdateEventDto): Promise<Event> {
    await this.eventsRepository.update(id, updateEventDto);
    return this.findOne(id);
  }

  async remove(id: string): Promise<void> {
    await this.findOne(id); // Ensure event exists
    await this.eventsRepository.delete(id);
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

event.entity.ts

طرح واره پایگاه داده را برای رویدادها با استفاده تعریف می کند TypeORM.

// /src/events/entities/event.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Event {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  name: string;

  @Column()
  description: string;

  @Column()
  date: string;

  @Column('decimal')
  price: number;

  @Column({ nullable: true })
  imageUrl: string;
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

create-event.dto.ts

شی انتقال داده برای ایجاد یک رویداد جدید.

// /src/events/dto/create-event.dto.ts
import { IsNotEmpty, IsString, IsDecimal, IsOptional } from 'class-validator';

export class CreateEventDto {
  @IsNotEmpty()
  @IsString()
  name: string;

  @IsNotEmpty()
  @IsString()
  description: string;

  @IsNotEmpty()
  date: string;

  @IsNotEmpty()
  @IsDecimal()
  price: number;

  @IsOptional()
  @IsString()
  imageUrl?: string;
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

update-event.dto.ts

شی انتقال داده برای به روز رسانی یک رویداد.

// /src/events/dto/update-event.dto.ts
import { PartialType } from '@nestjs/mapped-types';
import { CreateEventDto } from './create-event.dto';

export class UpdateEventDto extends PartialType(CreateEventDto) {}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


2. ماژول تهیه بلیط

بلیط.controller.ts

درخواست های HTTP مربوط به بلیط ها (به عنوان مثال، ایجاد، به روز رسانی، لیست بلیط ها) را مدیریت می کند.

// /src/tickets/tickets.controller.ts
import { Controller, Get, Post, Body, Param, Patch, Delete } from '@nestjs/common';
import { TicketsService } from './tickets.service';
import { CreateTicketDto } from './dto/create-ticket.dto';
import { UpdateTicketDto } from './dto/update-ticket.dto';

@Controller('tickets')
export class TicketsController {
  constructor(private readonly ticketsService: TicketsService) {}

  @Post()
  create(@Body() createTicketDto: CreateTicketDto) {
    return this.ticketsService.create(createTicketDto);
  }

  @Get()
  findAll() {
    return this.ticketsService.findAll();
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.ticketsService.findOne(id);
  }

  @Patch(':id')
  update(@Param('id') id: string, @Body() updateTicketDto: UpdateTicketDto) {
    return this.ticketsService.update(id, updateTicketDto);
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return this.ticketsService.remove(id);
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

بلیط.module.ts

ماژول Ticket را تعریف می کند که خدمات و کنترلرهای لازم را وارد می کند.

// /src/tickets/tickets.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { TicketsService } from './tickets.service';
import { TicketsController } from './tickets.controller';
import { Ticket } from './entities/ticket.entity';

@Module({
  imports: [TypeOrmModule.forFeature([Ticket])],
  controllers: [TicketsController],
  providers: [TicketsService],
})
export class TicketsModule {}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

بلیط.سرویس.تس

شامل منطق تجاری برای مدیریت بلیط ها، مانند ایجاد، به روز رسانی، و یافتن بلیط.

// /src/tickets/tickets.service.ts
import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { CreateTicketDto } from './dto/create-ticket.dto';
import { UpdateTicketDto } from './dto/update-ticket.dto';
import { Ticket } from './entities/ticket.entity';

@Injectable()
export class TicketsService {
  constructor(
    @InjectRepository(Ticket)
    private ticketsRepository: Repository<Ticket>,
  ) {}

  create(createTicketDto: CreateTicketDto): Promise<Ticket> {
    const ticket = this.ticketsRepository.create(createTicketDto);
    return this.ticketsRepository.save(ticket);
  }

  findAll(): Promise<Ticket[]> {
    return this.ticketsRepository.find();
  }

  async findOne(id: string): Promise<Ticket> {
    const ticket = await this.ticketsRepository.findOneBy({ id });
    if (!ticket) {
      throw new NotFoundException(`Ticket with ID ${id} not found`);
    }
    return ticket;
  }

  async update(id: string, updateTicketDto: UpdateTicketDto): Promise<Ticket> {
    await this.ticketsRepository.update(id, updateTicketDto);
    return this.findOne(id);
  }

  async remove(id: string): Promise<void> {
    await this.findOne(id); // Ensure ticket exists
    await this.ticketsRepository.delete(id);
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ticket.entity.ts

طرح پایگاه داده را برای استفاده از بلیط ها تعریف می کند TypeORM.

// /src/tickets/entities/ticket.entity.ts
import { Entity, Column, PrimaryGeneratedColumn, ManyToOne } from 'typeorm';
import { Event } from '../../events/entities/event.entity';

@Entity()
export class Ticket {
  @PrimaryGeneratedColumn('uuid')
  id: string

;

  @Column()
  seatNumber: string;

  @Column('decimal')
  price: number;

  @ManyToOne(() => Event, (event) => event.id)
  event: Event;
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

create-ticket.dto.ts

شی انتقال داده برای ایجاد یک بلیط جدید.

// /src/tickets/dto/create-ticket.dto.ts
import { IsNotEmpty, IsDecimal, IsString } from 'class-validator';

export class CreateTicketDto {
  @IsNotEmpty()
  @IsString()
  seatNumber: string;

  @IsNotEmpty()
  @IsDecimal()
  price: number;

  @IsNotEmpty()
  @IsString()
  eventId: string;
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

update-ticket.dto.ts

شیء انتقال داده برای به روز رسانی بلیط.

// /src/tickets/dto/update-ticket.dto.ts
import { PartialType } from '@nestjs/mapped-types';
import { CreateTicketDto } from './create-ticket.dto';

export class UpdateTicketDto extends PartialType(CreateTicketDto) {}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


خلاصه

این تنظیمات دو ماژول را ارائه می دهد:

  1. ماژول رویداد:

    • ایجاد، به‌روزرسانی و بازیابی رویدادها را مدیریت می‌کند.
    • استفاده می کند TypeORM برای تعامل با PostgreSQL پایگاه داده
    • اجرا می کند DTO ها برای اعتبار سنجی
  2. ماژول تهیه بلیط:

    • ایجاد بلیط و مدیریت مربوط به رویدادها را انجام می دهد.
    • استفاده می کند TypeORM برای طرح پایگاه داده بلیط.
    • هر بلیط با یک رویداد مرتبط است.

هر دو ماژول به گونه‌ای طراحی شده‌اند که توسعه‌پذیر و مقیاس‌پذیر باشند و ویژگی‌های بیشتری مانند خرید بلیط، مدیریت در دسترس بودن، و درخواست‌های پیچیده‌تر در رویدادها و بلیط‌ها را امکان‌پذیر می‌سازند.

در اینجا اجرای کامل کد برای پرداخت و اطلاع رسانی ماژول ها در a NestJS استفاده از باطن TypeORM برای مدیریت تراکنش‌های پرداخت و ارسال اعلان‌ها از طریق ایمیل، پیامک یا اعلان‌های فشاری.

نمای کلی ساختار پوشه

/src
├── /payments             # Payment module
│   ├── payments.controller.ts
│   ├── payments.module.ts
│   ├── payments.service.ts
│   ├── entities
│   │   ├── payment.entity.ts
│   ├── dto
│       ├── create-payment.dto.ts
├── /notifications        # Notification module
│   ├── notifications.controller.ts
│   ├── notifications.module.ts
│   ├── notifications.service.ts
│   ├── dto
│       ├── create-notification.dto.ts
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


1. ماژول پرداخت

payments.controller.ts

درخواست‌های HTTP مربوط به پرداخت‌ها (به عنوان مثال، پردازش پرداخت، واکشی جزئیات پرداخت) را مدیریت می‌کند.

// /src/payments/payments.controller.ts
import { Controller, Get, Post, Body, Param } from '@nestjs/common';
import { PaymentsService } from './payments.service';
import { CreatePaymentDto } from './dto/create-payment.dto';

@Controller('payments')
export class PaymentsController {
  constructor(private readonly paymentsService: PaymentsService) {}

  @Post()
  processPayment(@Body() createPaymentDto: CreatePaymentDto) {
    return this.paymentsService.processPayment(createPaymentDto);
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.paymentsService.findOne(id);
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

pays.module.ts

ماژول Payment را تعریف می کند که خدمات و کنترلرهای لازم را وارد می کند.

// /src/payments/payments.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { PaymentsService } from './payments.service';
import { PaymentsController } from './payments.controller';
import { Payment } from './entities/payment.entity';

@Module({
  imports: [TypeOrmModule.forFeature([Payment])],
  controllers: [PaymentsController],
  providers: [PaymentsService],
})
export class PaymentsModule {}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

pays.service.ts

حاوی منطق تجاری برای مدیریت پرداخت‌ها، مانند پردازش و بازیابی پرداخت‌ها.

// /src/payments/payments.service.ts
import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { CreatePaymentDto } from './dto/create-payment.dto';
import { Payment } from './entities/payment.entity';

@Injectable()
export class PaymentsService {
  constructor(
    @InjectRepository(Payment)
    private paymentsRepository: Repository<Payment>,
  ) {}

  async processPayment(createPaymentDto: CreatePaymentDto): Promise<Payment> {
    // Placeholder logic for payment processing (integrate with a real payment provider like Stripe or PayPal)
    const payment = this.paymentsRepository.create(createPaymentDto);
    return this.paymentsRepository.save(payment);
  }

  async findOne(id: string): Promise<Payment> {
    const payment = await this.paymentsRepository.findOneBy({ id });
    if (!payment) {
      throw new NotFoundException(`Payment with ID ${id} not found`);
    }
    return payment;
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

Payment.entity.ts

طرح پایگاه داده را برای پرداخت ها با استفاده از تعریف می کند TypeORM.

// /src/payments/entities/payment.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Payment {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  userId: string;

  @Column()
  eventId: string;

  @Column('decimal')
  amount: number;

  @Column()
  paymentMethod: string; // e.g., 'credit card', 'paypal'

  @Column()
  status: string; // e.g., 'pending', 'completed', 'failed'

  @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
  createdAt: Date;
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

create-payment.dto.ts

شی انتقال داده برای ایجاد یک پرداخت جدید.

// /src/payments/dto/create-payment.dto.ts
import { IsNotEmpty, IsDecimal } from 'class-validator';

export class CreatePaymentDto {
  @IsNotEmpty()
  userId: string;

  @IsNotEmpty()
  eventId: string;

  @IsNotEmpty()
  @IsDecimal()
  amount: number;

  @IsNotEmpty()
  paymentMethod: string; // e.g., 'credit card', 'paypal'
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


2. ماژول اطلاع رسانی

notifications.controller.ts

درخواست‌های HTTP مربوط به اعلان‌ها (به عنوان مثال، ارسال ایمیل یا پیامک اعلان) را مدیریت می‌کند.

// /src/notifications/notifications.controller.ts
import { Controller, Post, Body } from '@nestjs/common';
import { NotificationsService } from './notifications.service';
import { CreateNotificationDto } from './dto/create-notification.dto';

@Controller('notifications')
export class NotificationsController {
  constructor(private readonly notificationsService: NotificationsService) {}

  @Post()
  sendNotification(@Body() createNotificationDto: CreateNotificationDto) {
    return this.notificationsService.sendNotification(createNotificationDto);
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

notifications.module.ts

ماژول Notification را تعریف می کند که خدمات و کنترلرهای لازم را وارد می کند.

// /src/notifications/notifications.module.ts
import { Module } from '@nestjs/common';
import { NotificationsService } from './notifications.service';
import { NotificationsController } from './notifications.controller';

@Module({
  controllers: [NotificationsController],
  providers: [NotificationsService],
})
export class NotificationsModule {}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

notifications.service.ts

حاوی منطق تجاری برای ارسال اعلان‌هایی مانند ایمیل، پیامک یا اعلان‌های فشاری است.

// /src/notifications/notifications.service.ts
import { Injectable } from '@nestjs/common';
import { CreateNotificationDto } from './dto/create-notification.dto';
import * as nodemailer from 'nodemailer'; // For email notifications (use an actual provider for SMS)

@Injectable()
export class NotificationsService {
  async sendNotification(createNotificationDto: CreateNotificationDto): Promise<any> {
    const { recipient, message, type } = createNotificationDto;

    if (type === 'email') {
      return this.sendEmail(recipient, message);
    }

    if (type === 'sms') {
      return this.sendSms(recipient, message);
    }

    if (type === 'push') {
      return this.sendPushNotification(recipient, message);
    }
  }

  private async sendEmail(recipient: string, message: string) {
    const transporter = nodemailer.createTransport({
      service: 'Gmail', // Use your actual email service provider here
      auth: {
        user: 'your-email@gmail.com',
        pass: 'your-email-password',
      },
    });

    const mailOptions = {
      from: 'your-email@gmail.com',
      to: recipient,
      subject: 'Notification',
      text: message,
    };

    return transporter.sendMail(mailOptions);
  }

  private async sendSms(recipient: string, message: string) {
    // Implement SMS sending logic (e.g., using Twilio)
    console.log(`Sending SMS to ${recipient}: ${message}`);
    return { success: true };
  }

  private async sendPushNotification(recipient: string, message: string) {
    // Implement push notification logic (e.g., using Firebase Cloud Messaging)
    console.log(`Sending push notification to ${recipient}: ${message}`);
    return { success: true };
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

create-notification.dto.ts

شی انتقال داده برای ایجاد درخواست اعلان.

// /src/notifications/dto/create-notification.dto.ts
import { IsNotEmpty, IsEmail, IsIn } from 'class-validator';

export class CreateNotificationDto {
  @IsNotEmpty()
  @IsEmail()
  recipient: string; // Can be email or phone number depending on the type

  @IsNotEmpty()
  message: string;

  @IsNotEmpty()
  @IsIn(['email', 'sms', 'push'])
  type: string; // e.g., 'email', 'sms', 'push'
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


خلاصه

این تنظیمات دو ماژول را ارائه می دهد:

  1. ماژول پرداخت:

    • ایجاد و بازیابی پرداخت ها را مدیریت می کند.
    • استفاده می کند TypeORM برای تعامل با PostgreSQL پایگاه داده
    • اجرا می کند DTO ها برای اعتبارسنجی داده های پرداخت دریافتی
  2. ماژول اطلاع رسانی:

    • ارسال ایمیل، پیامک و اعلان‌های فشاری را کنترل می‌کند.
    • استفاده می کند nodemailer برای اعلان‌های ایمیل (می‌توانید آن را گسترش دهید تا از Twilio برای SMS یا Firebase برای اعلان‌های فشاری استفاده کنید).
    • اجرا می کند DTO ها برای تایید درخواست های اطلاع رسانی

شما می توانید این راه حل را با ادغام با درگاه های پرداخت (به عنوان مثال، Stripe، PayPal) و خدمات اعلان (به عنوان مثال، Twilio برای SMS، Firebase برای اعلان های فشار) گسترش دهید.

در اینجا اجرای کامل آن است ماژول پایگاه داده و خدمات عمومی مانند فیلترهای استثنایی، رهگیرها، دکوراتورها و لوله ها در الف NestJS کاربرد.

نمای کلی ساختار پوشه

/src
├── /database               # Database module
│   ├── database.module.ts
│   ├── database.service.ts
│   ├── ormconfig.ts         # TypeORM configuration
├── /common                 # Shared utilities, guards, interceptors, and exceptions
│   ├── /filters            # Global exception filters
│   │   ├── all-exceptions.filter.ts
│   ├── /interceptors       # Interceptors for response transformation, logging, etc.
│   │   ├── transform.interceptor.ts
│   ├── /decorators         # Reusable decorators
│   │   ├── api-response.decorator.ts
│   ├── /pipes              # Global pipes for validation, etc.
│   │   ├── validation.pipe.ts
├── app.module.ts           # Root application module
├── main.ts                 # Main entry point of the application
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


1. ماژول پایگاه داده

database.module.ts

این ماژول پیکربندی می کند TypeORM برای اتصال به پایگاه داده جزئیات اتصال از وارد شده است ormconfig.ts فایل

// /src/database/database.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { DatabaseService } from './database.service';
import ormconfig from './ormconfig';

@Module({
  imports: [TypeOrmModule.forRoot(ormconfig)],
  providers: [DatabaseService],
  exports: [DatabaseService],
})
export class DatabaseModule {}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

database.service.ts

در صورت نیاز می توان از این سرویس برای انجام عملیات پایگاه داده خام استفاده کرد. به طور معمول، برای اکثر موارد، شما از مخازن TypeORM استفاده خواهید کرد.

// /src/database/database.service.ts
import { Injectable } from '@nestjs/common';
import { DataSource } from 'typeorm';

@Injectable()
export class DatabaseService {
  constructor(private readonly dataSource: DataSource) {}

  async runRawQuery(query: string): Promise<any> {
    return this.dataSource.query(query);
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ormconfig.ts

را TypeORM فایل پیکربندی، که در آن جزئیات و موجودیت های اتصال پایگاه داده خود را تعریف می کنید.

// /src/database/ormconfig.ts
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
import { User } from '../users/entities/user.entity';
import { Event } from '../events/entities/event.entity';
import { Ticket } from '../tickets/entities/ticket.entity';
import { Payment } from '../payments/entities/payment.entity';

const ormconfig: TypeOrmModuleOptions = {
  type: 'postgres',
  host: process.env.DB_HOST || 'localhost',
  port: Number(process.env.DB_PORT) || 5432,
  username: process.env.DB_USERNAME || 'postgres',
  password: process.env.DB_PASSWORD || 'postgres',
  database: process.env.DB_NAME || 'event_platform',
  entities: [User, Event, Ticket, Payment],
  synchronize: true, // Set to false in production
};

export default ormconfig;
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


2. ماژول مشترک

فیلترهای استثنایی

all-exceptions.filter.ts

یک فیلتر استثنای جهانی برای گرفتن و رسیدگی به همه استثناها به روشی یکسان.

// /src/common/filters/all-exceptions.filter.ts
import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpException,
  HttpStatus,
} from '@nestjs/common';
import { Request, Response } from 'express';

@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();

    const status =
      exception instanceof HttpException
        ? exception.getStatus()
        : HttpStatus.INTERNAL_SERVER_ERROR;

    const message =
      exception instanceof HttpException
        ? exception.getResponse()
        : 'Internal server error';

    response.status(status).json({
      statusCode: status,
      timestamp: new Date().toISOString(),
      path: request.url,
      message,
    });
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


رهگیرها

transform.interceptor.ts

این رهگیر به طور خودکار پاسخ ها را قبل از ارسال به مشتری تغییر می دهد و استاندارد کردن پاسخ های API را آسان تر می کند.

// /src/common/interceptors/transform.interceptor.ts
import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  CallHandler,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable()
export class TransformInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      map((data) => ({
        success: true,
        data,
      })),
    );
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


دکوراتورها

api-response.decorator.ts

این دکوراتور قابل استفاده مجدد را می توان برای حاشیه نویسی پاسخ های API با ساختاری ثابت استفاده کرد.

// /src/common/decorators/api-response.decorator.ts
import { applyDecorators } from '@nestjs/common';
import { ApiResponse, ApiOperation } from '@nestjs/swagger';

export const ApiStandardResponse = (description: string) => {
  return applyDecorators(
    ApiOperation({ description }),
    ApiResponse({
      status: 200,
      description: 'Request was successful',
    }),
    ApiResponse({
      status: 400,
      description: 'Bad Request',
    }),
    ApiResponse({
      status: 500,
      description: 'Internal Server Error',
    }),
  );
};
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


لوله ها

validation.pipe.ts

یک لوله اعتبارسنجی جهانی که درخواست های دریافتی را در برابر DTO ها با استفاده از اعتبارسنجی می کند اعتبار سنجی کلاس.

// /src/common/pipes/validation.pipe.ts
import {
  ArgumentMetadata,
  BadRequestException,
  Injectable,
  PipeTransform,
} from '@nestjs/common';
import { plainToInstance } from 'class-transformer';
import { validate } from 'class-validator';

@Injectable()
export class ValidationPipe implements PipeTransform {
  async transform(value: any, { metatype }: ArgumentMetadata) {
    if (!metatype || !this.toValidate(metatype)) {
      return value;
    }

    const object = plainToInstance(metatype, value);
    const errors = await validate(object);
    if (errors.length > 0) {
      throw new BadRequestException('Validation failed');
    }
    return value;
  }

  private toValidate(metatype: Function): boolean {
    const types: Function[] = [String, Boolean, Number, Array, Object];
    return !types.includes(metatype);
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


3. ماژول برنامه و نقطه ورودی اصلی

app.module.ts

ماژول ریشه برنامه شما که همه ماژول های ویژگی را وارد می کند، از جمله ماژول پایگاه داده و CommonModule.

// /src/app.module.ts
import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { EventsModule } from './events/events.module';
import { TicketsModule } from './tickets/tickets.module';
import { PaymentsModule } from './payments/payments.module';
import { NotificationsModule } from './notifications/notifications.module';
import { APP_FILTER, APP_INTERCEPTOR, APP_PIPE } from '@nestjs/core';
import { AllExceptionsFilter } from './common/filters/all-exceptions.filter';
import { TransformInterceptor } from './common/interceptors/transform.interceptor';
import { ValidationPipe } from './common/pipes/validation.pipe';

@Module({
  imports: [
    DatabaseModule,
    EventsModule,
    TicketsModule,
    PaymentsModule,
    NotificationsModule,
  ],
  providers: [
    {
      provide: APP_FILTER,
      useClass: AllExceptionsFilter,
    },
    {
      provide: APP_INTERCEPTOR,
      useClass: TransformInterceptor,
    },
    {
      provide: APP_PIPE,
      useClass: ValidationPipe,
    },
  ],
})
export class AppModule {}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

main.ts

نقطه ورود اصلی برنامه این فایل فیلترهای سراسری، لوله‌ها را پیکربندی می‌کند و آن را راه‌اندازی می‌کند NestJS سرور

// /src/main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from './common/pipes/validation.pipe';
import { AllExceptionsFilter } from './common/filters/all-exceptions.filter';
import { TransformInterceptor } from './common/interceptors/transform.interceptor';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // Apply global validation pipe
  app.useGlobalPipes(new ValidationPipe());

  // Apply global exception filter
  app.useGlobalFilters(new AllExceptionsFilter());

  // Apply global transform interceptor
  app.useGlobalInterceptors(new TransformInterceptor());

  await app.listen(3000);
}
bootstrap();
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید


خلاصه

این ساختار شامل:

  1. ماژول پایگاه داده:

    • پیکربندی می کند TypeORM با جزئیات و نهادهای اتصال.
    • می توان آن را برای انجام پرس و جوهای پایگاه داده خام یا عملیات سفارشی گسترش داد.
  2. ابزارهای مشترک:

    • فیلتر استثنای جهانی: همه استثناها را به طور یکنواخت می گیرد و مدیریت می کند.
    • رهگیرها: به طور خودکار پاسخ های API را به یک ساختار سازگار تبدیل کنید.
    • لوله اعتبار سنجی: درخواست های دریافتی را با استفاده از DTO و class-validator اعتبار سنجی می کند.
    • دکوراتورها: تزئینات قابل استفاده مجدد برای حاشیه نویسی API ها.
  3. AppModule و Main Entry:

    • ریشه NestJS ماژول برنامه ای که همه چیز را به هم پیوند می دهد.
    • پیکربندی می کند لوله های جهانی، فیلترها، و

رهگیرها برای اطمینان از رفتار سازگار در سراسر برنامه.

این تنظیمات بسیار ماژولار، قابل نگهداری و به شرح زیر است NestJS بهترین شیوه ها اکنون می توانید ماژول های اضافی اضافه کنید یا ماژول های موجود را با این پایه گسترش دهید.

اگر از مطالب من لذت می برید و می خواهید از کار من حمایت کنید، می توانید یک قهوه برای من بخرید. حمایت شما بسیار قدردانی می شود!

سلب مسئولیت: این محتوا توسط هوش مصنوعی تولید شده است.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا