Initial commit: Meshkee dashboards monorepo.

Includes business, customer, and super-admin apps with shared packages and production deploy scripts.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-07-22 13:48:53 +03:30
co-authored by Cursor
commit f566387c61
509 changed files with 62690 additions and 0 deletions
@@ -0,0 +1,179 @@
import { useEffect, useMemo, useState } from 'react'
import { X } from 'lucide-react'
import { ApiError } from '../lib/api'
import { listAllStoreItems } from '../services/storeItemService'
import { groupStoreItemsByProduct } from '../utils/storeProductGroups'
import {
StoreItemMultiSearchSelect,
type StoreItemSearchOption,
} from './StoreItemMultiSearchSelect'
import modalStyles from './VariationsModal.module.css'
import styles from './PickStoreSpecialItemsModal.module.css'
interface PickStoreSpecialItemsModalProps {
open: boolean
specialTitle: string
existingStoreItemIds: string[]
onClose: () => void
onConfirm: (storeItemIds: string[]) => void
isSubmitting?: boolean
}
const ANIMATION_MS = 220
export function PickStoreSpecialItemsModal({
open,
specialTitle,
existingStoreItemIds,
onClose,
onConfirm,
isSubmitting = false,
}: PickStoreSpecialItemsModalProps) {
const [mounted, setMounted] = useState(open)
const [closing, setClosing] = useState(false)
const [options, setOptions] = useState<StoreItemSearchOption[]>([])
const [isLoading, setIsLoading] = useState(false)
const [error, setError] = useState('')
const [selectedIds, setSelectedIds] = useState<string[]>([])
const existingSet = useMemo(() => new Set(existingStoreItemIds), [existingStoreItemIds])
useEffect(() => {
if (open) {
setMounted(true)
setClosing(false)
setSelectedIds([])
setError('')
} else if (mounted) {
setClosing(true)
const timer = setTimeout(() => {
setMounted(false)
setClosing(false)
}, ANIMATION_MS)
return () => clearTimeout(timer)
}
}, [open, mounted])
useEffect(() => {
if (!open) return
const controller = new AbortController()
void loadOptions(controller.signal)
return () => controller.abort()
}, [open, existingStoreItemIds])
useEffect(() => {
if (!mounted || closing) return
const onKey = (e: KeyboardEvent) => {
if (e.key === 'Escape') onClose()
}
document.addEventListener('keydown', onKey)
return () => document.removeEventListener('keydown', onKey)
}, [mounted, closing, onClose])
async function loadOptions(signal?: AbortSignal) {
setIsLoading(true)
setError('')
try {
const items = await listAllStoreItems(signal)
const listings = groupStoreItemsByProduct(items)
const nextOptions = listings
.map((listing) => {
const storeItemId = listing.representative.storeItemId ?? listing.representative.id
return {
id: storeItemId,
title: listing.productTitle,
nameFa: listing.productNameFa,
image: listing.productImage,
}
})
.filter((option) => !existingSet.has(option.id))
setOptions(nextOptions)
} catch (err) {
if (err instanceof DOMException && err.name === 'AbortError') return
if (err instanceof ApiError) {
setError(err.message)
} else {
setError('Unable to load store items.')
}
} finally {
setIsLoading(false)
}
}
function toggleSelection(storeItemId: string) {
setSelectedIds((prev) =>
prev.includes(storeItemId)
? prev.filter((id) => id !== storeItemId)
: [...prev, storeItemId],
)
}
function handleConfirm() {
if (selectedIds.length === 0) return
onConfirm(selectedIds)
}
if (!mounted) return null
return (
<div
className={`${modalStyles.overlay} ${closing ? modalStyles.overlayOut : modalStyles.overlayIn}`}
onClick={(e) => e.target === e.currentTarget && onClose()}
role="presentation"
>
<div
className={`${modalStyles.modal} ${styles.modalWide} ${closing ? modalStyles.modalOut : modalStyles.modalIn}`}
role="dialog"
aria-modal="true"
aria-labelledby="pick-special-items-title"
>
<div className={modalStyles.header}>
<div>
<h2 id="pick-special-items-title" className={modalStyles.title}>
Add to {specialTitle}
</h2>
<p className={modalStyles.subtitle}>Select store items to feature in this category.</p>
</div>
<button type="button" className={modalStyles.closeBtn} onClick={onClose} aria-label="Close">
<X size={20} />
</button>
</div>
<div className={modalStyles.body}>
{error && <p className={styles.error}>{error}</p>}
{isLoading ? (
<p className={styles.empty}>Loading store items...</p>
) : options.length === 0 ? (
<p className={styles.empty}>All store items are already in this category.</p>
) : (
<StoreItemMultiSearchSelect
options={options}
selectedIds={selectedIds}
onToggle={toggleSelection}
placeholder="Type 3+ characters to search store items"
disabled={isSubmitting}
/>
)}
<div className={styles.footer}>
<button type="button" className={styles.cancelBtn} onClick={onClose} disabled={isSubmitting}>
Cancel
</button>
<button
type="button"
className={styles.confirmBtn}
onClick={handleConfirm}
disabled={isSubmitting || selectedIds.length === 0}
>
{isSubmitting ? 'Adding...' : `Add ${selectedIds.length || ''} item${selectedIds.length === 1 ? '' : 's'}`}
</button>
</div>
</div>
</div>
</div>
)
}