6.3 KiB
name, description
| name | description |
|---|---|
| mehraein | 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:
- Page file — thin wrapper that renders the feature root component.
- Feature root — composes section components (e.g.
Home.tsx,ProductDetail.tsx). components/— feature-specific sections and widgets.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
"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
FCand explicitPropstypes. - 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]orlg:px-30 - Buttons:
rounded-full, heighth-10(primary) orh-8(compact) - Cards:
rounded-xl, subtle shadows likeshadow-[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">, globaldirection: 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")— seeformatPriceinapp/product/constants.ts. - Star ratings: pass
rtltoreact-simple-star-rating. - Search inputs: icon on the right (
right-4,pr-11),text-right,dir="rtl"on input wrapper.
Images & Icons
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
alttext. - Icons from
iconsax-reactjs; usecolor="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:
ContactCtaSectionfrom@/app/home/components/ContactCtaSection— append at bottom of product/category pages.
Example page:
import ProductDetail from "../components/ProductDetail";
const ProductPage = () => {
return <ProductDetail />;
};
export default ProductPage;
Constants & Mock Data
Keep static content in feature constants.ts files:
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/withpage.tsx, root component,components/, andconstants.tsif 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/imagefor images,iconsax-reactjsfor icons - Match responsive spacing conventions (
px-4 sm:px-8 lg:px-[120px]) - Append
ContactCtaSectionon content pages when appropriate - Run
npm run lintafter changes
Commands
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