Create skill for cursor
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
---
|
||||
name: mehraein
|
||||
description: Develop the Mehraein Persian RTL print/e-commerce Next.js app following project conventions. Use when working in this repository, adding pages or features, building UI components, or implementing product/category/home screens for the Mehraein storefront.
|
||||
---
|
||||
|
||||
# Mehraein Project Skill
|
||||
|
||||
## Project Overview
|
||||
|
||||
Mehraein is a Persian (Farsi) RTL storefront for custom print, packaging, and promotional products (boxes, labels, business cards, etc.). UI copy is in Persian; layout is RTL throughout.
|
||||
|
||||
## Tech Stack
|
||||
|
||||
| Layer | Choice |
|
||||
|-------|--------|
|
||||
| Framework | Next.js 16 (App Router) |
|
||||
| UI | React 19, TypeScript |
|
||||
| Styling | Tailwind CSS v4 (`@import "tailwindcss"`) |
|
||||
| Icons | `iconsax-reactjs` |
|
||||
| Carousel | `embla-carousel-react` |
|
||||
| Ratings | `react-simple-star-rating` |
|
||||
| Deploy | Docker standalone (`output: "standalone"`) |
|
||||
|
||||
**Next.js 16:** This is NOT standard Next.js from training data. Before writing Next.js code, read the relevant guide in `node_modules/next/dist/docs/` and heed deprecation notices.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
app/
|
||||
├── components/ # Shared UI primitives (Button, Input, Carousel, GridWrapper, Select, Seprator)
|
||||
├── lib/ # Utilities (cn)
|
||||
├── shared/ # Layout shell (Header, Footer) + subcomponents
|
||||
├── home/ # Home feature: Home.tsx + components/
|
||||
├── product/ # Product feature: [id]/page.tsx + components/ + constants.ts
|
||||
├── category/ # Category feature: page.tsx + components/ + constants.ts
|
||||
├── layout.tsx # Root layout (Header + main + Footer)
|
||||
└── globals.css # Tailwind theme tokens + RTL base styles
|
||||
assets/ # Images, IRANYekan font files
|
||||
public/ # Static assets
|
||||
```
|
||||
|
||||
### Feature module pattern
|
||||
|
||||
Each route feature owns its folder:
|
||||
|
||||
1. **Page file** — thin wrapper that renders the feature root component.
|
||||
2. **Feature root** — composes section components (e.g. `Home.tsx`, `ProductDetail.tsx`).
|
||||
3. **`components/`** — feature-specific sections and widgets.
|
||||
4. **`constants.ts`** — mock data, option lists, types, and formatters.
|
||||
|
||||
Do not put feature-specific logic in `app/components/`; only reusable primitives go there.
|
||||
|
||||
## Component Conventions
|
||||
|
||||
```tsx
|
||||
"use client"; // only when state, events, or browser APIs are needed
|
||||
|
||||
import { cn } from "@/app/lib/cn";
|
||||
import { type FC } from "react";
|
||||
|
||||
type Props = {
|
||||
className?: string;
|
||||
};
|
||||
|
||||
const MyComponent: FC<Props> = ({ className }) => {
|
||||
return <div className={cn("base-classes", className)} />;
|
||||
};
|
||||
|
||||
export default MyComponent;
|
||||
```
|
||||
|
||||
- Default exports for components.
|
||||
- Use `FC` and explicit `Props` types.
|
||||
- Merge classes with `cn()` from `@/app/lib/cn`.
|
||||
- Extend native HTML attribute types where appropriate (`React.ButtonHTMLAttributes`, etc.).
|
||||
- Reuse existing primitives before creating new ones: `Button`, `Input`, `Carousel`, `GridWrapper`, `Select`.
|
||||
|
||||
## Styling & Design Tokens
|
||||
|
||||
Defined in `app/globals.css` via `@theme inline`:
|
||||
|
||||
| Token | Value | Usage |
|
||||
|-------|-------|-------|
|
||||
| `primary` | `#ff730b` | CTAs, accents, icons |
|
||||
| `secondary` | `#f1f6fa` | Borders, backgrounds |
|
||||
| `description` | `#888888` | Muted text |
|
||||
| `maxWidth` | `1100px` | Content max width |
|
||||
|
||||
Common patterns:
|
||||
|
||||
- **Page horizontal padding:** `px-4 sm:px-8 lg:px-[120px]` or `lg:px-30`
|
||||
- **Buttons:** `rounded-full`, height `h-10` (primary) or `h-8` (compact)
|
||||
- **Cards:** `rounded-xl`, subtle shadows like `shadow-[0_4px_20px_rgba(0,0,0,0.1)]`
|
||||
- **Brand blues:** `#194873`, `#2A3950`, `#3A4147`, `#6C7680`
|
||||
|
||||
Use Tailwind theme classes (`bg-primary`, `text-secondary`, `border-secondary`) instead of hardcoding token colors when possible.
|
||||
|
||||
## RTL & Persian Content
|
||||
|
||||
- Root layout: `<html lang="fa">`, global `direction: rtl`.
|
||||
- All user-facing strings in Persian.
|
||||
- Font: **IRANYekan** (loaded via `@/assets/iranyekan/fonts.css`).
|
||||
- Numbers in prices use English digits via `toLocaleString("en-US")` — see `formatPrice` in `app/product/constants.ts`.
|
||||
- Star ratings: pass `rtl` to `react-simple-star-rating`.
|
||||
- Search inputs: icon on the right (`right-4`, `pr-11`), `text-right`, `dir="rtl"` on input wrapper.
|
||||
|
||||
## Images & Icons
|
||||
|
||||
```tsx
|
||||
import logo from "@/assets/images/logo.png";
|
||||
import Image from "next/image";
|
||||
|
||||
<Image src={logo} alt="توضیح فارسی" width={116} height={72} className="h-12 w-auto" />
|
||||
```
|
||||
|
||||
- Static images live in `assets/images/`.
|
||||
- Always provide meaningful Persian `alt` text.
|
||||
- Icons from `iconsax-reactjs`; use `color="currentColor"` and size props (`size={20}`).
|
||||
|
||||
## Page Composition
|
||||
|
||||
Root layout wraps every page with `Header` and `Footer`. Pages only render `<main>` content.
|
||||
|
||||
Reuse cross-page sections:
|
||||
|
||||
- `ContactCtaSection` from `@/app/home/components/ContactCtaSection` — append at bottom of product/category pages.
|
||||
|
||||
Example page:
|
||||
|
||||
```tsx
|
||||
import ProductDetail from "../components/ProductDetail";
|
||||
|
||||
const ProductPage = () => {
|
||||
return <ProductDetail />;
|
||||
};
|
||||
|
||||
export default ProductPage;
|
||||
```
|
||||
|
||||
## Constants & Mock Data
|
||||
|
||||
Keep static content in feature `constants.ts` files:
|
||||
|
||||
```tsx
|
||||
export const SORT_OPTIONS = [
|
||||
{ label: "پرفروشترین", value: "bestseller" },
|
||||
] as const;
|
||||
|
||||
export type SortValue = (typeof SORT_OPTIONS)[number]["value"];
|
||||
|
||||
export function formatPrice(value: number): string {
|
||||
return value.toLocaleString("en-US");
|
||||
}
|
||||
```
|
||||
|
||||
Use `as const` for option arrays. Export types derived from constants. No API layer yet — data is mocked locally.
|
||||
|
||||
## Path Aliases
|
||||
|
||||
`@/*` maps to project root. Prefer:
|
||||
|
||||
- `@/app/components/Button`
|
||||
- `@/assets/images/...`
|
||||
|
||||
## Adding New Features Checklist
|
||||
|
||||
- [ ] Create feature folder under `app/` with `page.tsx`, root component, `components/`, and `constants.ts` if needed
|
||||
- [ ] Keep page files thin; compose in feature root component
|
||||
- [ ] Add `"use client"` only where interactivity is required
|
||||
- [ ] Use existing shared components and design tokens
|
||||
- [ ] Write UI text in Persian; respect RTL layout
|
||||
- [ ] Use `next/image` for images, `iconsax-reactjs` for icons
|
||||
- [ ] Match responsive spacing conventions (`px-4 sm:px-8 lg:px-[120px]`)
|
||||
- [ ] Append `ContactCtaSection` on content pages when appropriate
|
||||
- [ ] Run `npm run lint` after changes
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
npm run dev # local development
|
||||
npm run build # production build
|
||||
npm run lint # ESLint
|
||||
```
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- For component inventory and file map, see [reference.md](reference.md)
|
||||
@@ -0,0 +1,68 @@
|
||||
# Mehraein Reference
|
||||
|
||||
## Shared Components (`app/components/`)
|
||||
|
||||
| Component | Purpose | Key props |
|
||||
|-----------|---------|-----------|
|
||||
| `Button` | Primary/outline CTA | `variant: "primary" \| "outline"` |
|
||||
| `Input` | Text/search input | `variant: "primary" \| "search"` |
|
||||
| `Carousel` | Embla image slider | — |
|
||||
| `GridWrapper` | Responsive grid layout | — |
|
||||
| `Select` | Dropdown select | — |
|
||||
| `Seprator` | Visual divider | — |
|
||||
|
||||
## Layout Shell (`app/shared/`)
|
||||
|
||||
| File | Role |
|
||||
|------|------|
|
||||
| `Header.tsx` | Top bar, logo, search, nav, cart |
|
||||
| `Footer.tsx` | Footer sections |
|
||||
| `components/HeaderMenu.tsx` | Navigation menu |
|
||||
| `components/AllProductsMenu.tsx` | Products mega-menu |
|
||||
| `components/Footer*.tsx` | Footer sub-sections |
|
||||
|
||||
## Feature Routes
|
||||
|
||||
| Route | Entry | Root component |
|
||||
|-------|-------|----------------|
|
||||
| `/` | `app/page.tsx` | `app/home/Home.tsx` |
|
||||
| `/category` | `app/category/page.tsx` | inline in page |
|
||||
| `/product/[id]` | `app/product/[id]/page.tsx` | `ProductDetail` |
|
||||
|
||||
## Home Sections (`app/home/components/`)
|
||||
|
||||
`BannerSection`, `StepSection`, `CategorySection`, `ProductSection`, `OrderByApplication`, `BestSellerCategories`, `OrderRegistrationSteps`, `BlogsSection`, `ContactCtaSection`, `ProductCard`, `CategoryCard`, `BlogCard`
|
||||
|
||||
## Product Sections (`app/product/components/`)
|
||||
|
||||
`ProductDetail`, `ProductGallery`, `ProductPurchaseOptions`, `ProductOrderActions`, `ProductTabs`, `ProductRelated`, `ProductBreadcrumb`
|
||||
|
||||
## Category Sections (`app/category/components/`)
|
||||
|
||||
`CategoryHero`, `CategoryToolbar`, `CategoryFilters`, `CategoryProducts`
|
||||
|
||||
## Color Palette (beyond theme tokens)
|
||||
|
||||
| Hex | Typical use |
|
||||
|-----|-------------|
|
||||
| `#194873` | Body accent text |
|
||||
| `#2A3950` | Card titles |
|
||||
| `#3A4147` | Header/promo text |
|
||||
| `#6C7680` | Secondary nav icons |
|
||||
| `#D00003` | Strikethrough price |
|
||||
| `#E9EEF2` | Card borders |
|
||||
| `#004A9005` | Tinted info box background |
|
||||
|
||||
## Responsive Breakpoints
|
||||
|
||||
Follow Tailwind defaults (`sm`, `md`, `lg`). Common layout shifts:
|
||||
|
||||
- Mobile: stacked columns, compact padding
|
||||
- `lg`: side-by-side layouts, wider padding (`lg:px-[120px]` or `lg:px-30`)
|
||||
- Header: mobile cart/actions vs desktop full nav
|
||||
|
||||
## Docker Build Notes
|
||||
|
||||
- Multi-stage build with Liara npm mirror
|
||||
- Standalone Next.js output
|
||||
- Runs as non-root `appuser` on port 3000
|
||||
Reference in New Issue
Block a user