From 7ae5702b4ef8e8e15ac0907491efe745f348f12f Mon Sep 17 00:00:00 2001 From: snilakandan Date: Tue, 1 Jul 2025 14:46:00 -0500 Subject: [PATCH 01/13] Added cursor rules --- .../README.md | 50 +++ .../product-detail-component.mdc | 158 +++++++ .../product-list-component.mdc | 398 ++++++++++++++++++ .../product-tile-component.mdc | 303 +++++++++++++ .../rules/product-component-requirements.mdc | 33 ++ 5 files changed, 942 insertions(+) create mode 100644 .cursor/rules/product-component-requirements-mdc/README.md create mode 100644 .cursor/rules/product-component-requirements-mdc/product-detail-component.mdc create mode 100644 .cursor/rules/product-component-requirements-mdc/product-list-component.mdc create mode 100644 .cursor/rules/product-component-requirements-mdc/product-tile-component.mdc create mode 100644 .cursor/rules/product-component-requirements.mdc diff --git a/.cursor/rules/product-component-requirements-mdc/README.md b/.cursor/rules/product-component-requirements-mdc/README.md new file mode 100644 index 0000000000..67a16e92d1 --- /dev/null +++ b/.cursor/rules/product-component-requirements-mdc/README.md @@ -0,0 +1,50 @@ +# Product Component Development Guide + +## 🚀 Getting Started (Beginner-Friendly) + +### Quick Start Path +1. **Start Simple**: Use `product-tile-component.mdc` for basic product displays +2. **Add Lists**: Move to `product-list-component.mdc` when you need collections +3. **Go Deep**: Use `product-detail-component.mdc` for full product pages + +### For New Developers +- Focus on one component type at a time +- Start with the "Basic Implementation" examples +- Skip advanced features until you're comfortable with basics +- Use the "Common Mistakes" sections to avoid pitfalls + +### When You're Ready for More +- Explore "Advanced Features" sections +- Study the "Best Practices" examples +- Review "Testing Guidelines" for quality assurance + +## 📚 Component Complexity Levels + +| Component | Complexity | Best For | +|-----------|------------|----------| +| Product Tile | ⭐ Beginner | Simple product cards, grids | +| Product List | ⭐⭐ Intermediate | Product collections, search results | +| Product Detail | ⭐⭐⭐ Advanced | Full product pages, complex layouts | + +## 🎯 Quick Reference + +### Product Tile +- **Use when**: Displaying products in grids, carousels, or lists +- **Key features**: Image, name, price, quick actions +- **Start here**: Perfect for beginners + +### Product List +- **Use when**: Showing multiple products with filtering/sorting +- **Key features**: Grid/list views, pagination, filters +- **Prerequisites**: Comfortable with Product Tiles + +### Product Detail +- **Use when**: Full product information pages +- **Key features**: Complete product data, variants, add to cart +- **Prerequisites**: Experience with Tiles and Lists + +## 💡 Tips for Success +- Copy the basic examples and modify gradually +- Test frequently as you build +- Ask for help when stuck - these are complex components! +- Start with mock data before integrating real APIs \ No newline at end of file diff --git a/.cursor/rules/product-component-requirements-mdc/product-detail-component.mdc b/.cursor/rules/product-component-requirements-mdc/product-detail-component.mdc new file mode 100644 index 0000000000..4a045074fb --- /dev/null +++ b/.cursor/rules/product-component-requirements-mdc/product-detail-component.mdc @@ -0,0 +1,158 @@ +--- +description: Product Detail component requirement template +globs: "**/components/**" +type: agent-requested +alwaysApply: false +--- + +# Product Detail Component + +## Data Model +- Product +- Product Bundle (parent with child items; only parent can be added to cart) +- Product Set (logical group; all items added to cart together, no parent/child) + +## Features/Props +- Show product images (gallery) +- Show product name, price, description +- Add to Cart (single, bundle parent, or set) +- Quantity Selector (for product or bundle parent; for sets, quantity per item if supported) +- Show Reviews +- Show Affinity/Recommendations +- Variant selection (color, size, etc.) +- Show all items in bundle/set with details + +## Look & Feel +- Theme +- Skeleton +- Style + +## Example Requirement Object +```js +const requirement = { + dataModel: 'Product' | 'ProductBundle' | 'ProductSet', + features: ['Gallery', 'Add to Cart', 'Quantity Selector', 'Show Reviews', 'Variant Selection', 'Show Bundle/Set Items'], + lookAndFeel: ['Theme', 'Skeleton', 'Style'] +} +``` + +## Example Usage +```jsx + +``` + +## Best Practices +- For bundles: Only allow the parent product to be added to cart; display all child items with details, but do not allow adding/removing them individually. +- For sets: Display all items in the set; when the set is added to cart, all items are added together. There is no parent/child distinction. +- Use dedicated subcomponents for gallery, reviews, and variant selection. +- Scaffold all features as configurable props. +- Use skeletons for loading states. +- Support theming and custom styles. +- Validate all props and document requirements. +- Ensure accessibility (alt text, keyboard navigation, ARIA labels). + +## Bad Practices +- For bundles: Allowing child items to be added to cart individually, or not showing all child items. +- For sets: Treating one item as a parent, or not adding all items to cart together. +- Mixing all logic in one large component (no subcomponents). +- Hardcoding feature logic (not making features optional/configurable). +- Ignoring loading states (no skeletons or spinners). +- Not supporting theming or custom styles. +- Skipping accessibility (missing alt text, no keyboard support). +- Not validating props or documenting requirements. + +## Example Component Skeleton +```jsx +/* +Requirement: +{ + dataModel: 'Product' | 'ProductBundle' | 'ProductSet', + features: ['Gallery', 'Add to Cart', 'Quantity Selector', 'Show Reviews', 'Variant Selection', 'Show Bundle/Set Items'], + lookAndFeel: ['Theme', 'Skeleton', 'Style'] +} +*/ + +import React, {useState} from 'react' +import PropTypes from 'prop-types' +import {Box, Text, Button, Skeleton, useTheme} from '@salesforce/retail-react-app/app/components/shared/ui' +import {QuantityPicker} from '@salesforce/retail-react-app/app/components/quantity-picker' +import RecommendedProducts from '@salesforce/retail-react-app/app/components/recommended-products' +// import ProductGallery from './ProductGallery' +// import ProductReviews from './ProductReviews' +// import VariantSelector from './VariantSelector' + +const ProductDetail = ({product, onAddToCart, showReviews = true, showRecommendations = true}) => { + const [quantity, setQuantity] = useState(1) + const [isLoading, setIsLoading] = useState(false) + const theme = useTheme() + + const handleAddToCart = async () => { + setIsLoading(true) + await onAddToCart(product, quantity) + setIsLoading(false) + } + + // Example: Render bundle/set items + const renderBundleOrSetItems = () => { + if (product.type === 'bundle' && product.childItems) { + return ( + + Bundle Includes: + {product.childItems.map((item) => ( + + {item.name} + {/* No add to cart for child items */} + + ))} + + ) + } + if (product.type === 'set' && product.setItems) { + return ( + + Set Includes: + {product.setItems.map((item) => ( + + {item.name} + {/* All items in set are added to cart together */} + + ))} + + ) + } + return null + } + + return ( + + + {/* */} + {product.name} + {product.description} + {/* */} + + + {renderBundleOrSetItems()} + {showReviews && ( + // + Reviews go here + )} + {showRecommendations && ( + + )} + + + ) +} + +ProductDetail.propTypes = { + product: PropTypes.object.isRequired, + onAddToCart: PropTypes.func.isRequired, + showReviews: PropTypes.bool, + showRecommendations: PropTypes.bool +} + +export default ProductDetail +``` diff --git a/.cursor/rules/product-component-requirements-mdc/product-list-component.mdc b/.cursor/rules/product-component-requirements-mdc/product-list-component.mdc new file mode 100644 index 0000000000..9e45a7e2d9 --- /dev/null +++ b/.cursor/rules/product-component-requirements-mdc/product-list-component.mdc @@ -0,0 +1,398 @@ +--- +description: Product list component requirement template +globs: "**/components/**" +type: agent-requested +alwaysApply: false +--- +# Product List Component + +## Data Model +- Array of Products (single items) +- Array of Product Bundles (parent with child items; only parent can be added to cart) +- Array of Product Sets (logical groups; all items added to cart together, no parent/child) +- Mixed array (products, bundles, and sets together) + +## Features/Props +- Grid/List view toggle +- Sorting options (price, name, rating, newest, popularity) +- Filtering (category, price range, rating, availability) +- Pagination or infinite scroll +- Search functionality +- Loading states and skeletons +- Empty state handling +- Product count display +- View mode persistence +- Responsive grid/list layouts +- Bulk actions (add multiple to cart, wishlist) + +## Look & Feel +- Theme +- Skeleton +- Style (grid/list view options) +- Responsive design +- Loading animations +- Empty state design + +## Example Requirement Object +```js +const requirement = { + dataModel: 'Product[]' | 'ProductBundle[]' | 'ProductSet[]' | 'Mixed[]', + features: ['Grid/List Toggle', 'Sorting', 'Filtering', 'Pagination', 'Search', 'Loading States', 'Empty State', 'Product Count', 'View Persistence', 'Responsive Layout', 'Bulk Actions'], + lookAndFeel: ['Theme', 'Skeleton', 'Style', 'Responsive', 'Loading Animations', 'Empty State Design'] +} +``` + +## Example Usage +```jsx + +``` + +## Best Practices +- Support both grid and list view modes with smooth transitions. +- Implement proper sorting with clear visual indicators. +- Provide comprehensive filtering with clear active filter display. +- Use infinite scroll or pagination based on performance requirements. +- Show loading skeletons for better perceived performance. +- Handle empty states gracefully with helpful messaging. +- Display product count and current view information. +- Persist user preferences (view mode, sort order, filters). +- Ensure responsive design works on all screen sizes. +- Implement proper accessibility (keyboard navigation, screen readers). +- Use virtualization for large product lists to improve performance. +- Validate all props and document requirements. + +## Bad Practices +- No view mode toggle or poor transitions between modes. +- Limited sorting options or unclear sort indicators. +- No filtering capabilities or poor filter UX. +- No pagination/infinite scroll for large lists. +- No loading states (poor perceived performance). +- Poor empty state handling (no helpful messaging). +- No product count or view information. +- Not persisting user preferences. +- Non-responsive design (breaks on mobile). +- Ignoring accessibility (no keyboard support, missing ARIA labels). +- Loading all products at once (no virtualization for large lists). +- Not validating props or documenting requirements. + +## Example Component Skeleton +```jsx +/* +Requirement: +{ + dataModel: 'Product[]' | 'ProductBundle[]' | 'ProductSet[]' | 'Mixed[]', + features: ['Grid/List Toggle', 'Sorting', 'Filtering', 'Pagination', 'Search', 'Loading States', 'Empty State', 'Product Count', 'View Persistence', 'Responsive Layout', 'Bulk Actions'], + lookAndFeel: ['Theme', 'Skeleton', 'Style', 'Responsive', 'Loading Animations', 'Empty State Design'] +} +*/ + +import React, {useState, useEffect, useMemo} from 'react' +import PropTypes from 'prop-types' +import {Box, Text, Button, Skeleton, useTheme, Select, HStack, VStack, Grid, Flex, Spinner} from '@salesforce/retail-react-app/app/components/shared/ui' +import {Grid as GridIcon, List as ListIcon, Filter, Search} from '@salesforce/retail-react-app/app/components/shared/icons' +import ProductTile from './ProductTile' +// import ProductListTile from './ProductListTile' +// import ProductFilters from './ProductFilters' +// import ProductSearch from './ProductSearch' + +const ProductList = ({ + products = [], + onAddToCart, + onWishlistToggle, + onQuickView, + viewMode: initialViewMode = 'grid', + sortBy: initialSortBy = 'name', + filters = {}, + onLoadMore, + isLoading = false, + hasMore = false, + showFilters = true, + showSearch = true, + showSort = true, + showViewToggle = true, + itemsPerPage = 12 +}) => { + const [viewMode, setViewMode] = useState(initialViewMode) + const [sortBy, setSortBy] = useState(initialSortBy) + const [currentFilters, setCurrentFilters] = useState(filters) + const [searchQuery, setSearchQuery] = useState('') + const [currentPage, setCurrentPage] = useState(1) + const theme = useTheme() + + // Persist view mode preference + useEffect(() => { + localStorage.setItem('productListViewMode', viewMode) + }, [viewMode]) + + // Load view mode preference + useEffect(() => { + const savedViewMode = localStorage.getItem('productListViewMode') + if (savedViewMode) setViewMode(savedViewMode) + }, []) + + // Sort and filter products + const processedProducts = useMemo(() => { + let filtered = products.filter(product => { + // Search filter + if (searchQuery && !product.name.toLowerCase().includes(searchQuery.toLowerCase())) { + return false + } + + // Apply other filters (category, price range, etc.) + if (currentFilters.category && product.category !== currentFilters.category) { + return false + } + if (currentFilters.minPrice && product.price < currentFilters.minPrice) { + return false + } + if (currentFilters.maxPrice && product.price > currentFilters.maxPrice) { + return false + } + if (currentFilters.inStock && product.stock === 0) { + return false + } + + return true + }) + + // Sort products + filtered.sort((a, b) => { + switch (sortBy) { + case 'price': + return a.price - b.price + case 'price-desc': + return b.price - a.price + case 'name': + return a.name.localeCompare(b.name) + case 'rating': + return (b.rating || 0) - (a.rating || 0) + case 'newest': + return new Date(b.createdAt) - new Date(a.createdAt) + case 'popularity': + return (b.salesCount || 0) - (a.salesCount || 0) + default: + return 0 + } + }) + + return filtered + }, [products, searchQuery, currentFilters, sortBy]) + + // Paginate products + const paginatedProducts = useMemo(() => { + const startIndex = (currentPage - 1) * itemsPerPage + return processedProducts.slice(startIndex, startIndex + itemsPerPage) + }, [processedProducts, currentPage, itemsPerPage]) + + const handleLoadMore = () => { + if (hasMore && onLoadMore) { + onLoadMore() + } else { + setCurrentPage(prev => prev + 1) + } + } + + const handleFilterChange = (newFilters) => { + setCurrentFilters(newFilters) + setCurrentPage(1) // Reset to first page when filters change + } + + const renderEmptyState = () => ( + + + No products found + + + Try adjusting your search or filters to find what you're looking for. + + + + ) + + const renderProductGrid = () => ( + + {paginatedProducts.map((product) => ( + + ))} + + ) + + const renderProductList = () => ( + + {paginatedProducts.map((product) => ( + // + + {product.name} - ${product.price} + + ))} + + ) + + return ( + + {/* Header with controls */} + + + + Products ({processedProducts.length}) + + + + {/* Search */} + {showSearch && ( + + + setSearchQuery(e.target.value)} + style={{ + padding: '8px 12px 8px 36px', + border: '1px solid #e2e8f0', + borderRadius: '6px', + width: '250px' + }} + /> + + )} + + {/* Sort */} + {showSort && ( + + )} + + {/* View Toggle */} + {showViewToggle && ( + + + + + )} + + + + {/* Filters */} + {showFilters && ( + + {/* */} + + Filters: {Object.keys(currentFilters).length > 0 ? + Object.entries(currentFilters).map(([key, value]) => `${key}: ${value}`).join(', ') : + 'None applied' + } + + + )} + + + {/* Product Grid/List */} + + {processedProducts.length === 0 ? ( + renderEmptyState() + ) : ( + <> + {viewMode === 'grid' ? renderProductGrid() : renderProductList()} + + {/* Load More / Pagination */} + {(hasMore || currentPage * itemsPerPage < processedProducts.length) && ( + + + + )} + + )} + + + ) +} + +ProductList.propTypes = { + products: PropTypes.array.isRequired, + onAddToCart: PropTypes.func.isRequired, + onWishlistToggle: PropTypes.func, + onQuickView: PropTypes.func, + viewMode: PropTypes.oneOf(['grid', 'list']), + sortBy: PropTypes.string, + filters: PropTypes.object, + onLoadMore: PropTypes.func, + isLoading: PropTypes.bool, + hasMore: PropTypes.bool, + showFilters: PropTypes.bool, + showSearch: PropTypes.bool, + showSort: PropTypes.bool, + showViewToggle: PropTypes.bool, + itemsPerPage: PropTypes.number +} + +export default ProductList diff --git a/.cursor/rules/product-component-requirements-mdc/product-tile-component.mdc b/.cursor/rules/product-component-requirements-mdc/product-tile-component.mdc new file mode 100644 index 0000000000..03fb94e584 --- /dev/null +++ b/.cursor/rules/product-component-requirements-mdc/product-tile-component.mdc @@ -0,0 +1,303 @@ +--- +description: Product Tile component requirement template +globs: "**/components/**" +type: agent-requested +alwaysApply: false +--- +name: Product Tile Component +description: Requirements and examples for creating product tile components (cards, grid items) +globs: ["**/components/**"] + +# Product Tile Component + +## 🚀 Quick Start (Beginner) +If you're new to product components, start here: + +### Basic Product Tile +```jsx +const ProductTile = ({ product, onAddToCart }) => { + return ( +
+ {product.name} +

{product.name}

+

{product.price}

+ +
+ ) +} +``` + +### Essential Props +- `product`: Product data object +- `onAddToCart`: Function to add product to cart +- `className`: Optional styling + +--- + +## 📋 Full Requirements (Advanced) + +### Data Model +- Product (single item) +- Product Bundle (parent with child items; only parent can be added to cart) +- Product Set (logical group; all items added to cart together, no parent/child) + +## Features/Props +- Product image (primary image with optional hover gallery) +- Product name and price +- Quick Add to Cart (single, bundle parent, or set) +- Wishlist/Favorite toggle +- Quick view modal trigger +- Rating/Reviews display +- Sale/Badge indicators +- Stock status +- Variant preview (color swatches, size preview) +- Bundle/Set item count indicator + +## Look & Feel +- Theme +- Skeleton +- Style (grid/list view options) +- Hover effects +- Responsive design + +## Example Requirement Object +```js +const requirement = { + dataModel: 'Product' | 'ProductBundle' | 'ProductSet', + features: ['Image', 'Quick Add to Cart', 'Wishlist', 'Quick View', 'Rating', 'Sale Badge', 'Stock Status', 'Variant Preview', 'Bundle/Set Indicator'], + lookAndFeel: ['Theme', 'Skeleton', 'Style', 'Hover Effects', 'Responsive'] +} +``` + +## Example Usage +```jsx + +``` + +## Best Practices +- For bundles: Show bundle indicator and item count; only allow adding the parent to cart. +- For sets: Show set indicator and item count; add all items to cart together. +- Use lazy loading for images with proper alt text. +- Implement hover effects for better UX (image gallery, quick actions). +- Show stock status clearly (in stock, low stock, out of stock). +- Display sale badges prominently when applicable. +- Use skeleton loading states for better perceived performance. +- Support both grid and list view modes. +- Ensure accessibility (keyboard navigation, screen reader support). +- Validate all props and document requirements. + +## Bad Practices +- For bundles: Allowing child items to be added individually, or not showing bundle indicators. +- For sets: Treating one item as parent, or not adding all items together. +- Loading all images at once (no lazy loading). +- No hover states or interactive feedback. +- Missing stock status or sale indicators. +- No loading states (poor perceived performance). +- Hardcoded layout (no responsive design). +- Ignoring accessibility (no keyboard support, missing ARIA labels). +- Not validating props or documenting requirements. + +## Example Component Skeleton +```jsx +/* +Requirement: +{ + dataModel: 'Product' | 'ProductBundle' | 'ProductSet', + features: ['Image', 'Quick Add to Cart', 'Wishlist', 'Quick View', 'Rating', 'Sale Badge', 'Stock Status', 'Variant Preview', 'Bundle/Set Indicator'], + lookAndFeel: ['Theme', 'Skeleton', 'Style', 'Hover Effects', 'Responsive'] +} +*/ + +import React, {useState} from 'react' +import PropTypes from 'prop-types' +import {Box, Text, Button, Skeleton, useTheme, Badge, IconButton} from '@salesforce/retail-react-app/app/components/shared/ui' +import {Heart, Eye, ShoppingCart} from '@salesforce/retail-react-app/app/components/shared/icons' +// import ProductImage from './ProductImage' +// import RatingDisplay from './RatingDisplay' +// import VariantPreview from './VariantPreview' + +const ProductTile = ({ + product, + onAddToCart, + onWishlistToggle, + onQuickView, + viewMode = 'grid', + showWishlist = true, + showQuickView = true, + showRating = true +}) => { + const [isLoading, setIsLoading] = useState(false) + const [isHovered, setIsHovered] = useState(false) + const theme = useTheme() + + const handleAddToCart = async () => { + setIsLoading(true) + await onAddToCart(product, 1) + setIsLoading(false) + } + + const getStockStatus = () => { + if (product.stock === 0) return {status: 'out', color: 'red', text: 'Out of Stock'} + if (product.stock <= 5) return {status: 'low', color: 'orange', text: 'Low Stock'} + return {status: 'in', color: 'green', text: 'In Stock'} + } + + const renderBundleOrSetIndicator = () => { + if (product.type === 'bundle' && product.childItems) { + return ( + + Bundle ({product.childItems.length} items) + + ) + } + if (product.type === 'set' && product.setItems) { + return ( + + Set ({product.setItems.length} items) + + ) + } + return null + } + + const stockStatus = getStockStatus() + + return ( + + setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + transition="all 0.2s" + _hover={{transform: 'translateY(-2px)', boxShadow: 'lg'}} + cursor="pointer" + > + {renderBundleOrSetIndicator()} + + {/* Product Image */} + + {/* */} + + Product Image + + + {/* Quick Actions on Hover */} + {isHovered && ( + + {showWishlist && ( + } + onClick={(e) => { + e.stopPropagation() + onWishlistToggle?.(product) + }} + aria-label="Add to wishlist" + /> + )} + {showQuickView && ( + } + onClick={(e) => { + e.stopPropagation() + onQuickView?.(product) + }} + aria-label="Quick view" + /> + )} + + )} + + + {/* Product Info */} + + + {product.name} + + + + + ${product.price} + + {product.originalPrice && product.originalPrice > product.price && ( + + ${product.originalPrice} + + )} + + + {/* Rating */} + {showRating && product.rating && ( + + {/* */} + + ★ {product.rating} ({product.reviewCount || 0}) + + + )} + + {/* Stock Status */} + + {stockStatus.text} + + + {/* Quick Add to Cart */} + + + + + ) +} + +ProductTile.propTypes = { + product: PropTypes.object.isRequired, + onAddToCart: PropTypes.func.isRequired, + onWishlistToggle: PropTypes.func, + onQuickView: PropTypes.func, + viewMode: PropTypes.oneOf(['grid', 'list']), + showWishlist: PropTypes.bool, + showQuickView: PropTypes.bool, + showRating: PropTypes.bool +} + +export default ProductTile diff --git a/.cursor/rules/product-component-requirements.mdc b/.cursor/rules/product-component-requirements.mdc new file mode 100644 index 0000000000..b56f5f8e0d --- /dev/null +++ b/.cursor/rules/product-component-requirements.mdc @@ -0,0 +1,33 @@ +--- +description: Requirement template for a Product Detail component (supports single products, bundles, and sets) +globs: +alwaysApply: false +--- + +# Requirement-Driven Product Component Creation (Start Here) + +This rule is your entry point for building Product components in a requirement-driven, modular way. + +## How to Use +- Browse the `.cursor/rules/product-component-requirements-mdc/` directory. +- Each `.mdc` file in that directory describes a specific Product component scenario (e.g., product-tile, product-list, product-detail). +- Each file includes: + - Data model + - Features/props + - Look & feel + - Example requirement object + - Example code usage + - **Best practices** (what to do) + - **Bad practices** (what to avoid) + +## Why This Structure? +- Encourages a requirement-driven, modular approach to component development. +- Makes it easy to find, reuse, and update requirements for common Product scenarios. +- Helps teams avoid common mistakes and maintain high code quality. + +## Adding New Requirements +- Add a new `.mdc` file for each new Product component scenario in the `product-requirements-mdc` directory. +- Include both best and bad practices for maximum clarity. +- Update the directory as new scenarios or conventions arise. + +**Start every Product component with a requirement!** From c7749394a2de22128ba149e4141abf31ab58d58b Mon Sep 17 00:00:00 2001 From: snilakandan Date: Tue, 1 Jul 2025 14:57:53 -0500 Subject: [PATCH 02/13] Rules updated --- .../product-detail-component.mdc | 31 ++++++++++++++++- .../product-list-component.mdc | 33 +++++++++++++++++-- .../product-tile-component.mdc | 3 -- 3 files changed, 61 insertions(+), 6 deletions(-) diff --git a/.cursor/rules/product-component-requirements-mdc/product-detail-component.mdc b/.cursor/rules/product-component-requirements-mdc/product-detail-component.mdc index 4a045074fb..49415f5c3b 100644 --- a/.cursor/rules/product-component-requirements-mdc/product-detail-component.mdc +++ b/.cursor/rules/product-component-requirements-mdc/product-detail-component.mdc @@ -7,7 +7,36 @@ alwaysApply: false # Product Detail Component -## Data Model +## 🚀 Quick Start (Beginner) +If you're new to product components, start here: + +### Basic Product Detail +```jsx +const ProductDetail = ({ product, onAddToCart }) => { + return ( +
+ {product.name} +

{product.name}

+

{product.description}

+

Price: {product.price}

+ +
+ ) +} +``` + +### Essential Props +- `product`: Product data object +- `onAddToCart`: Function to add product to cart +- `className`: Optional styling + +--- + +## 📋 Full Requirements (Advanced) + +### Data Model - Product - Product Bundle (parent with child items; only parent can be added to cart) - Product Set (logical group; all items added to cart together, no parent/child) diff --git a/.cursor/rules/product-component-requirements-mdc/product-list-component.mdc b/.cursor/rules/product-component-requirements-mdc/product-list-component.mdc index 9e45a7e2d9..42e4dc11d5 100644 --- a/.cursor/rules/product-component-requirements-mdc/product-list-component.mdc +++ b/.cursor/rules/product-component-requirements-mdc/product-list-component.mdc @@ -1,11 +1,40 @@ --- -description: Product list component requirement template +description: Product list component requirement template globs: "**/components/**" type: agent-requested alwaysApply: false --- # Product List Component +## 🚀 Quick Start (Beginner) +If you're new to product components, start here: + +### Basic Product List +```jsx +const ProductList = ({ products, onAddToCart }) => { + return ( +
+ {products.map(product => ( + + ))} +
+ ) +} +``` + +### Essential Props +- `products`: Array of product objects +- `onAddToCart`: Function to add product to cart +- `className`: Optional styling + +--- + +## 📋 Full Requirements (Advanced) + ## Data Model - Array of Products (single items) - Array of Product Bundles (parent with child items; only parent can be added to cart) @@ -22,7 +51,7 @@ alwaysApply: false - Empty state handling - Product count display - View mode persistence -- Responsive grid/list layouts +- Responsive grid/list layout - Bulk actions (add multiple to cart, wishlist) ## Look & Feel diff --git a/.cursor/rules/product-component-requirements-mdc/product-tile-component.mdc b/.cursor/rules/product-component-requirements-mdc/product-tile-component.mdc index 03fb94e584..07d3b4c847 100644 --- a/.cursor/rules/product-component-requirements-mdc/product-tile-component.mdc +++ b/.cursor/rules/product-component-requirements-mdc/product-tile-component.mdc @@ -4,9 +4,6 @@ globs: "**/components/**" type: agent-requested alwaysApply: false --- -name: Product Tile Component -description: Requirements and examples for creating product tile components (cards, grid items) -globs: ["**/components/**"] # Product Tile Component From ebdd8a94c4ff2887fed33995637d3a2b8fea8105 Mon Sep 17 00:00:00 2001 From: snilakandan Date: Tue, 1 Jul 2025 15:02:04 -0500 Subject: [PATCH 03/13] Rules updated --- .cursor/rules/product-component-requirements.mdc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.cursor/rules/product-component-requirements.mdc b/.cursor/rules/product-component-requirements.mdc index b56f5f8e0d..1f59dce378 100644 --- a/.cursor/rules/product-component-requirements.mdc +++ b/.cursor/rules/product-component-requirements.mdc @@ -1,6 +1,7 @@ --- -description: Requirement template for a Product Detail component (supports single products, bundles, and sets) -globs: +description: Requirement template for a Product component +globs: "**/components/**" +type: agent-requested alwaysApply: false --- @@ -12,6 +13,7 @@ This rule is your entry point for building Product components in a requirement-d - Browse the `.cursor/rules/product-component-requirements-mdc/` directory. - Each `.mdc` file in that directory describes a specific Product component scenario (e.g., product-tile, product-list, product-detail). - Each file includes: + - Quick Start - Data model - Features/props - Look & feel From 702811bc399b6da48db81125acab680a97d34d68 Mon Sep 17 00:00:00 2001 From: snilakandan Date: Tue, 1 Jul 2025 15:35:08 -0500 Subject: [PATCH 04/13] Updated Readme document --- .../README.md | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/.cursor/rules/product-component-requirements-mdc/README.md b/.cursor/rules/product-component-requirements-mdc/README.md index 67a16e92d1..c14fe6bd3a 100644 --- a/.cursor/rules/product-component-requirements-mdc/README.md +++ b/.cursor/rules/product-component-requirements-mdc/README.md @@ -47,4 +47,37 @@ - Copy the basic examples and modify gradually - Test frequently as you build - Ask for help when stuck - these are complex components! -- Start with mock data before integrating real APIs \ No newline at end of file +- Start with mock data before integrating real APIs + +## 📊 Data Structure: ProductHit + +All product components work with **ProductHit** objects from Salesforce Commerce Cloud's search API: + +```javascript +// Basic ProductHit structure +{ + productId: '25686571M', + productName: 'Product Name', + price: 299.99, + hitType: 'master', // 'master', 'product', 'set', 'bundle' + image: { + alt: 'Product description', + link: 'https://example.com/image.jpg' + } +} +``` + +### Hit Types +- **`master`**: Product with variants (colors, sizes) +- **`product`**: Simple product (single item) +- **`set`**: Product set (multiple items sold together) +- **`bundle`**: Product bundle (parent with child items) + +### Key Properties +- `productId`: Unique identifier +- `productName`: Display name +- `price`: Current price +- `image`: Primary product image +- `imageGroups`: Multiple image sizes +- `variants`: Product variations +- `variationAttributes`: Available options (color, size, etc.) \ No newline at end of file From b299d4e44ef1c36f27b89e7995f36a04291a9c1b Mon Sep 17 00:00:00 2001 From: snilakandan Date: Wed, 2 Jul 2025 11:53:21 -0500 Subject: [PATCH 05/13] Updated rules --- .../README.md | 94 ++---- .../product-detail-component.mdc | 96 +----- .../product-list-component.mdc | 314 +----------------- .../product-tile-component.mdc | 197 +---------- .../rules/product-component-requirements.mdc | 1 - 5 files changed, 28 insertions(+), 674 deletions(-) diff --git a/.cursor/rules/product-component-requirements-mdc/README.md b/.cursor/rules/product-component-requirements-mdc/README.md index c14fe6bd3a..490e4ac5a6 100644 --- a/.cursor/rules/product-component-requirements-mdc/README.md +++ b/.cursor/rules/product-component-requirements-mdc/README.md @@ -1,83 +1,27 @@ -# Product Component Development Guide +# Product Component Requirements -## 🚀 Getting Started (Beginner-Friendly) +This directory contains hybrid rules for product components that combine structured requirements with intelligent analysis. Each rule provides clear guidance on what to build while instructing the AI to study the actual implementation in `node_modules/@salesforce/retail-react-app`. -### Quick Start Path -1. **Start Simple**: Use `product-tile-component.mdc` for basic product displays -2. **Add Lists**: Move to `product-list-component.mdc` when you need collections -3. **Go Deep**: Use `product-detail-component.mdc` for full product pages +## Rules -### For New Developers -- Focus on one component type at a time -- Start with the "Basic Implementation" examples -- Skip advanced features until you're comfortable with basics -- Use the "Common Mistakes" sections to avoid pitfalls +- `product-detail-component.mdc` - Requirements and analysis for product detail pages +- `product-list-component.mdc` - Requirements and analysis for product listing pages +- `product-tile-component.mdc` - Requirements and analysis for product tile components -### When You're Ready for More -- Explore "Advanced Features" sections -- Study the "Best Practices" examples -- Review "Testing Guidelines" for quality assurance +## Hybrid Approach -## 📚 Component Complexity Levels +Each rule combines: -| Component | Complexity | Best For | -|-----------|------------|----------| -| Product Tile | ⭐ Beginner | Simple product cards, grids | -| Product List | ⭐⭐ Intermediate | Product collections, search results | -| Product Detail | ⭐⭐⭐ Advanced | Full product pages, complex layouts | +### 📋 **Structured Requirements** +- Clear data models (Product, Bundle, Set) +- Essential features and props +- Best practices and bad practices +- Look & feel requirements -## 🎯 Quick Reference +### 🔍 **Analysis-Based Guidance** +- Instructions to analyze actual codebase +- Study real implementation patterns +- Guide developers based on actual code +- Provide contextual advice -### Product Tile -- **Use when**: Displaying products in grids, carousels, or lists -- **Key features**: Image, name, price, quick actions -- **Start here**: Perfect for beginners - -### Product List -- **Use when**: Showing multiple products with filtering/sorting -- **Key features**: Grid/list views, pagination, filters -- **Prerequisites**: Comfortable with Product Tiles - -### Product Detail -- **Use when**: Full product information pages -- **Key features**: Complete product data, variants, add to cart -- **Prerequisites**: Experience with Tiles and Lists - -## 💡 Tips for Success -- Copy the basic examples and modify gradually -- Test frequently as you build -- Ask for help when stuck - these are complex components! -- Start with mock data before integrating real APIs - -## 📊 Data Structure: ProductHit - -All product components work with **ProductHit** objects from Salesforce Commerce Cloud's search API: - -```javascript -// Basic ProductHit structure -{ - productId: '25686571M', - productName: 'Product Name', - price: 299.99, - hitType: 'master', // 'master', 'product', 'set', 'bundle' - image: { - alt: 'Product description', - link: 'https://example.com/image.jpg' - } -} -``` - -### Hit Types -- **`master`**: Product with variants (colors, sizes) -- **`product`**: Simple product (single item) -- **`set`**: Product set (multiple items sold together) -- **`bundle`**: Product bundle (parent with child items) - -### Key Properties -- `productId`: Unique identifier -- `productName`: Display name -- `price`: Current price -- `image`: Primary product image -- `imageGroups`: Multiple image sizes -- `variants`: Product variations -- `variationAttributes`: Available options (color, size, etc.) \ No newline at end of file +This approach provides the clarity of structured requirements while leveraging the intelligence of analysis-based guidance. \ No newline at end of file diff --git a/.cursor/rules/product-component-requirements-mdc/product-detail-component.mdc b/.cursor/rules/product-component-requirements-mdc/product-detail-component.mdc index 49415f5c3b..889bde948f 100644 --- a/.cursor/rules/product-component-requirements-mdc/product-detail-component.mdc +++ b/.cursor/rules/product-component-requirements-mdc/product-detail-component.mdc @@ -1,7 +1,6 @@ --- description: Product Detail component requirement template globs: "**/components/**" -type: agent-requested alwaysApply: false --- @@ -90,98 +89,9 @@ const requirement = { - Skipping accessibility (missing alt text, no keyboard support). - Not validating props or documenting requirements. -## Example Component Skeleton -```jsx -/* -Requirement: -{ - dataModel: 'Product' | 'ProductBundle' | 'ProductSet', - features: ['Gallery', 'Add to Cart', 'Quantity Selector', 'Show Reviews', 'Variant Selection', 'Show Bundle/Set Items'], - lookAndFeel: ['Theme', 'Skeleton', 'Style'] -} -*/ - -import React, {useState} from 'react' -import PropTypes from 'prop-types' -import {Box, Text, Button, Skeleton, useTheme} from '@salesforce/retail-react-app/app/components/shared/ui' -import {QuantityPicker} from '@salesforce/retail-react-app/app/components/quantity-picker' -import RecommendedProducts from '@salesforce/retail-react-app/app/components/recommended-products' -// import ProductGallery from './ProductGallery' -// import ProductReviews from './ProductReviews' -// import VariantSelector from './VariantSelector' - -const ProductDetail = ({product, onAddToCart, showReviews = true, showRecommendations = true}) => { - const [quantity, setQuantity] = useState(1) - const [isLoading, setIsLoading] = useState(false) - const theme = useTheme() - - const handleAddToCart = async () => { - setIsLoading(true) - await onAddToCart(product, quantity) - setIsLoading(false) - } - - // Example: Render bundle/set items - const renderBundleOrSetItems = () => { - if (product.type === 'bundle' && product.childItems) { - return ( - - Bundle Includes: - {product.childItems.map((item) => ( - - {item.name} - {/* No add to cart for child items */} - - ))} - - ) - } - if (product.type === 'set' && product.setItems) { - return ( - - Set Includes: - {product.setItems.map((item) => ( - - {item.name} - {/* All items in set are added to cart together */} - - ))} - - ) - } - return null - } +--- - return ( - - - {/* */} - {product.name} - {product.description} - {/* */} - - - {renderBundleOrSetItems()} - {showReviews && ( - // - Reviews go here - )} - {showRecommendations && ( - - )} - - - ) -} +## 🔍 Analysis Rule -ProductDetail.propTypes = { - product: PropTypes.object.isRequired, - onAddToCart: PropTypes.func.isRequired, - showReviews: PropTypes.bool, - showRecommendations: PropTypes.bool -} +Analyze node_modules/@salesforce/retail-react-app/app/pages/product-detail/ to understand how product detail pages are implemented. Study the data models, component structure, and patterns used for single products, bundles, and sets. Guide developers based on actual implementation patterns found in the template. -export default ProductDetail -``` diff --git a/.cursor/rules/product-component-requirements-mdc/product-list-component.mdc b/.cursor/rules/product-component-requirements-mdc/product-list-component.mdc index 42e4dc11d5..3a35c60694 100644 --- a/.cursor/rules/product-component-requirements-mdc/product-list-component.mdc +++ b/.cursor/rules/product-component-requirements-mdc/product-list-component.mdc @@ -1,7 +1,6 @@ --- description: Product list component requirement template globs: "**/components/**" -type: agent-requested alwaysApply: false --- # Product List Component @@ -113,315 +112,8 @@ const requirement = { - Loading all products at once (no virtualization for large lists). - Not validating props or documenting requirements. -## Example Component Skeleton -```jsx -/* -Requirement: -{ - dataModel: 'Product[]' | 'ProductBundle[]' | 'ProductSet[]' | 'Mixed[]', - features: ['Grid/List Toggle', 'Sorting', 'Filtering', 'Pagination', 'Search', 'Loading States', 'Empty State', 'Product Count', 'View Persistence', 'Responsive Layout', 'Bulk Actions'], - lookAndFeel: ['Theme', 'Skeleton', 'Style', 'Responsive', 'Loading Animations', 'Empty State Design'] -} -*/ - -import React, {useState, useEffect, useMemo} from 'react' -import PropTypes from 'prop-types' -import {Box, Text, Button, Skeleton, useTheme, Select, HStack, VStack, Grid, Flex, Spinner} from '@salesforce/retail-react-app/app/components/shared/ui' -import {Grid as GridIcon, List as ListIcon, Filter, Search} from '@salesforce/retail-react-app/app/components/shared/icons' -import ProductTile from './ProductTile' -// import ProductListTile from './ProductListTile' -// import ProductFilters from './ProductFilters' -// import ProductSearch from './ProductSearch' - -const ProductList = ({ - products = [], - onAddToCart, - onWishlistToggle, - onQuickView, - viewMode: initialViewMode = 'grid', - sortBy: initialSortBy = 'name', - filters = {}, - onLoadMore, - isLoading = false, - hasMore = false, - showFilters = true, - showSearch = true, - showSort = true, - showViewToggle = true, - itemsPerPage = 12 -}) => { - const [viewMode, setViewMode] = useState(initialViewMode) - const [sortBy, setSortBy] = useState(initialSortBy) - const [currentFilters, setCurrentFilters] = useState(filters) - const [searchQuery, setSearchQuery] = useState('') - const [currentPage, setCurrentPage] = useState(1) - const theme = useTheme() - - // Persist view mode preference - useEffect(() => { - localStorage.setItem('productListViewMode', viewMode) - }, [viewMode]) - - // Load view mode preference - useEffect(() => { - const savedViewMode = localStorage.getItem('productListViewMode') - if (savedViewMode) setViewMode(savedViewMode) - }, []) - - // Sort and filter products - const processedProducts = useMemo(() => { - let filtered = products.filter(product => { - // Search filter - if (searchQuery && !product.name.toLowerCase().includes(searchQuery.toLowerCase())) { - return false - } - - // Apply other filters (category, price range, etc.) - if (currentFilters.category && product.category !== currentFilters.category) { - return false - } - if (currentFilters.minPrice && product.price < currentFilters.minPrice) { - return false - } - if (currentFilters.maxPrice && product.price > currentFilters.maxPrice) { - return false - } - if (currentFilters.inStock && product.stock === 0) { - return false - } - - return true - }) - - // Sort products - filtered.sort((a, b) => { - switch (sortBy) { - case 'price': - return a.price - b.price - case 'price-desc': - return b.price - a.price - case 'name': - return a.name.localeCompare(b.name) - case 'rating': - return (b.rating || 0) - (a.rating || 0) - case 'newest': - return new Date(b.createdAt) - new Date(a.createdAt) - case 'popularity': - return (b.salesCount || 0) - (a.salesCount || 0) - default: - return 0 - } - }) - - return filtered - }, [products, searchQuery, currentFilters, sortBy]) - - // Paginate products - const paginatedProducts = useMemo(() => { - const startIndex = (currentPage - 1) * itemsPerPage - return processedProducts.slice(startIndex, startIndex + itemsPerPage) - }, [processedProducts, currentPage, itemsPerPage]) - - const handleLoadMore = () => { - if (hasMore && onLoadMore) { - onLoadMore() - } else { - setCurrentPage(prev => prev + 1) - } - } - - const handleFilterChange = (newFilters) => { - setCurrentFilters(newFilters) - setCurrentPage(1) // Reset to first page when filters change - } - - const renderEmptyState = () => ( - - - No products found - - - Try adjusting your search or filters to find what you're looking for. - - - - ) - - const renderProductGrid = () => ( - - {paginatedProducts.map((product) => ( - - ))} - - ) - - const renderProductList = () => ( - - {paginatedProducts.map((product) => ( - // - - {product.name} - ${product.price} - - ))} - - ) - - return ( - - {/* Header with controls */} - - - - Products ({processedProducts.length}) - - - - {/* Search */} - {showSearch && ( - - - setSearchQuery(e.target.value)} - style={{ - padding: '8px 12px 8px 36px', - border: '1px solid #e2e8f0', - borderRadius: '6px', - width: '250px' - }} - /> - - )} - - {/* Sort */} - {showSort && ( - - )} - - {/* View Toggle */} - {showViewToggle && ( - - - - - )} - - - - {/* Filters */} - {showFilters && ( - - {/* */} - - Filters: {Object.keys(currentFilters).length > 0 ? - Object.entries(currentFilters).map(([key, value]) => `${key}: ${value}`).join(', ') : - 'None applied' - } - - - )} - - - {/* Product Grid/List */} - - {processedProducts.length === 0 ? ( - renderEmptyState() - ) : ( - <> - {viewMode === 'grid' ? renderProductGrid() : renderProductList()} - - {/* Load More / Pagination */} - {(hasMore || currentPage * itemsPerPage < processedProducts.length) && ( - - - - )} - - )} - - - ) -} +--- -ProductList.propTypes = { - products: PropTypes.array.isRequired, - onAddToCart: PropTypes.func.isRequired, - onWishlistToggle: PropTypes.func, - onQuickView: PropTypes.func, - viewMode: PropTypes.oneOf(['grid', 'list']), - sortBy: PropTypes.string, - filters: PropTypes.object, - onLoadMore: PropTypes.func, - isLoading: PropTypes.bool, - hasMore: PropTypes.bool, - showFilters: PropTypes.bool, - showSearch: PropTypes.bool, - showSort: PropTypes.bool, - showViewToggle: PropTypes.bool, - itemsPerPage: PropTypes.number -} +## 🔍 Analysis Rule -export default ProductList +Analyze node_modules/@salesforce/retail-react-app/app/pages/product-list/ to understand how product listing pages are implemented. Study the search functionality, filtering, pagination, and grid/list display patterns. diff --git a/.cursor/rules/product-component-requirements-mdc/product-tile-component.mdc b/.cursor/rules/product-component-requirements-mdc/product-tile-component.mdc index 07d3b4c847..c66cbf6e62 100644 --- a/.cursor/rules/product-component-requirements-mdc/product-tile-component.mdc +++ b/.cursor/rules/product-component-requirements-mdc/product-tile-component.mdc @@ -1,7 +1,6 @@ --- description: Product Tile component requirement template globs: "**/components/**" -type: agent-requested alwaysApply: false --- @@ -102,199 +101,9 @@ const requirement = { - Ignoring accessibility (no keyboard support, missing ARIA labels). - Not validating props or documenting requirements. -## Example Component Skeleton -```jsx -/* -Requirement: -{ - dataModel: 'Product' | 'ProductBundle' | 'ProductSet', - features: ['Image', 'Quick Add to Cart', 'Wishlist', 'Quick View', 'Rating', 'Sale Badge', 'Stock Status', 'Variant Preview', 'Bundle/Set Indicator'], - lookAndFeel: ['Theme', 'Skeleton', 'Style', 'Hover Effects', 'Responsive'] -} -*/ - -import React, {useState} from 'react' -import PropTypes from 'prop-types' -import {Box, Text, Button, Skeleton, useTheme, Badge, IconButton} from '@salesforce/retail-react-app/app/components/shared/ui' -import {Heart, Eye, ShoppingCart} from '@salesforce/retail-react-app/app/components/shared/icons' -// import ProductImage from './ProductImage' -// import RatingDisplay from './RatingDisplay' -// import VariantPreview from './VariantPreview' - -const ProductTile = ({ - product, - onAddToCart, - onWishlistToggle, - onQuickView, - viewMode = 'grid', - showWishlist = true, - showQuickView = true, - showRating = true -}) => { - const [isLoading, setIsLoading] = useState(false) - const [isHovered, setIsHovered] = useState(false) - const theme = useTheme() - - const handleAddToCart = async () => { - setIsLoading(true) - await onAddToCart(product, 1) - setIsLoading(false) - } - - const getStockStatus = () => { - if (product.stock === 0) return {status: 'out', color: 'red', text: 'Out of Stock'} - if (product.stock <= 5) return {status: 'low', color: 'orange', text: 'Low Stock'} - return {status: 'in', color: 'green', text: 'In Stock'} - } - - const renderBundleOrSetIndicator = () => { - if (product.type === 'bundle' && product.childItems) { - return ( - - Bundle ({product.childItems.length} items) - - ) - } - if (product.type === 'set' && product.setItems) { - return ( - - Set ({product.setItems.length} items) - - ) - } - return null - } - - const stockStatus = getStockStatus() - - return ( - - setIsHovered(true)} - onMouseLeave={() => setIsHovered(false)} - transition="all 0.2s" - _hover={{transform: 'translateY(-2px)', boxShadow: 'lg'}} - cursor="pointer" - > - {renderBundleOrSetIndicator()} - - {/* Product Image */} - - {/* */} - - Product Image - - - {/* Quick Actions on Hover */} - {isHovered && ( - - {showWishlist && ( - } - onClick={(e) => { - e.stopPropagation() - onWishlistToggle?.(product) - }} - aria-label="Add to wishlist" - /> - )} - {showQuickView && ( - } - onClick={(e) => { - e.stopPropagation() - onQuickView?.(product) - }} - aria-label="Quick view" - /> - )} - - )} - - - {/* Product Info */} - - - {product.name} - - - - - ${product.price} - - {product.originalPrice && product.originalPrice > product.price && ( - - ${product.originalPrice} - - )} - - - {/* Rating */} - {showRating && product.rating && ( - - {/* */} - - ★ {product.rating} ({product.reviewCount || 0}) - - - )} +--- - {/* Stock Status */} - - {stockStatus.text} - +## 🔍 Analysis Rule - {/* Quick Add to Cart */} - - - - - ) -} - -ProductTile.propTypes = { - product: PropTypes.object.isRequired, - onAddToCart: PropTypes.func.isRequired, - onWishlistToggle: PropTypes.func, - onQuickView: PropTypes.func, - viewMode: PropTypes.oneOf(['grid', 'list']), - showWishlist: PropTypes.bool, - showQuickView: PropTypes.bool, - showRating: PropTypes.bool -} +Analyze node_modules/@salesforce/retail-react-app/app/components/product-tile/ to understand how product tiles are implemented. Study the image handling, pricing display, variant selection, and interaction patterns. -export default ProductTile diff --git a/.cursor/rules/product-component-requirements.mdc b/.cursor/rules/product-component-requirements.mdc index 1f59dce378..8864e22e52 100644 --- a/.cursor/rules/product-component-requirements.mdc +++ b/.cursor/rules/product-component-requirements.mdc @@ -1,7 +1,6 @@ --- description: Requirement template for a Product component globs: "**/components/**" -type: agent-requested alwaysApply: false --- From a2bff8baa4a2198e84e3acd3bf4b7f36be973c99 Mon Sep 17 00:00:00 2001 From: snilakandan Date: Wed, 2 Jul 2025 14:13:47 -0500 Subject: [PATCH 06/13] updated rules --- .../product-detail-component.mdc | 2 +- .../product-list-component.mdc | 2 +- .../product-tile-component.mdc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.cursor/rules/product-component-requirements-mdc/product-detail-component.mdc b/.cursor/rules/product-component-requirements-mdc/product-detail-component.mdc index 889bde948f..c6eb870770 100644 --- a/.cursor/rules/product-component-requirements-mdc/product-detail-component.mdc +++ b/.cursor/rules/product-component-requirements-mdc/product-detail-component.mdc @@ -93,5 +93,5 @@ const requirement = { ## 🔍 Analysis Rule -Analyze node_modules/@salesforce/retail-react-app/app/pages/product-detail/ to understand how product detail pages are implemented. Study the data models, component structure, and patterns used for single products, bundles, and sets. Guide developers based on actual implementation patterns found in the template. +Analyze "node_modules/@salesforce/*retail-react-app*/app/pages/*product*/" to understand how product detail pages are implemented. Study the data models, component structure, and patterns used for single products, bundles, and sets. Guide developers based on actual implementation patterns found in the template. diff --git a/.cursor/rules/product-component-requirements-mdc/product-list-component.mdc b/.cursor/rules/product-component-requirements-mdc/product-list-component.mdc index 3a35c60694..6d4f2065de 100644 --- a/.cursor/rules/product-component-requirements-mdc/product-list-component.mdc +++ b/.cursor/rules/product-component-requirements-mdc/product-list-component.mdc @@ -116,4 +116,4 @@ const requirement = { ## 🔍 Analysis Rule -Analyze node_modules/@salesforce/retail-react-app/app/pages/product-list/ to understand how product listing pages are implemented. Study the search functionality, filtering, pagination, and grid/list display patterns. +Analyze "node_modules/@salesforce/*retail-react-app*/app/pages/*product*/" to understand how product listing pages are implemented. Study the search functionality, filtering, pagination, and grid/list display patterns. diff --git a/.cursor/rules/product-component-requirements-mdc/product-tile-component.mdc b/.cursor/rules/product-component-requirements-mdc/product-tile-component.mdc index c66cbf6e62..19649b1ad1 100644 --- a/.cursor/rules/product-component-requirements-mdc/product-tile-component.mdc +++ b/.cursor/rules/product-component-requirements-mdc/product-tile-component.mdc @@ -105,5 +105,5 @@ const requirement = { ## 🔍 Analysis Rule -Analyze node_modules/@salesforce/retail-react-app/app/components/product-tile/ to understand how product tiles are implemented. Study the image handling, pricing display, variant selection, and interaction patterns. +Analyze "node_modules/@salesforce/*retail-react-app*/app/pages/*product*/" to understand how product tiles are implemented. Study the image handling, pricing display, variant selection, and interaction patterns. From 370178a0eed3870fc1604cf073e5a3ad430b0f2e Mon Sep 17 00:00:00 2001 From: snilakandan Date: Thu, 3 Jul 2025 15:39:21 -0500 Subject: [PATCH 07/13] Cursor Rules for generating components --- .../component-generation-requirements.mdc | 249 ++++++++++++++++++ .../README.md | 27 -- .../product-detail-component.mdc | 97 ------- .../product-list-component.mdc | 119 --------- .../product-tile-component.mdc | 109 -------- .../rules/product-component-requirements.mdc | 34 --- 6 files changed, 249 insertions(+), 386 deletions(-) create mode 100644 .cursor/rules/component-generation-requirements.mdc delete mode 100644 .cursor/rules/product-component-requirements-mdc/README.md delete mode 100644 .cursor/rules/product-component-requirements-mdc/product-detail-component.mdc delete mode 100644 .cursor/rules/product-component-requirements-mdc/product-list-component.mdc delete mode 100644 .cursor/rules/product-component-requirements-mdc/product-tile-component.mdc delete mode 100644 .cursor/rules/product-component-requirements.mdc diff --git a/.cursor/rules/component-generation-requirements.mdc b/.cursor/rules/component-generation-requirements.mdc new file mode 100644 index 0000000000..d858489bfc --- /dev/null +++ b/.cursor/rules/component-generation-requirements.mdc @@ -0,0 +1,249 @@ +--- +description: USE when generating components +globs: "**/components/**" +alwaysApply: false +--- +# Create and Generate React Components in PWA Kit + +## Overview +- Agent must follow the following steps to handle user request to create a new component: + - Agent must ask user to provide the component name, purpose, and desired functionality. + - Agent should determine the appropriate component type (presentational, container, form, etc.). + - Collected component information must be displayed and asked for confirmation. + +## Instructions to Create a New Component + +You need to create a new React component following established patterns and best practices. + +### 1. Create the Component File +First, create a new file for your component. A good practice is to place it in the `app/components` directory. +For example, to create a new "User Profile" component, you would create the file `app/components/user-profile/index.jsx`: + +```jsx +import React from 'react' +import {Box, Avatar, Text} from '@salesforce/retail-react-app/app/components/shared/ui' +import {useCurrentCustomer} from '@salesforce/retail-react-app/app/hooks/use-current-customer' + +const UserProfile = ({userId}) => { + const {data: customer, loading, error} = useCurrentCustomer() + + if (loading) return Loading... + if (error) return Error loading user + if (!customer) return User not found + + return ( + + + + {customer.firstName} {customer.lastName} + + + {customer.email} + + + ) +} + +export default UserProfile +``` + +### 2. Component Structure Guidelines +- **Always use functional components** with React hooks +- **Include proper error handling** for data fetching +- **Use semantic HTML elements** and proper accessibility +- **Follow naming conventions**: PascalCase for components, camelCase for props +- **Include TypeScript interfaces** when using TypeScript + +### 3. File Organization +``` +app/components/ +├── user-profile/ +│ ├── index.jsx // Main component +│ ├── user-profile.test.jsx // Tests +│ └── user-profile.stories.jsx // Storybook +``` + +## Overriding an Existing Component + +Override components from the base template by creating files with the same name and path in your project's `overrides` directory. + +### 1. Identify the Component to Override +The component in the base template is located at `app/components/component-name/index.jsx`. + +### 2. Create the Overriding File +To override this component, create a new file with the exact same path inside your `overrides` directory: `overrides/app/components/component-name/index.jsx`. + +### 3. Customize the Component +Now you can add your custom code to this new file. You can either copy the original content and modify it, extend the original component or create a new component from scratch. + +Here's an example of how you might add a custom feature to extend an existing component: + +```jsx +// overrides/app/components/product-card/index.jsx +import React from 'react' +import {Box, Badge} from '@salesforce/retail-react-app/app/components/shared/ui' +import {default as BaseProductCard} from '@salesforce/retail-react-app/app/components/product-card' + +const CustomProductCard = (props) => { + return ( + + + New! + + + + ) +} + +// You must export the component as default +export default CustomProductCard +``` + +In this example, we're importing the original `ProductCard` component and wrapping it with our own custom component to add a "New!" badge. + +## Component Best Practices + +### Component Structure +- **Single Responsibility**: One main purpose per component +- **Functional Components**: Always use hooks-based approach +- **Error Handling**: Include loading and error states +- **Accessibility**: Use semantic HTML and ARIA labels +- **Type Safety**: Include TypeScript interfaces when possible + +### Naming Conventions +- **Components**: PascalCase (e.g., `UserProfile`, `ProductCard`) +- **Files**: kebab-case for directories (e.g., `user-profile/`) +- **Props**: camelCase (e.g., `userId`, `productName`) +- **Hooks**: camelCase starting with 'use' (e.g., `useUser`, `useProduct`) + +### File Organization +- Place components in `app/components/` directory +- Use index.jsx for main component file +- Include test files with `.test.jsx` suffix +- Include Storybook files with `.stories.jsx` suffix + +## Common Patterns to Avoid + +### Component Anti-patterns +- **Class Components**: Use functional components with hooks +- **Large Components**: Break down components over 200 lines +- **Mixed Concerns**: Don't mix UI logic with business logic +- **Poor Error Handling**: Always handle loading and error states +- **Missing Accessibility**: Include proper ARIA labels and semantic HTML + +## Special Component Types + +The PWA Kit also has several "special" component types that you can create for different purposes: + +### Presentational Components +Components that focus on displaying data without business logic: +```jsx +// app/components/product-image/index.jsx +import React from 'react' +import {Image} from '@salesforce/retail-react-app/app/components/shared/ui' + +const ProductImage = ({src, alt, ...props}) => { + return {alt} +} + +export default ProductImage +``` + +### Container Components +Components that handle data fetching and state management: +```jsx +// app/components/product-details-container/index.jsx +import React from 'react' +import {useProduct} from '@salesforce/retail-react-app/app/hooks/use-product' +import ProductDetails from './product-details' + +const ProductDetailsContainer = ({productId}) => { + const {data: product, loading, error} = useProduct(productId) + + if (loading) return
Loading...
+ if (error) return
Error loading product
+ + return +} + +export default ProductDetailsContainer +``` + +### Form Components +Components that handle user input and form submission: +```jsx +// app/components/contact-form/index.jsx +import React from 'react' +import {Box, Button, Input, Textarea} from '@salesforce/retail-react-app/app/components/shared/ui' + +const ContactForm = ({onSubmit}) => { + const handleSubmit = (e) => { + e.preventDefault() + // Handle form submission + onSubmit(formData) + } + + return ( + + + +