{Array.from({ length: slideCount }).map((_, i) => (
@@ -261,7 +187,7 @@ export default function CafeDetail() {
aria-label="بازگشت"
className="absolute left-4 top-4 z-10 flex h-9 w-9 items-center justify-center rounded-full bg-white shadow"
>
-
+
@@ -316,7 +242,7 @@ export default function CafeDetail() {
-
+
آدرس
{cafe.address}
@@ -342,7 +268,7 @@ export default function CafeDetail() {
-
+
توجه داشته باشید که مسئولیت رزرو و حضور بهموقع در کافه بر عهده
کاربر است.
diff --git a/src/pages/CafeOwnerPanel.tsx b/src/pages/CafeOwnerPanel.tsx
index 48f3927..bf7b68d 100644
--- a/src/pages/CafeOwnerPanel.tsx
+++ b/src/pages/CafeOwnerPanel.tsx
@@ -1,47 +1,12 @@
import { ReactNode, useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom'
-import BookIcon from '../components/BookIcon'
+import Icon from '../components/Icon'
import { useNow } from '../hooks/useNow'
import { CafeSchedule, fetchCafeSchedules } from '../services/campaignApi'
import { getCafeUuid } from '../utils/cafe'
import { formatPersianNumber } from '../utils/formatNumber'
import { formatMatchLabel } from '../utils/matchCountdown'
-function ChevronIcon({ className = 'h-5 w-5 text-gray-400' }: { className?: string }) {
- return (
-
- )
-}
-
-function ProfileCircleIcon() {
- return (
-
- )
-}
-
-function CalendarIcon() {
- return (
-
- )
-}
-
function PanelRow({ icon, label, onClick }: { icon: ReactNode; label: string; onClick?: () => void }) {
return (
-
+
)
}
@@ -76,11 +41,11 @@ export default function CafeOwnerPanel() {
}
+ icon={
}
label="اطلاعات کافه"
onClick={() => navigate('/owner/register', { state: { step: 2 } })}
/>
-
} label="افزودن رویداد" onClick={() => navigate('/owner/events/new')} />
+
} label="افزودن رویداد" onClick={() => navigate('/owner/events/new')} />
رویدادهای فعال شما
@@ -108,7 +73,7 @@ export default function CafeOwnerPanel() {
}
+ icon={
}
label="مشاهده رزروها"
onClick={() =>
navigate(`/owner/events/${schedule.uuid}/reservations`, {
diff --git a/src/pages/CafeOwnerRegister.tsx b/src/pages/CafeOwnerRegister.tsx
index f5bc445..0193dcf 100644
--- a/src/pages/CafeOwnerRegister.tsx
+++ b/src/pages/CafeOwnerRegister.tsx
@@ -3,7 +3,7 @@ import { useLocation, useNavigate } from "react-router-dom";
import { MapContainer, TileLayer, Marker, ZoomControl, useMapEvents } from "react-leaflet";
import "leaflet/dist/leaflet.css";
import "../utils/leafletIcons";
-import InfoIcon from "../components/InfoIcon";
+import Icon from "../components/Icon";
import {
CafeFeature,
City,
@@ -21,52 +21,6 @@ import { fromE164, toE164 } from "../utils/phone";
// Tehran — default pin until the owner picks their cafe's actual location
const DEFAULT_CAFE_LOCATION = { lat: 35.6892, lng: 51.389 };
-function ArrowIcon({ className = "" }: { className?: string }) {
- return (
-
- );
-}
-
-function ChevronDownIcon({ className = "" }: { className?: string }) {
- return (
-
- );
-}
-
-function CheckIcon() {
- return (
-
- );
-}
-
function StepCircle({
active,
children,
@@ -161,7 +115,10 @@ function CitySelectField({
{selectedCity ? selectedCity.city_name : "شهر کافه را انتخاب کنید"}
-
+
{open && (
@@ -289,7 +246,7 @@ function FeatureChip({
checked ? "bg-[#223D5D]" : "bg-transparent"
}`}
>
- {checked &&
}
+ {checked &&
}
{label}
@@ -424,7 +381,7 @@ export default function CafeOwnerRegister() {
{step === 1 ? (
<>
-
+
لطفاً یک{" "}
نماینده{" "}
@@ -528,7 +485,7 @@ export default function CafeOwnerRegister() {
className="pointer-events-auto flex items-center gap-2 rounded-full bg-[#223D5D] px-6 py-3 font-semibold text-white disabled:opacity-50"
>
{isSubmitting ? "در حال ارسال..." : isEditMode ? "ذخیره تغییرات" : "ادامه"}
- {!isSubmitting && !isEditMode && }
+ {!isSubmitting && !isEditMode && }
diff --git a/src/pages/CafeRegisterFail.tsx b/src/pages/CafeRegisterFail.tsx
index 57b8914..50e7909 100644
--- a/src/pages/CafeRegisterFail.tsx
+++ b/src/pages/CafeRegisterFail.tsx
@@ -1,5 +1,5 @@
import { useNavigate } from 'react-router-dom'
-import FailIcon from '../components/FailIcon'
+import Icon from '../components/Icon'
export default function CafeRegisterFail() {
const navigate = useNavigate()
@@ -9,7 +9,7 @@ export default function CafeRegisterFail() {
-
+
ثبت کافه با خطا مواجه شد. لطفا دوباره تلاش کنید.
diff --git a/src/pages/CafeRegisterSuccess.tsx b/src/pages/CafeRegisterSuccess.tsx
index fb5846c..7ae3955 100644
--- a/src/pages/CafeRegisterSuccess.tsx
+++ b/src/pages/CafeRegisterSuccess.tsx
@@ -1,5 +1,5 @@
import { useNavigate } from 'react-router-dom'
-import SuccessIcon from '../components/SuccessIcon'
+import Icon from '../components/Icon'
export default function CafeRegisterSuccess() {
const navigate = useNavigate()
@@ -9,7 +9,7 @@ export default function CafeRegisterSuccess() {
-
+
کافه شما با موفقیت ثبت شد!
با اضافه کردن ایونت بازیها، کافه شما در کمپین نمایش داده میشود و کاربران میتوانند برای تماشای هر مسابقه در کافه شما، میز رزرو کنند.
diff --git a/src/pages/EventReservations.tsx b/src/pages/EventReservations.tsx
index 75390cb..709e9ca 100644
--- a/src/pages/EventReservations.tsx
+++ b/src/pages/EventReservations.tsx
@@ -1,59 +1,11 @@
import { useEffect, useMemo, useState } from "react";
import { useLocation, useNavigate, useParams } from "react-router-dom";
+import Icon from "../components/Icon";
import { CafeEvent, mockCafeEvents } from "../data/mockCafeEvents";
import { EventReservation, fetchEventReservations } from "../services/campaignApi";
import { getCafeUuid } from "../utils/cafe";
import { formatPersianNumber } from "../utils/formatNumber";
-function ChevronIcon({ className = "" }: { className?: string }) {
- return (
-
- );
-}
-
-function SearchIcon({ className = "" }: { className?: string }) {
- return (
-
- );
-}
-
-function CheckIcon() {
- return (
-
- );
-}
-
function toEnglishDigits(value: string) {
const persianDigits = "۰۱۲۳۴۵۶۷۸۹";
return value.replace(/[۰-۹]/g, (digit) =>
@@ -120,7 +72,7 @@ function ReservationCard({
onClick={onToggle}
className={`flex h-6 w-6 shrink-0 items-center justify-center rounded-md border-2 border-[#223D5D] ${selected ? "bg-[#223D5D]" : "bg-transparent"}`}
>
- {selected && }
+ {selected && }
);
@@ -179,7 +131,7 @@ export default function EventReservations() {
onClick={() => navigate(-1)}
className="mt-4 flex w-full items-center justify-start gap-2 px-4"
>
-
+
رزروهای {event?.matchLabel ?? ""}
@@ -193,7 +145,10 @@ export default function EventReservations() {
placeholder="جستجو"
className="w-full rounded-2xl shadow-[0px_4px_12px_0px_#0000001F] bg-white py-3 pr-6 pl-4 text-right placeholder:font-light placeholder:text-[#999999]"
/>
-
+
diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx
index 2d0e360..c2c61be 100644
--- a/src/pages/Home.tsx
+++ b/src/pages/Home.tsx
@@ -1,6 +1,6 @@
import { useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom'
-import BookIcon from '../components/BookIcon'
+import Icon from '../components/Icon'
import { Cafe, City, fetchCafes, fetchCities, MatchEvent } from '../services/campaignApi'
import { useMatchEvents } from '../hooks/useMatchEvents'
import { formatMatchLabel } from '../utils/matchCountdown'
@@ -10,28 +10,6 @@ function findTehran(cities: City[]): City | undefined {
return cities.find((c) => c.city_name === 'تهران' || c.city_name.toLowerCase() === 'tehran')
}
-function ChevronIcon({ className = '' }: { className?: string }) {
- return (
-
- )
-}
-
-function ChevronDownIcon({ className = '' }: { className?: string }) {
- return (
-
- )
-}
-
// MapIcon/ListIcon — only used by the disabled نقشه/لیست toggle above, commented out together with it
// function MapIcon() {
// return (
@@ -93,7 +71,10 @@ function CitySelectorRow({
className="w-full flex items-center justify-between gap-2 rounded-xl border border-gray-200 bg-white px-4 py-3"
>
{selectedCity?.city_name ?? ''}
-
+
{open && (
@@ -149,7 +130,10 @@ function MatchSelectorRow({
{selectedMatch ? formatMatchLabel(selectedMatch, now) : !hasMatches ? 'بازی فعالی موجود نیست' : ''}
-
+
{open && hasMatches && (
@@ -186,10 +170,10 @@ function MyReservationsRow() {
className="flex w-full items-center justify-between px-4 py-6"
>
-
+
رزروهای شما
-
+
)
}
diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx
index 499092c..7542bab 100644
--- a/src/pages/Login.tsx
+++ b/src/pages/Login.tsx
@@ -1,26 +1,11 @@
import { useEffect, useState } from "react";
import { useLocation, useNavigate } from "react-router-dom";
+import Icon from "../components/Icon";
import { requestOtp } from "../services/authApi";
import { toPersianDigits } from "../utils/formatNumber";
import { toE164 } from "../utils/phone";
import { setUserRole } from "../utils/role";
-function CheckIcon() {
- return (
-
- );
-}
-
export default function Login() {
const navigate = useNavigate();
const location = useLocation();
@@ -98,7 +83,7 @@ export default function Login() {
acceptedTerms ? "bg-[#223D5D]" : "bg-transparent"
}`}
>
- {acceptedTerms &&
}
+ {acceptedTerms &&
}
diff --git a/src/pages/LoginOtp.tsx b/src/pages/LoginOtp.tsx
index ef70874..8943688 100644
--- a/src/pages/LoginOtp.tsx
+++ b/src/pages/LoginOtp.tsx
@@ -1,5 +1,6 @@
import { useEffect, useRef, useState } from 'react'
import { useLocation, useNavigate } from 'react-router-dom'
+import Icon from '../components/Icon'
import { requestOtp, verifyOtp } from '../services/authApi'
import { fetchMyCafes } from '../services/campaignApi'
import { storeAuthTokens } from '../utils/authToken'
@@ -17,19 +18,6 @@ interface OTPCredential extends Credential {
code: string
}
-function EditIcon({ className = '' }: { className?: string }) {
- return (
-
- )
-}
-
function formatCountdown(seconds: number) {
const mm = String(Math.floor(seconds / 60)).padStart(2, '0')
const ss = String(seconds % 60).padStart(2, '0')
@@ -195,7 +183,7 @@ export default function LoginOtp() {
{phone}
diff --git a/src/pages/MyReservations.tsx b/src/pages/MyReservations.tsx
index 643b2e0..3e14bd7 100644
--- a/src/pages/MyReservations.tsx
+++ b/src/pages/MyReservations.tsx
@@ -1,8 +1,7 @@
import { useEffect, useState } from 'react'
import { createPortal } from 'react-dom'
import { useNavigate } from 'react-router-dom'
-import InfoIcon from '../components/InfoIcon'
-import SuccessIcon from '../components/SuccessIcon'
+import Icon from '../components/Icon'
import { fetchMyReservationByUuid, fetchMyReservations, MyReservation } from '../services/campaignApi'
import { formatPersianNumber } from '../utils/formatNumber'
@@ -16,14 +15,6 @@ function formatReservationDateTime(iso: string): string {
}).format(new Date(iso))
}
-function ChevronIcon({ className = '' }: { className?: string }) {
- return (
-
- )
-}
-
function MyReservationCard({ reservation, onClick }: { reservation: MyReservation; onClick: () => void }) {
return (