refactor: remove unused icons and dependencies
- Deleted several unused icon components including AddDocumentIcon, ArrowRightIcon, AttachIcon, and others to clean up the codebase. - Removed the 'arcaptcha-react' package from package.json and next.config.js as it is no longer needed. - This cleanup helps improve project maintainability and reduces bundle size.
This commit is contained in:
parent
f7c65cbfeb
commit
840c328819
@ -1,21 +0,0 @@
|
|||||||
export default function AddDocumentIcon({ className = 'size-6' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 18 20"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M18 11C18 14.7497 18 16.6246 17.0451 17.9389C16.7367 18.3634 16.3634 18.7367 15.9389 19.0451C14.6246 20 12.7497 20 9 20C5.25027 20 3.3754 20 2.06107 19.0451C1.6366 18.7367 1.26331 18.3634 0.954914 17.9389C0 16.6246 0 14.7497 0 11V9C0 8.16106 0 7.41596 0.0106945 6.75L0.0808201 6.75C0.932837 6.75007 1.45182 6.75011 1.8995 6.67921C4.35988 6.28952 6.28952 4.35988 6.67921 1.8995C6.75011 1.45182 6.75007 0.932837 6.75 0.0808201L6.75 0.0106945C7.41596 0 8.16106 0 9 0C12.7497 0 14.6246 0 15.9389 0.954914C16.3634 1.26331 16.7367 1.6366 17.0451 2.06107C18 3.3754 18 5.25027 18 9V11ZM8.25 8C8.25 7.58579 8.58579 7.25 9 7.25C9.41421 7.25 9.75 7.58579 9.75 8V10.25H12C12.4142 10.25 12.75 10.5858 12.75 11C12.75 11.4142 12.4142 11.75 12 11.75H9.75V14C9.75 14.4142 9.41421 14.75 9 14.75C8.58579 14.75 8.25 14.4142 8.25 14V11.75H6C5.58579 11.75 5.25 11.4142 5.25 11C5.25 10.5858 5.58579 10.25 6 10.25H8.25V8Z"
|
|
||||||
fill="currentColor"
|
|
||||||
fillRule="evenodd"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M1.66485 5.19768C1.35646 5.24652 0.975676 5.24987 0.0653362 5.25C0.159744 3.81037 0.390566 2.83783 0.954914 2.06107C1.26331 1.6366 1.6366 1.26331 2.06107 0.954914C2.83783 0.390566 3.81037 0.159744 5.25 0.0653362C5.24987 0.975676 5.24652 1.35645 5.19768 1.66485C4.90965 3.48339 3.48339 4.90965 1.66485 5.19768Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
export default function ArrowRightIcon({ className = 'size-6' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
aria-hidden
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M18 12.0001C17.9951 11.474 17.7832 10.971 17.41 10.6001L13.12 6.30007C12.9326 6.11382 12.6792 6.00928 12.415 6.00928C12.1508 6.00928 11.8974 6.11382 11.71 6.30007C11.6163 6.39303 11.5419 6.50363 11.4911 6.62549C11.4403 6.74735 11.4142 6.87806 11.4142 7.01007C11.4142 7.14208 11.4403 7.27279 11.4911 7.39465C11.5419 7.5165 11.6163 7.62711 11.71 7.72007L15 11.0001H5C4.73478 11.0001 4.48043 11.1054 4.29289 11.293C4.10536 11.4805 4 11.7348 4 12.0001C4 12.2653 4.10536 12.5196 4.29289 12.7072C4.48043 12.8947 4.73478 13.0001 5 13.0001H15L11.71 16.2901C11.5217 16.477 11.4154 16.7312 11.4144 16.9965C11.4135 17.2619 11.518 17.5168 11.705 17.7051C11.892 17.8934 12.1461 17.9997 12.4115 18.0006C12.6768 18.0016 12.9317 17.897 13.12 17.7101L17.41 13.4101C17.7856 13.0367 17.9978 12.5296 18 12.0001Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
export default function AttachIcon({ className = 'size-6' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M14.7084 3.05518C15.323 2.74964 16.0454 2.65873 16.7604 2.85032C18.3163 3.26723 19.2397 4.86655 18.8228 6.42249L16.4503 15.2768C16.0334 16.8328 14.434 17.7561 12.8781 17.3392C11.3222 16.9223 10.3988 15.323 10.8157 13.767L11.7647 10.2253C11.8719 9.8252 11.6345 9.41395 11.2344 9.30674C10.8343 9.19954 10.423 9.43698 10.3158 9.83708L9.36682 13.3788C8.7355 15.7349 10.1337 18.1568 12.4899 18.7881C14.846 19.4194 17.2678 18.0212 17.8992 15.665L20.2717 6.81072C20.903 4.45458 19.5048 2.03275 17.1486 1.40143C16.0672 1.11165 14.9701 1.24999 14.0407 1.71198C13.4708 1.99527 12.9628 2.4007 12.5583 2.90504C12.2991 3.22815 12.3509 3.70019 12.6741 3.95936C12.9972 4.21853 13.4692 4.1667 13.7284 3.84358C13.9949 3.51125 14.3307 3.24292 14.7084 3.05518Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M8.22299 9.2763C8.6399 7.72036 10.2392 6.79699 11.7952 7.21391C13.3511 7.63082 14.2745 9.23013 13.8576 10.7861L12.9086 14.3278C12.8013 14.7279 13.0388 15.1392 13.4389 15.2464C13.839 15.3536 14.2502 15.1161 14.3574 14.716L15.3064 11.1743C15.9378 8.81816 14.5395 6.39634 12.1834 5.76502C9.82725 5.13369 7.40542 6.53193 6.7741 8.88807L4.40159 17.7424C3.77026 20.0985 5.1685 22.5204 7.52465 23.1517C8.6061 23.4415 9.70319 23.3031 10.6326 22.8411C11.2024 22.5578 11.7105 22.1524 12.115 21.6481C12.3742 21.325 12.3223 20.8529 11.9992 20.5937C11.6761 20.3346 11.2041 20.3864 10.9449 20.7095C10.6783 21.0419 10.3425 21.3102 9.96485 21.4979C9.35022 21.8035 8.62787 21.8944 7.91287 21.7028C6.35693 21.2859 5.43357 19.6866 5.85048 18.1306L8.22299 9.2763Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
export default function AwardIcon({ className = 'h-[15px] w-[10px]' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 10 15"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M3.25336 3.81088C3.87839 3.81088 4.41789 3.39599 4.60364 2.80546C4.73175 2.39818 5.26825 2.39818 5.39636 2.80546C5.58211 3.396 6.12161 3.81088 6.74664 3.81088C6.94002 3.81088 7.08433 3.92981 7.143 4.11634C7.20203 4.30401 7.15381 4.50118 6.98625 4.62693C6.49069 4.99886 6.29086 5.64927 6.47584 6.23738C6.54414 6.4545 6.46241 6.64042 6.3191 6.74797C6.17813 6.85377 6.0016 6.86935 5.83987 6.74797C5.3402 6.37296 4.6598 6.37296 4.16013 6.74797C3.9984 6.86935 3.82187 6.85377 3.6809 6.74797C3.53759 6.64042 3.45586 6.4545 3.52416 6.23738C3.70914 5.64927 3.50931 4.99886 3.01375 4.62693C2.84619 4.50118 2.79797 4.30401 2.857 4.11634C2.91567 3.92981 3.05998 3.81088 3.25336 3.81088Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M5 10C7.76142 10 10 7.76142 10 5C10 2.23858 7.76142 0 5 0C2.23858 0 0 2.23858 0 5C0 7.76142 2.23858 10 5 10ZM6.35028 2.50541C5.92862 1.16486 4.07138 1.16486 3.64972 2.50541C3.5896 2.69654 3.42396 2.81088 3.25336 2.81088C1.84732 2.81088 1.3386 4.62002 2.41348 5.42673C2.5616 5.5379 2.63111 5.74378 2.57023 5.93733C2.36364 6.59412 2.62861 7.20852 3.08064 7.54778C3.53501 7.88878 4.20245 7.96651 4.76039 7.54777C4.9044 7.43969 5.0956 7.43969 5.23961 7.54778C5.79755 7.96651 6.46499 7.88878 6.91936 7.54778C7.37139 7.20852 7.63636 6.59412 7.42977 5.93733C7.36889 5.74378 7.4384 5.5379 7.58651 5.42673C8.6614 4.62002 8.15268 2.81088 6.74664 2.81088C6.57604 2.81088 6.4104 2.69654 6.35028 2.50541Z"
|
|
||||||
fill="currentColor"
|
|
||||||
fillRule="evenodd"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M5 11C6.53671 11 7.93849 10.4223 9 9.47221V12.5858C9 13.6286 9 14.15 8.66735 14.2988C8.33469 14.4476 7.92759 14.1082 7.11338 13.4296L6.48752 12.9079C5.77769 12.3163 5.42277 12.0204 5 12.0204C4.57723 12.0204 4.22231 12.3163 3.51248 12.9079L2.88662 13.4296C2.07241 14.1082 1.66531 14.4476 1.33265 14.2988C1 14.15 1 13.6286 1 12.5858V9.47221C2.06151 10.4223 3.46329 11 5 11Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
export default function BookmarkFillIcon({ className = 'size-6' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
className={className}
|
|
||||||
fill="currentColor"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path d="M6 2.25A2.75 2.75 0 0 0 3.25 5v16a.75.75 0 0 0 1.16.628L12 16.66l7.59 4.968A.75.75 0 0 0 20.75 21V5A2.75 2.75 0 0 0 18 2.25H6Z" />
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,29 +0,0 @@
|
|||||||
export default function CalendarSecondary({ className = 'size-6' }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 20 20"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M6.25 3.44396C5.38215 3.54687 4.74558 3.74555 4.21756 4.12918C3.86383 4.38618 3.55276 4.69725 3.29576 5.05098C2.5 6.14625 2.5 7.70864 2.5 10.8334C2.5 13.9582 2.5 15.5206 3.29576 16.6159C3.55276 16.9696 3.86383 17.2807 4.21756 17.5377C5.31283 18.3334 6.87522 18.3334 10 18.3334C10.6991 18.3334 11.32 18.3334 11.875 18.3245L11.875 18.2661C11.8749 17.5561 11.8749 17.1236 11.934 16.7505C12.2587 14.7002 13.8668 13.0921 15.9171 12.7674C16.2901 12.7083 16.7226 12.7084 17.4326 12.7084L17.4911 12.7084C17.5 12.1535 17.5 11.5328 17.5 10.8338C17.5 7.70902 17.5 6.14625 16.7042 5.05098C16.4472 4.69725 16.1362 4.38618 15.7824 4.12918C15.2544 3.74555 14.6178 3.54687 13.75 3.44396V4.16675C13.75 4.8571 13.1904 5.41675 12.5 5.41675C11.8096 5.41675 11.25 4.8571 11.25 4.16675V3.33575C10.8633 3.33341 10.4477 3.33341 10 3.33341C9.55234 3.33341 9.13675 3.33341 8.75 3.33575V4.16675C8.75 4.8571 8.19036 5.41675 7.5 5.41675C6.80964 5.41675 6.25 4.8571 6.25 4.16675V3.44396ZM5.83333 8.33341C6.29357 8.33341 6.66667 7.96032 6.66667 7.50008C6.66667 7.03984 6.29357 6.66675 5.83333 6.66675C5.3731 6.66675 5 7.03984 5 7.50008C5 7.96032 5.3731 8.33341 5.83333 8.33341ZM6.66667 10.8334C6.66667 11.2937 6.29357 11.6667 5.83333 11.6667C5.3731 11.6667 5 11.2937 5 10.8334C5 10.3732 5.3731 10.0001 5.83333 10.0001C6.29357 10.0001 6.66667 10.3732 6.66667 10.8334ZM10 8.33341C10.4602 8.33341 10.8333 7.96032 10.8333 7.50008C10.8333 7.03984 10.4602 6.66675 10 6.66675C9.53976 6.66675 9.16667 7.03984 9.16667 7.50008C9.16667 7.96032 9.53976 8.33341 10 8.33341ZM10.8333 10.8334C10.8333 11.2937 10.4602 11.6667 10 11.6667C9.53976 11.6667 9.16667 11.2937 9.16667 10.8334C9.16667 10.3732 9.53976 10.0001 10 10.0001C10.4602 10.0001 10.8333 10.3732 10.8333 10.8334ZM10 15.0001C10.4602 15.0001 10.8333 14.627 10.8333 14.1667C10.8333 13.7065 10.4602 13.3334 10 13.3334C9.53976 13.3334 9.16667 13.7065 9.16667 14.1667C9.16667 14.627 9.53976 15.0001 10 15.0001ZM15 7.50008C15 7.96032 14.6269 8.33341 14.1667 8.33341C13.7064 8.33341 13.3333 7.96032 13.3333 7.50008C13.3333 7.03984 13.7064 6.66675 14.1667 6.66675C14.6269 6.66675 15 7.03984 15 7.50008ZM14.1667 11.6667C14.6269 11.6667 15 11.2937 15 10.8334C15 10.3732 14.6269 10.0001 14.1667 10.0001C13.7064 10.0001 13.3333 10.3732 13.3333 10.8334C13.3333 11.2937 13.7064 11.6667 14.1667 11.6667ZM6.66667 14.1667C6.66667 14.627 6.29357 15.0001 5.83333 15.0001C5.3731 15.0001 5 14.627 5 14.1667C5 13.7065 5.3731 13.3334 5.83333 13.3334C6.29357 13.3334 6.66667 13.7065 6.66667 14.1667Z"
|
|
||||||
fill="currentColor"
|
|
||||||
fillRule="evenodd"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M17.4456 13.9584C16.6869 13.9585 16.3696 13.9613 16.1126 14.002C14.5972 14.242 13.4086 15.4306 13.1686 16.946C13.1279 17.203 13.1251 17.5203 13.125 18.279C14.3247 18.2003 15.1351 18.0079 15.7824 17.5377C16.1362 17.2807 16.4472 16.9696 16.7042 16.6159C17.1745 15.9686 17.3669 15.1581 17.4456 13.9584Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M8.125 1.66675C8.125 1.32157 7.84518 1.04175 7.5 1.04175C7.15482 1.04175 6.875 1.32157 6.875 1.66675V4.16675C6.875 4.51193 7.15482 4.79175 7.5 4.79175C7.84518 4.79175 8.125 4.51193 8.125 4.16675V1.66675Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M13.125 1.66675C13.125 1.32157 12.8452 1.04175 12.5 1.04175C12.1548 1.04175 11.875 1.32157 11.875 1.66675V4.16675C11.875 4.51193 12.1548 4.79175 12.5 4.79175C12.8452 4.79175 13.125 4.51193 13.125 4.16675V1.66675Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
export default function ClockIcon({ className = 'size-6' }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 20 20"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M5.32025 2.14494C5.57061 1.94466 5.6112 1.57934 5.41092 1.32898C5.21063 1.07862 4.84531 1.03803 4.59495 1.23832L2.65987 2.78638C2.40952 2.98667 2.36893 3.35198 2.56921 3.60234C2.7695 3.8527 3.13482 3.89329 3.38517 3.693L5.32025 2.14494Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M15.3827 1.23832C15.1323 1.03803 14.767 1.07862 14.5667 1.32898C14.3664 1.57934 14.407 1.94466 14.6574 2.14494L16.5924 3.693C16.8428 3.89329 17.2081 3.8527 17.4084 3.60234C17.6087 3.35198 17.5681 2.98667 17.3177 2.78638L15.3827 1.23832Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M9.98881 1.69163C5.39334 1.69163 1.66797 5.417 1.66797 10.0125C1.66797 14.6079 5.39334 18.3333 9.98881 18.3333C14.5843 18.3333 18.3096 14.6079 18.3096 10.0125C18.3096 5.417 14.5843 1.69163 9.98881 1.69163ZM10.5693 6.14231C10.5693 5.8217 10.3094 5.56179 9.98881 5.56179C9.66819 5.56179 9.40829 5.8217 9.40829 6.14231V10.0125C9.40836 10.5643 10.0755 10.8407 10.4657 10.4505L12.0413 8.8749C12.268 8.64819 12.268 8.28062 12.0413 8.05392C11.8146 7.82721 11.447 7.82721 11.2203 8.05392L10.5693 8.70488V6.14231Z"
|
|
||||||
fill="currentColor"
|
|
||||||
fillRule="evenodd"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
export default function CloseSquareIcon({ className = 'size-[12px]' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 12 12"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M0.63661 1.37405C0 2.25027 0 3.50018 0 6C0 8.49982 0 9.74973 0.63661 10.626C0.842209 10.9089 1.09107 11.1578 1.37405 11.3634C2.25027 12 3.50018 12 6 12C8.49982 12 9.74973 12 10.626 11.3634C10.9089 11.1578 11.1578 10.9089 11.3634 10.626C12 9.74973 12 8.49982 12 6C12 3.50018 12 2.25027 11.3634 1.37405C11.1578 1.09107 10.9089 0.842209 10.626 0.63661C9.74973 0 8.49982 0 6 0C3.50018 0 2.25027 0 1.37405 0.63661C1.09107 0.842209 0.842209 1.09107 0.63661 1.37405ZM4.93933 4.394C4.74407 4.19873 4.42748 4.19873 4.23222 4.394C4.03696 4.58926 4.03696 4.90584 4.23222 5.1011L5.29288 6.16176L4.23222 7.22242C4.03696 7.41768 4.03696 7.73427 4.23222 7.92953C4.42748 8.12479 4.74407 8.12479 4.93933 7.92953L5.99999 6.86887L7.06065 7.92953C7.25591 8.12479 7.57249 8.12479 7.76776 7.92953C7.96302 7.73427 7.96302 7.41768 7.76776 7.22242L6.7071 6.16176L7.76776 5.1011C7.96302 4.90584 7.96302 4.58926 7.76776 4.394C7.57249 4.19873 7.25591 4.19873 7.06065 4.394L5.99999 5.45466L4.93933 4.394Z"
|
|
||||||
fill="currentColor"
|
|
||||||
fillRule="evenodd"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,182 +0,0 @@
|
|||||||
import type { ReactNode, SVGProps } from 'react'
|
|
||||||
|
|
||||||
type IconProps = SVGProps<SVGSVGElement>
|
|
||||||
|
|
||||||
const baseProps = (className?: string): IconProps => ({
|
|
||||||
className,
|
|
||||||
fill: 'none',
|
|
||||||
height: 24,
|
|
||||||
viewBox: '0 0 24 24',
|
|
||||||
width: 24,
|
|
||||||
xmlns: 'http://www.w3.org/2000/svg',
|
|
||||||
'aria-hidden': true,
|
|
||||||
})
|
|
||||||
|
|
||||||
const InstagramChannelIcon = ({ className }: { className?: string }) => (
|
|
||||||
<svg {...baseProps(className)}>
|
|
||||||
<rect
|
|
||||||
fill="currentColor"
|
|
||||||
height="18"
|
|
||||||
opacity="0.15"
|
|
||||||
rx="5"
|
|
||||||
width="18"
|
|
||||||
x="3"
|
|
||||||
y="3"
|
|
||||||
/>
|
|
||||||
<rect
|
|
||||||
height="14"
|
|
||||||
rx="4"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeWidth="1.75"
|
|
||||||
width="14"
|
|
||||||
x="5"
|
|
||||||
y="5"
|
|
||||||
/>
|
|
||||||
<circle
|
|
||||||
cx="12"
|
|
||||||
cy="12"
|
|
||||||
r="3.25"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeWidth="1.75"
|
|
||||||
/>
|
|
||||||
<circle
|
|
||||||
cx="16.35"
|
|
||||||
cy="7.65"
|
|
||||||
fill="currentColor"
|
|
||||||
r="1"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
|
|
||||||
const TelegramChannelIcon = ({ className }: { className?: string }) => (
|
|
||||||
<svg {...baseProps(className)}>
|
|
||||||
<circle
|
|
||||||
cx="12"
|
|
||||||
cy="12"
|
|
||||||
fill="currentColor"
|
|
||||||
opacity="0.15"
|
|
||||||
r="9"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M7.2 11.9 16.4 7.8c.45-.2.9.12.74.74l-1.7 8.05c-.12.55-.55.68-.98.42l-2.45-1.8-1.18 1.14c-.13.13-.24.24-.49.24l.18-2.55 4.62-4.17c.2-.18-.04-.28-.3-.1l-5.7 3.6-2.46-.77c-.53-.16-.54-.53.12-.8Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
|
|
||||||
const TwitterChannelIcon = ({ className }: { className?: string }) => (
|
|
||||||
<svg {...baseProps(className)}>
|
|
||||||
<circle
|
|
||||||
cx="12"
|
|
||||||
cy="12"
|
|
||||||
fill="currentColor"
|
|
||||||
opacity="0.15"
|
|
||||||
r="9"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M7 7.5h2.35l2.3 3.2L14.3 7.5H17l-3.55 4.2L17 16.5h-2.35l-2.5-3.45L9.4 16.5H7l3.75-4.45L7 7.5Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
|
|
||||||
const LinkedinChannelIcon = ({ className }: { className?: string }) => (
|
|
||||||
<svg {...baseProps(className)}>
|
|
||||||
<rect
|
|
||||||
fill="currentColor"
|
|
||||||
height="18"
|
|
||||||
opacity="0.15"
|
|
||||||
rx="4"
|
|
||||||
width="18"
|
|
||||||
x="3"
|
|
||||||
y="3"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M8.2 10.2v6.1H6.1v-6.1h2.1Zm.15-2.15c0 .6-.5 1.1-1.2 1.1s-1.2-.5-1.2-1.1.5-1.1 1.2-1.1 1.2.5 1.2 1.1ZM17.9 16.3h-2.1v-3.2c0-.9-.35-1.5-1.2-1.5-.65 0-1.05.45-1.2.85-.07.15-.05.4-.05.6v3.25h-2.1s.03-5.3 0-5.85h2.1v.85c.3-.45.8-1.1 1.95-1.1 1.4 0 2.45.95 2.45 2.95v3.15Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
|
|
||||||
const YoutubeChannelIcon = ({ className }: { className?: string }) => (
|
|
||||||
<svg {...baseProps(className)}>
|
|
||||||
<rect
|
|
||||||
fill="currentColor"
|
|
||||||
height="14"
|
|
||||||
opacity="0.15"
|
|
||||||
rx="4"
|
|
||||||
width="18"
|
|
||||||
x="3"
|
|
||||||
y="5"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M17.6 8.2c.3.8.4 2.1.4 3.8s-.1 3-.4 3.8c-.2.55-.7.9-1.25 1.05-1.1.25-5.35.25-5.35.25s-4.25 0-5.35-.25A1.7 1.7 0 0 1 4.4 15.8C4.1 15 4 13.7 4 12s.1-3 .4-3.8c.2-.55.7-.9 1.25-1.05C6.75 6.9 11 6.9 11 6.9s4.25 0 5.35.25c.55.15 1.05.5 1.25 1.05ZM10.4 14.35 14.1 12l-3.7-2.35v4.7Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
|
|
||||||
const WebsiteChannelIcon = ({ className }: { className?: string }) => (
|
|
||||||
<svg {...baseProps(className)}>
|
|
||||||
<circle
|
|
||||||
cx="12"
|
|
||||||
cy="12"
|
|
||||||
fill="currentColor"
|
|
||||||
opacity="0.15"
|
|
||||||
r="9"
|
|
||||||
/>
|
|
||||||
<circle
|
|
||||||
cx="12"
|
|
||||||
cy="12"
|
|
||||||
r="7"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeWidth="1.75"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M5 12h14M12 5c1.8 2 2.7 4.3 2.7 7s-.9 5-2.7 7c-1.8-2-2.7-4.3-2.7-7s.9-5 2.7-7Z"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeWidth="1.75"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
|
|
||||||
const SupportPhoneChannelIcon = ({ className }: { className?: string }) => (
|
|
||||||
<svg {...baseProps(className)}>
|
|
||||||
<rect
|
|
||||||
fill="currentColor"
|
|
||||||
height="18"
|
|
||||||
opacity="0.15"
|
|
||||||
rx="4"
|
|
||||||
width="14"
|
|
||||||
x="5"
|
|
||||||
y="3"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M15.2 3.8H8.8c-1.9 0-2.6.7-2.6 2.6v11.2c0 1.9.7 2.6 2.6 2.6h6.4c1.9 0 2.6-.7 2.6-2.6V6.4c0-1.9-.7-2.6-2.6-2.6Zm-3.2 14.3a1.05 1.05 0 1 1 0-2.1 1.05 1.05 0 0 1 0 2.1Zm2.2-11.6H9.8a.7.7 0 0 1 0-1.4h4.4a.7.7 0 0 1 0 1.4Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
|
|
||||||
const CHANNEL_ICONS: Record<string, (props: { className?: string }) => ReactNode> = {
|
|
||||||
instagram: InstagramChannelIcon,
|
|
||||||
telegram: TelegramChannelIcon,
|
|
||||||
twitter: TwitterChannelIcon,
|
|
||||||
linkedin: LinkedinChannelIcon,
|
|
||||||
youtube: YoutubeChannelIcon,
|
|
||||||
website: WebsiteChannelIcon,
|
|
||||||
support_phone: SupportPhoneChannelIcon,
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ContactChannelIconProps {
|
|
||||||
channel: string
|
|
||||||
className?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const ContactChannelIcon = ({ channel, className = 'size-6 text-primary' }: ContactChannelIconProps) => {
|
|
||||||
const Icon = CHANNEL_ICONS[channel] ?? WebsiteChannelIcon
|
|
||||||
|
|
||||||
return <Icon className={className} />
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ContactChannelIcon
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
export default function CopyIcon({ className = 'size-4' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 14 16"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M7.33333 2.66667C7.33333 2.84348 7.40357 3.01305 7.52859 3.13807C7.65362 3.2631 7.82319 3.33333 8 3.33333H10.644C10.5949 2.90045 10.405 2.49569 10.1033 2.18133L8.58067 0.608667C8.24757 0.271032 7.80568 0.0622496 7.33333 0.0193333V2.66667ZM6 2.66667V0H3.33333C2.4496 0.00105857 1.60237 0.352588 0.97748 0.97748C0.352588 1.60237 0.00105857 2.4496 0 3.33333V10C0.00105857 10.8837 0.352588 11.731 0.97748 12.3559C1.60237 12.9807 2.4496 13.3323 3.33333 13.3333H7.33333C8.21706 13.3323 9.06429 12.9807 9.68919 12.3559C10.3141 11.731 10.6656 10.8837 10.6667 10V4.66667H8C7.46957 4.66667 6.96086 4.45595 6.58579 4.08088C6.21071 3.70581 6 3.1971 6 2.66667ZM10 16H4C3.82319 16 3.65362 15.9298 3.5286 15.8047C3.40357 15.6797 3.33333 15.5101 3.33333 15.3333C3.33333 15.1565 3.40357 14.987 3.5286 14.8619C3.65362 14.7369 3.82319 14.6667 4 14.6667H10C10.5304 14.6667 11.0391 14.456 11.4142 14.0809C11.7893 13.7058 12 13.1971 12 12.6667V5.33333C12 5.15652 12.0702 4.98695 12.1953 4.86193C12.3203 4.7369 12.4899 4.66667 12.6667 4.66667C12.8435 4.66667 13.013 4.7369 13.1381 4.86193C13.2631 4.98695 13.3333 5.15652 13.3333 5.33333V12.6667C13.3323 13.5504 12.9807 14.3976 12.3559 15.0225C11.731 15.6474 10.8837 15.9989 10 16Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
/** Orange «؟» mark used on consumer event FAQ rows. */
|
|
||||||
export default function FaqQuestionMarkIcon({ className = 'size-5' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
aria-hidden
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 20 20"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<circle
|
|
||||||
cx="10"
|
|
||||||
cy="10"
|
|
||||||
fill="currentColor"
|
|
||||||
opacity="0.15"
|
|
||||||
r="9"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M10.1 14.6c-.55 0-.9-.35-.9-.88 0-.52.35-.87.9-.87.54 0 .89.35.89.87 0 .53-.35.88-.89.88Zm-.05-2.55c-.42 0-.72-.22-.72-.6 0-.55.28-1.02.78-1.55.52-.55.9-1.02.9-1.55 0-.48-.28-.78-.75-.78-.52 0-.82.35-.85.92h-1.05c.05-1.05.78-1.78 1.95-1.78 1.18 0 1.92.68 1.92 1.62 0 .65-.35 1.18-.95 1.72-.48.45-.72.82-.72 1.25 0 .32-.2.55-.51.55Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,95 +0,0 @@
|
|||||||
export default function FireIcon({ className = 'size-[120px]' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 120 120"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M33.2626 80.6892L60.0001 87.8536L87.0296 80.6109C89.0387 77.8453 90.6315 74.7333 91.6961 71.3433C92.6068 68.4427 93.1618 65.3639 93.1618 62.1666C93.1618 44.2819 78.5195 29.8509 78.5195 29.8509C78.5195 29.8509 79.5282 35.693 78.9006 40.6659C78.2729 45.6389 75.9601 48.6914 75.9601 48.6914C75.9601 48.6914 77.649 40.883 75.4051 35.648C72.8223 29.6222 68.005 26.827 66.1543 21.4017C64.0243 15.1575 67.2161 7.89563 67.2161 7.89563C67.2161 7.89563 56.7184 11.9517 49.1331 22.4194C42.1684 32.0302 44.6406 43.8811 45.8354 48.0478C45.2148 46.508 43.8836 44.0686 41.1775 41.9381C36.8298 38.5153 38.5918 33.2067 38.5918 33.2067C38.5918 33.2067 26.8389 46.3786 26.8389 62.1666C26.8389 66.4528 28.0661 70.7752 29.8543 74.7984C30.7904 76.9059 31.9393 78.8733 33.2626 80.6892Z"
|
|
||||||
fill="#D10028"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M89.3519 68.5308C87.6611 73.9144 84.6391 78.5944 80.7269 82.2998L87.0292 80.6114C89.0383 77.8458 90.6311 74.7337 91.6956 71.3437C92.6064 68.4431 93.1614 65.3644 93.1614 62.167C93.1614 47.5144 83.3373 35.1858 79.7852 31.2065C84.1206 36.7462 90.8177 47.2565 90.8177 59.3545C90.8177 62.5514 90.2631 65.6301 89.3519 68.5308Z"
|
|
||||||
fill="#B7022D"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M79.2046 71.2195C79.2046 60.8264 72.3861 54.1233 68.1411 49.8225C60.5811 42.1631 61.9236 33.4481 61.9236 33.4481C61.9236 33.4481 47.1069 46.1864 44.7786 56.7525C42.5525 66.8578 48.1522 72.4758 48.1522 72.4758C48.1522 72.4758 45.5432 71.4684 43.9203 69.6642C41.8536 67.3659 41.1111 64.5816 41.1111 64.5816C41.1111 64.5816 40.2472 66.6712 41.3797 73.8202C42.1846 78.9009 44.8246 82.7039 47.9225 85.5023C55.4521 92.3039 67.1947 91.6458 74.0193 84.1369C76.9433 80.9194 79.2046 76.6692 79.2046 71.2195Z"
|
|
||||||
fill="#FFA91A"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M47.8609 67.3219C47.47 67.3219 47.1053 67.0758 46.9727 66.6849C46.413 65.0306 46.1289 63.2578 46.1289 61.4161C46.1289 60.0352 46.2902 58.6017 46.6089 57.1556C47.2267 54.3506 48.873 51.0905 51.5017 47.4656C51.8055 47.0466 52.3919 46.9533 52.8109 47.257C53.23 47.5608 53.3233 48.1472 53.0195 48.5663C50.5431 51.9811 49.0023 55.0069 48.4398 57.5588C48.1506 58.8727 48.0039 60.1702 48.0039 61.4161C48.0039 63.053 48.2547 64.6238 48.7488 66.0839C48.9147 66.5742 48.6517 67.1067 48.1614 67.2727C48.062 67.306 47.9603 67.3219 47.8609 67.3219ZM54.5613 45.9919C54.3513 45.9919 54.1398 45.9216 53.9655 45.7777C53.5656 45.4481 53.5094 44.8575 53.8384 44.4581L54.0119 44.2495C54.3447 43.8525 54.9358 43.8005 55.3328 44.1324C55.7298 44.4647 55.7819 45.0563 55.45 45.4533L55.2855 45.6511C55.0994 45.8756 54.8313 45.9919 54.5613 45.9919Z"
|
|
||||||
fill="#FFC91D"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M60.0003 87.8536L74.0646 84.0853C76.9667 80.8739 79.205 76.6411 79.205 71.22C79.205 61.132 72.7817 54.5212 68.5221 50.2087C71.6773 54.1884 74.5175 59.3569 74.5175 66.0637C74.5175 71.5134 72.2562 75.7636 69.3321 78.9806C62.7847 86.1848 51.7123 87.0783 44.1748 81.1326C44.9206 82.29 45.7723 83.3334 46.6812 84.2845L60.0003 87.8536Z"
|
|
||||||
fill="#F79219"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M58.2764 87.3915L60.0004 87.8537L74.0648 84.0854C76.9668 80.874 79.2051 76.6412 79.2051 71.2201C79.2051 63.1941 75.1392 57.3704 71.332 53.1521C74.2954 57.0474 76.8614 62.0326 76.8614 68.4076C76.8614 73.8573 74.6001 78.1074 71.6761 81.3244C68.1154 85.2413 63.217 87.2897 58.2764 87.3915Z"
|
|
||||||
fill="#EF7816"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M48.3053 84.72C47.3514 84.1378 46.4369 83.4647 45.5786 82.6899C45.2359 82.38 44.8998 82.0561 44.5703 81.7214C45.2158 82.6491 45.9302 83.4975 46.682 84.285L48.3053 84.72Z"
|
|
||||||
fill="#EF7816"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M73.5935 5.75439C73.5935 5.75439 69.1502 8.55658 69.2346 13.7569C69.2791 16.5038 70.6821 18.7121 71.7072 21.1585C72.6227 23.3438 72.805 26.6681 72.805 26.6681C72.805 26.6681 75.8491 24.0553 76.1744 18.2602C76.3019 15.9858 75.0982 13.2342 74.47 11.2636C73.4983 8.21299 73.5935 5.75439 73.5935 5.75439Z"
|
|
||||||
fill="#D10028"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M41.3375 30.9277C41.3375 30.9277 37.5767 27.2438 38.7579 22.1673C39.3818 19.4855 42.1662 17.7315 43.9925 15.7998C45.8539 13.831 46.7108 10.2732 46.7108 10.2732C46.7108 10.2732 48.7006 12.7041 47.4476 17.4113C46.6423 20.4371 44.1289 22.6294 43.0976 24.4271C41.5006 27.2101 41.3375 30.9277 41.3375 30.9277Z"
|
|
||||||
fill="#D10028"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M97.4557 105.674C98.5305 101.663 101.419 98.9526 103.909 99.6192L19.9821 77.1309C19.9816 77.1309 19.9816 77.1309 19.9812 77.1304C17.4916 76.4634 14.6023 79.1742 13.5274 83.1853C12.4526 87.1964 13.5996 90.9886 16.0891 91.6556H16.0901L100.016 114.143C97.5279 113.476 96.3813 109.685 97.4557 105.674Z"
|
|
||||||
fill="#7C3108"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M97.2218 110.423L18.4338 89.3123C18.4334 89.3123 18.4334 89.3123 18.4329 89.3123C15.9434 88.6453 14.7968 84.8531 15.8712 80.842C16.1984 79.6209 16.6952 78.5227 17.2962 77.6016C15.6804 78.5447 14.2231 80.5894 13.5274 83.1858C12.4526 87.1969 13.5996 90.9891 16.0891 91.6561H16.0901L100.016 114.144C98.5807 113.759 97.5954 112.331 97.2218 110.423Z"
|
|
||||||
fill="#6D2E03"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M106.498 108.103C107.574 104.091 106.427 100.298 103.938 99.631C101.448 98.9635 98.558 101.674 97.4825 105.686C96.407 109.697 97.5533 113.49 100.043 114.157C102.532 114.825 105.423 112.114 106.498 108.103Z"
|
|
||||||
fill="#F2AD97"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M104.811 100.035C105.945 101.629 106.29 104.334 105.534 107.152C104.46 111.163 101.57 113.874 99.0806 113.207C98.7562 113.12 98.4563 112.978 98.1797 112.791C98.6592 113.466 99.2775 113.946 100.018 114.144C102.508 114.811 105.397 112.101 106.472 108.09C107.407 104.601 106.659 101.28 104.811 100.035Z"
|
|
||||||
fill="#E59076"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M103.969 107.425C104.518 105.375 104.078 103.477 102.985 103.184C101.892 102.891 100.561 104.314 100.011 106.364C99.462 108.413 99.9025 110.311 100.995 110.604C102.088 110.897 103.42 109.474 103.969 107.425Z"
|
|
||||||
fill="#FFD2C0"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M106.471 83.1858C105.397 79.1747 102.507 76.4639 100.018 77.1309L100.017 77.1314L16.0908 99.6192C18.5799 98.9531 21.4688 101.663 22.5436 105.674C23.6185 109.685 22.4719 113.477 19.9829 114.144L103.909 91.6565H103.91C106.4 90.989 107.546 87.1969 106.471 83.1858Z"
|
|
||||||
fill="#995222"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M106.471 83.1858C105.775 80.5894 104.318 78.5447 102.702 77.6016C103.303 78.5231 103.8 79.6209 104.127 80.842C105.202 84.8531 104.055 88.6453 101.566 89.3123C101.565 89.3123 101.565 89.3123 101.565 89.3123L22.7771 110.423C22.4035 112.331 21.4182 113.759 19.9824 114.144L103.909 91.6561H103.91C106.399 90.9891 107.546 87.1969 106.471 83.1858Z"
|
|
||||||
fill="#8C3F0A"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M20.004 114.15C22.4936 113.482 23.6399 109.689 22.5644 105.678C21.4889 101.667 18.5989 98.9562 16.1093 99.6237C13.6198 100.291 12.4734 104.084 13.5489 108.095C14.6244 112.107 17.5145 114.817 20.004 114.15Z"
|
|
||||||
fill="#F2AD97"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M22.5431 105.674C21.9571 103.488 20.8307 101.693 19.5253 100.616C20.4206 101.679 21.1664 103.096 21.6056 104.737C22.6804 108.748 21.5334 112.54 19.0439 113.207C17.9114 113.51 16.6978 113.109 15.6084 112.21C16.9021 113.747 18.5104 114.539 19.9814 114.144C22.4709 113.477 23.6179 109.685 22.5431 105.674Z"
|
|
||||||
fill="#E59076"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M19.0514 110.597C20.1443 110.304 20.5848 108.405 20.0354 106.356C19.486 104.307 18.1547 102.883 17.0618 103.176C15.9689 103.469 15.5284 105.368 16.0778 107.417C16.6272 109.466 17.9585 110.89 19.0514 110.597Z"
|
|
||||||
fill="#FFD2C0"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M18.39 28.856C16.7224 29.3325 15.3904 29.3414 14.3939 28.8826C13.3943 28.4126 12.7335 27.6142 12.4116 26.4874C12.1733 25.6536 12.1476 24.8809 12.3343 24.1694C12.529 23.4435 12.8429 22.7505 13.2759 22.0905C13.7089 21.4305 14.1806 20.7778 14.6908 20.1323C15.3347 19.3146 15.8932 18.4968 16.3665 17.6791C16.8397 16.8614 16.9492 16.0074 16.6948 15.1173C16.4695 14.3285 16.0059 13.815 15.304 13.5768C14.599 13.3273 13.6984 13.3531 12.6022 13.6541C12.1289 13.7893 11.4142 14.1459 10.4581 14.7238C9.49869 15.2904 8.51598 15.9673 7.50993 16.7545L6.02734 12.4614C6.52313 12.1491 7.13641 11.7789 7.86721 11.3507C8.60605 10.908 9.38273 10.4911 10.1972 10.0999C11.0085 9.69751 11.7747 9.39327 12.4959 9.18722C14.7494 8.54331 16.6303 8.49339 18.1386 9.03744C19.655 9.56701 20.6836 10.7783 21.2245 12.6713C21.5722 13.8882 21.6181 15.0086 21.3621 16.0323C21.1175 17.0529 20.7191 17.9833 20.167 18.8236C19.6261 19.6606 19.0772 20.4268 18.5203 21.1222C17.9585 21.8434 17.4821 22.5219 17.0909 23.1577C16.7078 23.779 16.5984 24.377 16.7626 24.9517C16.9364 25.5602 17.2567 25.9135 17.7236 26.0117C18.1904 26.1099 18.6693 26.101 19.1602 25.9851C19.3856 25.9207 19.6866 25.7799 20.0632 25.5625C20.4399 25.3452 20.7699 25.1352 21.0532 24.9323L21.9056 27.3396C21.5112 27.5376 20.9655 27.8032 20.2685 28.1364C19.5796 28.4552 18.9534 28.695 18.39 28.856ZM20.4353 38.2534C19.4324 38.5399 18.5575 38.4852 17.8106 38.0892C17.0718 37.6787 16.5366 36.8932 16.2049 35.7326C15.9409 34.8087 16.0311 34.0151 16.4753 33.3519C16.9196 32.6887 17.6488 32.2122 18.6629 31.9225C19.677 31.6327 20.5422 31.6536 21.2585 31.9852C21.9748 32.3168 22.465 32.9446 22.729 33.8685C23.0606 35.0291 23.0156 35.9804 22.5938 36.7225C22.1801 37.4501 21.4606 37.9604 20.4353 38.2534Z"
|
|
||||||
fill="#CCCCCC"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M97.6548 42.9533L98.205 39.7661C98.6377 37.2602 99.0158 34.8638 99.3393 32.5769C99.6647 30.2784 99.9664 27.7737 100.244 25.0627L105.545 25.9778C105.18 27.675 104.837 29.2865 104.514 30.8124C104.202 32.3403 103.903 33.8702 103.614 35.402C103.328 36.9224 103.036 38.5429 102.739 40.2635L102.158 43.7309L97.6548 42.9533ZM98.6949 47.4675C99.3323 47.8392 99.9162 48.3146 100.446 48.8938C100.977 49.4729 101.446 50.0594 101.855 50.6532L98.6552 53.7933C98.2248 53.2552 97.7463 52.7206 97.2196 52.1897C96.7064 51.6492 96.142 51.1296 95.5265 50.6309L98.6949 47.4675Z"
|
|
||||||
fill="#CCCCCC"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
export default function GoogleMapsLogoIcon({ className = 'size-6' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 28 28"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M16.8325 12.2214L13.9267 16.5126L9.62976 20.7881C8.03168 18.757 6.2866 16.7895 5.22266 14.4098L7.53878 10.8617L11.0911 7.43457C9.90385 8.90189 9.9925 11.06 11.3571 12.4246C12.8171 13.8845 15.1835 13.8845 16.6434 12.4246C16.7092 12.3588 16.7727 12.2908 16.8325 12.2214Z"
|
|
||||||
fill="#ECB72B"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M16.9001 12.1408C18.0978 10.6728 18.0128 8.50726 16.6437 7.13898C15.1838 5.67904 12.8173 5.67904 11.3575 7.13898C11.2962 7.20028 11.2378 7.26312 11.1816 7.32738L13.6322 3.34356L16.957 0.455566C19.4402 1.24164 21.4941 2.99192 22.6799 5.26681L20.2544 9.17784L16.9001 12.1408Z"
|
|
||||||
fill="#5085F7"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M11.0913 7.43462L5.22265 14.41C4.64061 13.1093 4.26223 11.6856 4.22318 10.0607C4.22023 9.96835 4.21875 9.87527 4.21875 9.7822C4.21875 7.39137 5.07652 5.19998 6.50173 3.50073L11.0913 7.43462Z"
|
|
||||||
fill="#DA2F2A"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M11.0917 7.43471L6.50195 3.50055C8.29658 1.3609 10.9896 0 14.001 0C15.0316 0 16.025 0.159469 16.9577 0.455L11.0917 7.43471Z"
|
|
||||||
fill="#4274EB"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M23.7815 9.78174C23.7815 8.1532 23.3835 6.61757 22.6795 5.26685L9.62891 20.7886C11.1116 22.6746 12.4665 24.6159 13.0295 26.9931C13.0476 27.0692 13.067 27.1582 13.0877 27.2582C13.2918 28.2473 14.7081 28.2473 14.9122 27.2582C14.9329 27.1582 14.9523 27.0692 14.9703 26.9931C16.4714 20.6553 23.6004 17.4163 23.7774 10.0609C23.7799 9.96811 23.7815 9.87509 23.7815 9.78174Z"
|
|
||||||
fill="#60A850"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
export default function HeartIcon({ className = 'size-6' }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
height="15"
|
|
||||||
viewBox="0 0 15 15"
|
|
||||||
width="15"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M14.5913 2.04754C15 2.8497 15 3.8998 15 6V6.88816C15 8.15502 15 8.78845 14.8485 9.30514C14.4891 10.5307 13.5307 11.4891 12.3051 11.8485C11.7884 12 11.155 12 9.88816 12H9.47655L9.42773 12.0001C8.66255 12.005 7.91718 12.2438 7.29168 12.6846L7.25191 12.7129L5.29386 14.1115C4.62262 14.591 3.74057 13.8986 4.04693 13.1327C4.26394 12.5902 3.86438 12 3.28006 12H2.82874C1.26647 12 0 10.7335 0 9.17126V6C0 3.8998 0 2.8497 0.408726 2.04754C0.768251 1.34193 1.34193 0.768251 2.04754 0.408726C2.8497 0 3.8998 0 6 0H9C11.1002 0 12.1503 0 12.9525 0.408726C13.6581 0.768251 14.2317 1.34193 14.5913 2.04754ZM8.10025 3.42972C8.72788 3.0316 9.74148 2.65512 10.6168 3.54777C12.6947 5.66676 9.13131 9.75 7.50001 9.75C5.8687 9.75 2.30532 5.66676 4.3832 3.54777C5.25852 2.65513 6.27211 3.0316 6.89973 3.42972C7.25437 3.65468 7.74562 3.65468 8.10025 3.42972Z"
|
|
||||||
fill="currentColor"
|
|
||||||
fillRule="evenodd"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
export default function HeatIcon({ className = 'size-6' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 22 20"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M19.5968 1.68557C18.2693 0.331733 16.7914 -0.0870913 15.4035 0.0145124C14.0531 0.113369 12.837 0.699139 11.9488 1.26257C11.2484 1.70689 10.2514 1.70689 9.55091 1.26257C8.6627 0.699145 7.4466 0.113382 6.09624 0.0145278C4.70834 -0.0870739 3.23046 0.331747 1.9029 1.68557C0.33562 3.28386 -0.156097 5.25689 0.0413567 7.25265C0.236535 9.22542 1.10186 11.2308 2.25598 13.0078C3.41317 14.7896 4.89136 16.3892 6.37433 17.5508C7.82467 18.6868 9.40271 19.5 10.7499 19.5C12.0971 19.5 13.6751 18.6868 15.1254 17.5508C16.6084 16.3892 18.0866 14.7896 19.2438 13.0078C20.3979 11.2308 21.2632 9.22541 21.4584 7.25265C21.6558 5.25688 21.1641 3.28386 19.5968 1.68557ZM12.7523 2.52922C13.5377 2.03097 14.5099 1.58394 15.513 1.51051C16.4785 1.43983 17.5192 1.70923 18.5258 2.73579C19.7291 3.96282 20.1274 5.46987 19.9657 7.10497C19.8016 8.76307 19.0584 10.5393 17.9858 12.1908C16.9163 13.8376 15.5496 15.3132 14.2005 16.3699C12.8188 17.4521 11.5778 18 10.7499 18C9.922 18 8.68093 17.4521 7.29926 16.3699C5.95021 15.3132 4.58348 13.8376 3.51394 12.1908C2.44132 10.5393 1.69812 8.76307 1.53407 7.10497C1.3723 5.46987 1.77067 3.96283 2.9739 2.73579C3.98053 1.70925 5.02119 1.43984 5.98672 1.51052C6.98978 1.58395 7.96197 2.03098 8.74742 2.52922C9.93834 3.28467 11.5614 3.28467 12.7523 2.52922Z"
|
|
||||||
fill="currentColor"
|
|
||||||
fillRule="evenodd"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
export default function HomeFillIcon({ className = 'size-[21px]' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 21 21"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M4.78341 2.96556C7.45023 1.028 8.78364 0.0592252 10.3065 0.00336104C10.4286 -0.00112035 10.5509 -0.00112035 10.6731 0.00336104C12.1959 0.0592252 13.5293 1.028 16.1961 2.96556C18.8629 4.90311 20.1963 5.87189 20.72 7.30291C20.762 7.41771 20.7998 7.534 20.8333 7.65157C21.2508 9.11711 20.7414 10.6846 19.7228 13.8197L18.0018 19.1164C17.7283 19.958 16.944 20.5279 16.0591 20.5279C14.931 20.5279 14.0165 19.6133 14.0165 18.4852V15.7363C14.0165 14.6778 13.1584 13.8197 12.0998 13.8197H8.87967C7.82115 13.8197 6.96304 14.6778 6.96304 15.7363V18.4852C6.96304 19.6133 6.04852 20.5279 4.9204 20.5279C4.03547 20.5279 3.25118 19.958 2.97773 19.1164L1.2567 13.8197C0.238068 10.6846 -0.271248 9.11711 0.146197 7.65157C0.179685 7.534 0.217472 7.41771 0.259483 7.30291C0.783189 5.87189 2.1166 4.90311 4.78341 2.96556Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,56 +0,0 @@
|
|||||||
import { cn } from '@/lib/cn'
|
|
||||||
|
|
||||||
interface HomeHashtagTwoToneIconProps {
|
|
||||||
className?: string
|
|
||||||
/** رنگ لایه اصلی — مثلاً `text-gray-800` */
|
|
||||||
primaryClassName?: string
|
|
||||||
/** رنگ لایه ثانویه — مثلاً `text-primary`؛ پیشفرض opacity-40 مثل Iconsax */
|
|
||||||
secondaryClassName?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function HomeHashtagTwoToneIcon({
|
|
||||||
className = 'size-6',
|
|
||||||
primaryClassName,
|
|
||||||
secondaryClassName,
|
|
||||||
}: HomeHashtagTwoToneIconProps) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
className={primaryClassName}
|
|
||||||
d="M9.02 2.83821L3.63 7.03821C2.73 7.73821 2 9.22821 2 10.3582V17.7682C2 20.0882 3.89 21.9882 6.21 21.9882H17.79C20.11 21.9882 22 20.0882 22 17.7782V10.4982C22 9.28821 21.19 7.73821 20.2 7.04821L14.02 2.71821C12.62 1.73821 10.37 1.78821 9.02 2.83821Z"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
strokeWidth="1.5"
|
|
||||||
/>
|
|
||||||
<g className={cn('opacity-40', secondaryClassName)}>
|
|
||||||
<path
|
|
||||||
d="M10.5 18H13.5C15.15 18 16.5 16.65 16.5 15V12C16.5 10.35 15.15 9 13.5 9H10.5C8.85 9 7.5 10.35 7.5 12V15C7.5 16.65 8.85 18 10.5 18Z"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
strokeWidth="1.5"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M12 9V18"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
strokeWidth="1.5"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M7.5 13.5H16.5"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
strokeWidth="1.5"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
File diff suppressed because one or more lines are too long
@ -1,94 +0,0 @@
|
|||||||
export default function IdentityIcon() {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
fill="none"
|
|
||||||
height="40"
|
|
||||||
viewBox="0 0 26 40"
|
|
||||||
width="26"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M17.4017 37.7484C22.645 34.7408 25.9023 29.1175 25.9023 23.0728V19.4169C23.2444 19.013 20.9773 17.25 19.9459 14.6976C19.5781 13.7873 19.6862 12.7583 20.2348 11.9448C20.7825 11.1328 21.6944 10.648 22.674 10.648H25.9022V7.21936H21.7655C19.1542 7.21936 17.0298 9.34374 17.0298 11.955V18.3355C17.0298 19.8382 16.2812 21.2298 15.0273 22.058L13.8216 22.8544C13.6258 22.9838 13.4008 23.0485 13.1758 23.0485C12.9508 23.0485 12.7258 22.9838 12.5299 22.8544L11.3243 22.058C10.0704 21.2299 9.3218 19.8383 9.3218 18.3355V11.955C9.3218 9.34374 7.19742 7.21936 4.58617 7.21936H7.80821e-05V10.6479H3.22828C4.20789 10.6479 5.11984 11.1327 5.6675 11.9448C6.21617 12.7582 6.32406 13.7873 5.95633 14.6976C4.92508 17.25 2.65797 19.0129 0 19.4168V22.9075C0 29.0475 3.33414 34.7143 8.70125 37.6965L12.5787 39.8509C12.9414 40.0524 13.3902 40.0494 13.7501 39.843L17.4017 37.7484ZM9.92844 33.7274C7.98164 33.7274 6.39781 32.1436 6.39781 30.1968V29.5656C6.39781 27.6188 7.98164 26.035 9.92844 26.035H16.4232C18.37 26.035 19.9538 27.6188 19.9538 29.5656V30.1968C19.9538 32.1436 18.37 33.7274 16.4232 33.7274H9.92844Z"
|
|
||||||
fill="white"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M15.9737 0H9.64258L12.8081 3.16555L15.9737 0Z"
|
|
||||||
fill="white"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M4.58602 4.87555C8.48969 4.87555 11.6655 8.05133 11.6655 11.955V18.3355C11.6655 19.0487 12.0208 19.7092 12.6159 20.1023L13.1758 20.4721L13.7356 20.1023C14.3308 19.7092 14.6861 19.0487 14.6861 18.3355V11.955C14.6861 8.05133 17.8619 4.87555 21.7655 4.87555H25.9023V1.48547C25.9022 0.666406 25.2358 0 24.4167 0H19.2432C19.1963 0.0757813 13.6376 5.65148 13.6376 5.65148C13.4087 5.88031 13.1088 5.99477 12.8089 5.99477C12.509 5.99477 12.2091 5.88039 11.9802 5.65148C11.9802 5.65148 6.42141 0.0757813 6.37453 0H1.48547C0.666328 0 0 0.666406 0 1.48547V4.87555H4.58602Z"
|
|
||||||
fill="url(#paint0_linear_634_5391)"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M3.7243 13.2554C3.65789 13.1569 3.50508 12.9917 3.2282 12.9917H0V17.0333C1.69203 16.6575 3.11297 15.4783 3.7832 13.8195C3.88805 13.5601 3.79133 13.3547 3.7243 13.2554Z"
|
|
||||||
fill="url(#paint1_linear_634_5391)"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M22.1774 13.2554C22.1105 13.3547 22.0137 13.5601 22.1186 13.8195C22.7888 15.4783 24.2097 16.6575 25.9017 17.0333V12.9917H22.6735C22.3966 12.9917 22.2439 13.1569 22.1774 13.2554Z"
|
|
||||||
fill="url(#paint2_linear_634_5391)"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M17.6105 30.1968V29.5656C17.6105 28.9112 17.0781 28.3788 16.4237 28.3788H9.92898C9.27453 28.3788 8.74219 28.9112 8.74219 29.5656V30.1968C8.74219 30.8512 9.27461 31.3835 9.92898 31.3835H16.4237C17.0781 31.3835 17.6105 30.8512 17.6105 30.1968Z"
|
|
||||||
fill="url(#paint3_linear_634_5391)"
|
|
||||||
/>
|
|
||||||
<defs>
|
|
||||||
<linearGradient
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
id="paint0_linear_634_5391"
|
|
||||||
x1="12.9511"
|
|
||||||
x2="12.9511"
|
|
||||||
y1="0"
|
|
||||||
y2="20.4721"
|
|
||||||
>
|
|
||||||
<stop stopColor="white" />
|
|
||||||
<stop
|
|
||||||
offset="1"
|
|
||||||
stopColor="#D3D3D3"
|
|
||||||
/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
id="paint1_linear_634_5391"
|
|
||||||
x1="1.91476"
|
|
||||||
x2="1.91476"
|
|
||||||
y1="12.9917"
|
|
||||||
y2="17.0333"
|
|
||||||
>
|
|
||||||
<stop stopColor="white" />
|
|
||||||
<stop
|
|
||||||
offset="1"
|
|
||||||
stopColor="#BEBEBE"
|
|
||||||
/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
id="paint2_linear_634_5391"
|
|
||||||
x1="23.987"
|
|
||||||
x2="23.987"
|
|
||||||
y1="12.9917"
|
|
||||||
y2="17.0333"
|
|
||||||
>
|
|
||||||
<stop stopColor="white" />
|
|
||||||
<stop
|
|
||||||
offset="1"
|
|
||||||
stopColor="#BEBEBE"
|
|
||||||
/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
id="paint3_linear_634_5391"
|
|
||||||
x1="13.1764"
|
|
||||||
x2="13.1764"
|
|
||||||
y1="28.3788"
|
|
||||||
y2="31.3835"
|
|
||||||
>
|
|
||||||
<stop stopColor="white" />
|
|
||||||
<stop
|
|
||||||
offset="1"
|
|
||||||
stopColor="#BEBEBE"
|
|
||||||
/>
|
|
||||||
</linearGradient>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
export default function InfoIcon({ className = 'size-[15px]' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 15 15"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M7.83333 9.83333C7.83333 10.2015 7.53486 10.5 7.16667 10.5C6.79848 10.5 6.5 10.2015 6.5 9.83333C6.5 9.46514 6.79848 9.16667 7.16667 9.16667C7.53486 9.16667 7.83333 9.46514 7.83333 9.83333Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M7.66667 3.83333C7.66667 3.55719 7.44281 3.33333 7.16667 3.33333C6.89052 3.33333 6.66667 3.55719 6.66667 3.83333V7.83333C6.66667 8.10948 6.89052 8.33333 7.16667 8.33333C7.44281 8.33333 7.66667 8.10948 7.66667 7.83333V3.83333Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M7.16667 0C3.20863 0 0 3.20863 0 7.16667C0 11.1247 3.20863 14.3333 7.16667 14.3333C11.1247 14.3333 14.3333 11.1247 14.3333 7.16667C14.3333 3.20863 11.1247 0 7.16667 0ZM1 7.16667C1 3.76091 3.76091 1 7.16667 1C10.5724 1 13.3333 3.76091 13.3333 7.16667C13.3333 10.5724 10.5724 13.3333 7.16667 13.3333C3.76091 13.3333 1 10.5724 1 7.16667Z"
|
|
||||||
fill="currentColor"
|
|
||||||
fillRule="evenodd"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
export default function LinkIcon({ className = 'size-5' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 20 12"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M5.75 0C2.574 0 0 2.574 0 5.75s2.574 5.75 5.75 5.75a.75.75 0 0 0 0-1.5 4.25 4.25 0 0 1 0-8.5.75.75 0 0 0 0-1.5ZM13.75 0a.75.75 0 0 0 0 1.5 4.25 4.25 0 0 1 0 8.5.75.75 0 0 0 0 1.5 5.75 5.75 0 0 0 0-11.5ZM5.75 5a.75.75 0 0 0 0 1.5h8a.75.75 0 0 0 0-1.5h-8Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
import { cn } from '@/lib/cn'
|
|
||||||
|
|
||||||
interface LoginTwoToneIconProps {
|
|
||||||
className?: string
|
|
||||||
/** رنگ لایه اصلی — مثلاً `text-gray-800` */
|
|
||||||
primaryClassName?: string
|
|
||||||
/** رنگ لایه ثانویه — مثلاً `text-primary`؛ پیشفرض opacity-40 مثل Iconsax */
|
|
||||||
secondaryClassName?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function LoginTwoToneIcon({ className = 'size-6', primaryClassName, secondaryClassName }: LoginTwoToneIconProps) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
className={primaryClassName}
|
|
||||||
d="M8.89844 7.55828C9.20844 3.95828 11.0584 2.48828 15.1084 2.48828H15.2384C19.7084 2.48828 21.4984 4.27828 21.4984 8.74828V15.2683C21.4984 19.7383 19.7084 21.5283 15.2384 21.5283H15.1084C11.0884 21.5283 9.23844 20.0783 8.90844 16.5383"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
strokeWidth="1.5"
|
|
||||||
/>
|
|
||||||
<g className={cn('opacity-40', secondaryClassName)}>
|
|
||||||
<path
|
|
||||||
d="M2 12H14.88"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
strokeWidth="1.5"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M12.6484 8.64844L15.9984 11.9984L12.6484 15.3484"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
strokeWidth="1.5"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
File diff suppressed because one or more lines are too long
@ -1,29 +0,0 @@
|
|||||||
export default function MessageIcon({ className = 'size-[21.5px]' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 21.4997 21.4998"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M18.3358 7.51099C18.0009 5.75204 17.1531 4.07081 15.7938 2.70982C12.1853 -0.903275 6.33425 -0.903275 2.72569 2.70982C1.62489 3.81202 0.65272 5.44355 0.227554 7.25489C-0.200187 9.0772 -0.081596 11.1242 1.07372 12.9856C1.13287 13.0809 1.16946 13.1399 1.1953 13.1841C1.20722 13.2045 1.21349 13.2161 1.21614 13.2211C1.21854 13.2275 1.22003 13.2319 1.2209 13.2347C1.22089 13.238 1.22075 13.2436 1.22019 13.2521C1.21948 13.256 1.21783 13.2647 1.21447 13.2795C1.20592 13.3174 1.19292 13.368 1.16976 13.4574L1.16304 13.4834C1.03035 13.9959 0.921296 14.4172 0.85719 14.7576C0.79266 15.1002 0.755326 15.446 0.823966 15.7837C1.01969 16.7467 1.77151 17.5 2.73447 17.6962C3.07228 17.765 3.41811 17.7276 3.7604 17.6629C4.10045 17.5987 4.52128 17.4895 5.03315 17.3567L5.0591 17.3499C5.14841 17.3268 5.19895 17.3137 5.23673 17.3052C5.25143 17.3018 5.26001 17.3002 5.26398 17.2995C5.27182 17.2989 5.27718 17.2988 5.28052 17.2987C5.28328 17.2996 5.28745 17.3011 5.29327 17.3032C5.29833 17.3059 5.31005 17.3122 5.33059 17.3242C5.3751 17.3502 5.43463 17.3869 5.53045 17.4462C6.15037 17.8298 6.79558 18.0979 7.44919 18.2677C7.69167 18.6054 7.96434 18.9278 8.26704 19.2308C9.15893 20.1239 10.5212 20.9343 12.0386 21.2978C13.5665 21.6637 15.3073 21.5871 16.8825 20.6124C16.9589 20.5651 17.0056 20.5363 17.04 20.5161C17.0675 20.5227 17.1052 20.5324 17.1678 20.5486L17.193 20.5552C17.6113 20.6637 17.9615 20.7546 18.246 20.8084C18.5327 20.8625 18.838 20.8973 19.1419 20.8354C19.987 20.6632 20.6468 20.002 20.8185 19.1571C20.8802 18.8534 20.8456 18.5481 20.7915 18.2612C20.7379 17.9764 20.6471 17.6258 20.5387 17.207L20.5322 17.1818C20.5158 17.1184 20.506 17.0805 20.4995 17.0529C20.5196 17.0187 20.5483 16.9724 20.5956 16.8961C21.5693 15.3274 21.6673 13.6041 21.3088 12.0767C20.9529 10.5603 20.1397 9.19499 19.2163 8.27044C18.9381 7.99187 18.6436 7.73867 18.3358 7.51099ZM14.7325 3.76982C11.7099 0.743394 6.80964 0.743394 3.78702 3.76982C2.87704 4.68094 2.04731 6.06632 1.68786 7.59766C1.331 9.11803 1.4451 10.7395 2.34819 12.1945C2.35673 12.2083 2.3654 12.2222 2.37413 12.2362C2.46023 12.3744 2.55296 12.5233 2.60672 12.6584C2.70209 12.8982 2.73511 13.1152 2.7154 13.3725C2.70432 13.5171 2.66546 13.6661 2.63133 13.7971C2.62813 13.8093 2.62498 13.8214 2.6219 13.8333C2.48084 14.3782 2.38491 14.7504 2.33127 15.0352C2.27698 15.3235 2.28426 15.4375 2.29391 15.485C2.36993 15.859 2.66166 16.1505 3.03397 16.2264C3.08083 16.2359 3.19429 16.2433 3.48211 16.189C3.76643 16.1353 4.13804 16.0393 4.68231 15.898C4.69422 15.8949 4.70632 15.8918 4.71858 15.8886C4.8492 15.8544 4.99811 15.8155 5.1423 15.8044C5.39935 15.7845 5.61495 15.8171 5.85458 15.9121C5.98944 15.9656 6.13878 16.0583 6.27766 16.1446C6.2918 16.1534 6.30582 16.1621 6.31972 16.1707C6.34705 16.1876 6.37444 16.2042 6.40189 16.2205C5.49764 13.5206 6.11883 10.4214 8.26704 8.27044C10.4934 6.0413 13.7376 5.45388 16.5009 6.50716C16.1246 5.50929 15.5353 4.57365 14.7325 3.76982ZM17.2294 8.56521C14.8023 6.92382 11.4766 7.1795 9.32837 9.33044C7.19781 11.4637 6.92847 14.7573 8.52335 17.1829C8.75271 17.5317 9.02093 17.863 9.32837 18.1708C10.0248 18.8681 11.1408 19.5403 12.388 19.839C13.6247 20.1352 14.9348 20.0536 16.0933 19.3368C16.1047 19.3297 16.1165 19.3224 16.1286 19.3149C16.2402 19.2455 16.3742 19.1622 16.4972 19.1134C16.7132 19.0277 16.911 18.9978 17.1427 19.0157C17.2741 19.0259 17.4088 19.0612 17.514 19.0888C17.5245 19.0915 17.5347 19.0942 17.5446 19.0967C17.9946 19.2135 18.2956 19.2912 18.5243 19.3344C18.7565 19.3782 18.8295 19.3682 18.8424 19.3656C19.0969 19.3137 19.2965 19.1144 19.3486 18.8583C19.3513 18.8448 19.3612 18.7714 19.3174 18.5388C19.2743 18.3096 19.1967 18.0082 19.08 17.5577C19.0775 17.5478 19.0748 17.5376 19.0721 17.5271C19.0445 17.4216 19.0093 17.2868 18.9992 17.1551C18.9814 16.9231 19.0117 16.7242 19.0977 16.508C19.1467 16.3848 19.23 16.2512 19.2993 16.1402C19.3067 16.1282 19.314 16.1165 19.3211 16.1051C20.0426 14.9427 20.1361 13.6449 19.8485 12.4195C19.5583 11.1831 18.8876 10.0639 18.155 9.33044C17.8655 9.04062 17.5553 8.78565 17.2294 8.56521Z"
|
|
||||||
fill="#333A44"
|
|
||||||
fillRule="evenodd"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M11.7498 13.75C11.7498 14.3023 11.3021 14.75 10.7498 14.75C10.1976 14.75 9.74985 14.3023 9.74985 13.75C9.74985 13.1977 10.1976 12.75 10.7498 12.75C11.3021 12.75 11.7498 13.1977 11.7498 13.75Z"
|
|
||||||
fill="#333A44"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M14.7498 13.75C14.7498 14.3023 14.3021 14.75 13.7498 14.75C13.1976 14.75 12.7498 14.3023 12.7498 13.75C12.7498 13.1977 13.1976 12.75 13.7498 12.75C14.3021 12.75 14.7498 13.1977 14.7498 13.75Z"
|
|
||||||
fill="#333A44"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M17.7498 13.75C17.7498 14.3023 17.3021 14.75 16.7498 14.75C16.1976 14.75 15.7498 14.3023 15.7498 13.75C15.7498 13.1977 16.1976 12.75 16.7498 12.75C17.3021 12.75 17.7498 13.1977 17.7498 13.75Z"
|
|
||||||
fill="#333A44"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
import { cn } from '@/lib/cn'
|
|
||||||
|
|
||||||
interface MessagesTwoToneIconProps {
|
|
||||||
className?: string
|
|
||||||
/** رنگ لایه اصلی — مثلاً `text-gray-800` */
|
|
||||||
primaryClassName?: string
|
|
||||||
/** رنگ لایه ثانویه — مثلاً `text-primary`؛ پیشفرض opacity-40 مثل Iconsax */
|
|
||||||
secondaryClassName?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function MessagesTwoToneIcon({ className = 'size-6', primaryClassName, secondaryClassName }: MessagesTwoToneIconProps) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
className={cn('opacity-40', secondaryClassName)}
|
|
||||||
d="M18.4698 16.83L18.8598 19.99C18.9598 20.82 18.0698 21.4 17.3598 20.97L13.1698 18.48C12.7098 18.48 12.2599 18.45 11.8199 18.39C12.5599 17.52 12.9998 16.42 12.9998 15.23C12.9998 12.39 10.5398 10.09 7.49985 10.09C6.33985 10.09 5.26985 10.42 4.37985 11C4.34985 10.75 4.33984 10.5 4.33984 10.24C4.33984 5.68999 8.28985 2 13.1698 2C18.0498 2 21.9998 5.68999 21.9998 10.24C21.9998 12.94 20.6098 15.33 18.4698 16.83Z"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
strokeWidth="1.5"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
className={primaryClassName}
|
|
||||||
d="M13 15.2298C13 16.4198 12.56 17.5198 11.82 18.3898C10.83 19.5898 9.26 20.3598 7.5 20.3598L4.89 21.9098C4.45 22.1798 3.89 21.8098 3.95 21.2998L4.2 19.3298C2.86 18.3998 2 16.9098 2 15.2298C2 13.4698 2.94 11.9198 4.38 10.9998C5.27 10.4198 6.34 10.0898 7.5 10.0898C10.54 10.0898 13 12.3898 13 15.2298Z"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
strokeWidth="1.5"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
export default function MuteIcon({ className = 'size-6' }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
width="24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M22.5303 1.46967C22.8232 1.76256 22.8232 2.23744 22.5303 2.53033L2.53033 22.5303C2.23744 22.8232 1.76256 22.8232 1.46967 22.5303C1.17678 22.2374 1.17678 21.7626 1.46967 21.4697L5.19121 17.7481C4.30803 17.7386 3.63551 17.6859 3.02496 17.4034C2.33016 17.082 1.66141 16.4527 1.29828 15.7788C0.905663 15.0501 0.859593 14.2881 0.794087 13.2045C0.791489 13.1615 0.788861 13.1181 0.786179 13.0741C0.763733 12.7058 0.75 12.3416 0.75 12C0.75 11.6585 0.763733 11.2943 0.786179 10.926C0.788861 10.882 0.791489 10.8385 0.794087 10.7955C0.859593 9.712 0.905663 8.94996 1.29828 8.22128C1.66141 7.54732 2.33016 6.9181 3.02496 6.59664C3.77659 6.24889 4.62215 6.24933 5.83906 6.24998C5.89202 6.25 5.94569 6.25003 6.00008 6.25003C6.5366 6.25003 6.71956 6.24762 6.89132 6.21862C7.0752 6.18757 7.25452 6.13378 7.42513 6.05848C7.58448 5.98815 7.73856 5.88944 8.18647 5.59411L8.45324 5.41822C9.68412 4.60663 10.6712 3.95576 11.4848 3.56055C12.3108 3.15928 13.1241 2.9361 13.9423 3.21531C14.2142 3.30809 14.4759 3.44128 14.7109 3.60646C15.3503 4.05581 15.6552 4.74135 15.827 5.52977C15.9146 5.93197 15.9746 6.39532 16.0205 6.91886L21.4697 1.46967C21.7626 1.17678 22.2374 1.17678 22.5303 1.46967ZM14.6104 8.32893C14.5528 7.22797 14.4889 6.43466 14.3614 5.84912C14.2254 5.22532 14.0443 4.97136 13.8485 4.8337C13.7297 4.75023 13.5952 4.68181 13.4578 4.63492C13.2087 4.54989 12.8525 4.56376 12.1402 4.90978C11.426 5.25675 10.5209 5.85164 9.2311 6.70206L9.01216 6.84641C8.9955 6.85739 8.97906 6.86824 8.96284 6.87894C8.58264 7.12973 8.31931 7.30343 8.03077 7.43078C7.74641 7.55627 7.44756 7.64593 7.14108 7.69768C6.83009 7.7502 6.51464 7.75013 6.05917 7.75004C6.03973 7.75004 6.02004 7.75003 6.00008 7.75003C4.55641 7.75003 4.06911 7.76631 3.6548 7.958C3.25445 8.14323 2.82804 8.54443 2.6188 8.93278C2.40052 9.33789 2.36045 9.75309 2.2834 11.0173C2.26225 11.3642 2.25 11.6968 2.25 12C2.25 12.3033 2.26225 12.6358 2.2834 12.9828C2.36045 14.247 2.40052 14.6622 2.6188 15.0673C2.82804 15.4556 3.25445 15.8568 3.6548 16.0421C4.06911 16.2338 4.55641 16.25 6.00008 16.25C6.02004 16.25 6.03973 16.25 6.05917 16.25C6.29891 16.25 6.49985 16.2499 6.68178 16.2576L14.6104 8.32893ZM20.2645 6.3164C20.642 6.14605 21.0862 6.31403 21.2565 6.6916C21.7236 7.72674 22.25 9.45958 22.25 12C22.25 14.1916 21.8582 15.7829 21.45 16.8442C21.2462 17.374 21.0394 17.7692 20.8775 18.039C20.7966 18.1738 20.727 18.2772 20.6748 18.3504C20.6486 18.3869 20.6269 18.4159 20.6102 18.4375C20.6018 18.4483 20.5948 18.4572 20.5891 18.4643L20.5816 18.4736L20.5786 18.4772L20.5773 18.4788C20.577 18.4791 20.5762 18.4801 20 18L20.5762 18.4801C20.311 18.7983 19.8381 18.8413 19.5199 18.5762C19.2032 18.3123 19.1591 17.8426 19.42 17.5244C19.4207 17.5237 19.4218 17.5222 19.4235 17.52C19.4288 17.5132 19.4393 17.4994 19.4542 17.4785C19.4839 17.4368 19.5315 17.3668 19.5913 17.2673C19.7106 17.0683 19.8788 16.751 20.05 16.3058C20.3918 15.4171 20.75 14.0084 20.75 12C20.75 9.67366 20.2694 8.15099 19.8893 7.30849C19.7189 6.93093 19.8869 6.48676 20.2645 6.3164ZM18.164 9.26566C18.5696 9.18146 18.9666 9.44198 19.0508 9.84754C19.1609 10.378 19.25 11.0889 19.25 12C19.25 13.1101 19.1178 13.9228 18.9765 14.4738C18.9059 14.749 18.8333 14.9579 18.7745 15.1051C18.7451 15.1787 18.7191 15.2367 18.6986 15.2797C18.6884 15.3012 18.6795 15.3189 18.6723 15.333L18.6626 15.3514L18.6588 15.3585L18.6571 15.3615L18.6563 15.3629C18.6562 15.3632 18.6556 15.3642 18.0276 15.0153L18.6556 15.3642C18.4545 15.7263 17.9979 15.8568 17.6358 15.6556C17.2768 15.4562 17.1455 15.0056 17.3393 14.645L17.3443 14.6348C17.3512 14.6204 17.3643 14.5917 17.3818 14.548C17.4167 14.4608 17.4691 14.3135 17.5235 14.1012C17.6322 13.6772 17.75 12.9899 17.75 12C17.75 11.1873 17.6706 10.5787 17.5821 10.1525C17.4979 9.74689 17.7584 9.34986 18.164 9.26566ZM15.5 11.25C15.9142 11.25 16.25 11.5858 16.25 12C16.25 12.552 16.2137 13.5253 16.1619 14.6402L16.1592 14.6977C16.0914 16.1576 16.037 17.3296 15.8778 18.2139C15.7159 19.1134 15.417 19.8974 14.7109 20.3936C14.4759 20.5588 14.2142 20.692 13.9423 20.7848C13.2003 21.038 12.4627 20.8773 11.7204 20.549C10.9875 20.2248 10.1277 19.6808 9.08893 19.0001C8.74247 18.7731 8.64566 18.3082 8.87269 17.9617C9.09972 17.6153 9.56462 17.5184 9.91107 17.7455C10.9698 18.4393 11.7264 18.9114 12.3272 19.1772C12.9187 19.4389 13.2324 19.4421 13.4578 19.3651C13.5952 19.3183 13.7297 19.2498 13.8485 19.1664C14.0651 19.0141 14.2626 18.7195 14.4015 17.9482C14.541 17.1733 14.5924 16.1014 14.6635 14.5706C14.7156 13.451 14.75 12.5118 14.75 12C14.75 11.5858 15.0858 11.25 15.5 11.25Z"
|
|
||||||
fill="currentColor"
|
|
||||||
fillRule="evenodd"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
export default function NeshanLogoIcon({ className = 'size-6' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 28 28"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M25.8854 18.7656C26.5277 17.057 26.8193 15.2366 26.7428 13.4128C26.6663 11.589 26.2232 9.79937 25.44 8.15058L21.5725 0L12.5534 0.742312C10.7376 0.88579 8.96907 1.39198 7.35234 2.23095C5.73561 3.06991 4.30357 4.22461 3.14092 5.62672L1.06245 5.72322C0.768366 5.73671 0.491598 5.86611 0.292672 6.08312C0.0937466 6.30013 -0.0111452 6.58709 0.000939539 6.88123C0.00960807 7.03954 0.0526701 7.19406 0.127131 7.33404L1.06987 9.14528C0.350238 10.9272 0.0190473 12.8422 0.0984121 14.7623C0.177777 16.6824 0.665867 18.5635 1.5301 20.28L5.3827 28L13.9935 27.4804C15.9161 27.366 17.7922 26.8434 19.4971 25.9475C21.202 25.0515 22.6965 23.8027 23.8811 22.2842L25.915 22.1951C26.0593 22.1922 26.2016 22.1609 26.3338 22.103C26.466 22.0451 26.5855 21.9618 26.6854 21.8577C26.7854 21.7536 26.8639 21.6308 26.9164 21.4964C26.9688 21.362 26.9944 21.2185 26.9914 21.0742C26.9863 20.9139 26.9458 20.7567 26.8726 20.614L25.8854 18.7656Z"
|
|
||||||
fill="white"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M18.4991 16.8652C18.7839 16.4108 18.9513 15.8927 18.9863 15.3576C19.0213 14.8225 18.9227 14.287 18.6995 13.7994L19.568 12.3593L18.0834 11.5279C18.0257 11.075 17.8792 10.6379 17.6525 10.2416C17.4257 9.84537 17.123 9.49768 16.7618 9.21846C16.4005 8.93924 15.9877 8.73398 15.5471 8.6144C15.1064 8.49483 14.6466 8.46329 14.1937 8.52158C13.8839 8.55848 13.5812 8.64103 13.2955 8.76655L11.8554 7.92773L11.0315 9.36782C10.1214 9.49507 9.2986 9.97693 8.74239 10.7084C8.18617 11.4398 7.94168 12.3614 8.06221 13.2724C8.10466 13.5731 8.18446 13.8673 8.29975 14.1483L7.46094 15.6329L8.94556 16.4717C9.00673 16.9232 9.15627 17.3582 9.38566 17.7518C9.61504 18.1454 9.91976 18.4899 10.2824 18.7657C10.645 19.0414 11.0585 19.243 11.499 19.3589C11.9396 19.4748 12.3987 19.5027 12.8501 19.441C13.1456 19.4045 13.4351 19.3297 13.7112 19.2183L15.1142 20.0423L15.9381 18.5576C16.4716 18.5089 16.9846 18.3288 17.4315 18.0335C17.8784 17.7382 18.2452 17.3368 18.4991 16.8652Z"
|
|
||||||
fill="#10B990"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M8.10623 23.2864L7.95777 23.0117C5.51557 18.4168 3.14759 14.245 5.79022 9.65012C5.81426 9.62077 5.83423 9.58831 5.84961 9.55362L1.19531 6.86646L2.3459 9.09339C1.58576 10.7767 1.21064 12.6083 1.24788 14.4549C1.28512 16.3015 1.73377 18.1166 2.56116 19.7678L6.0723 26.8049L8.10623 23.2864Z"
|
|
||||||
fill="#234D69"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M21.1193 18.3796C21.0992 18.4102 21.0818 18.4425 21.0673 18.4761C20.4869 19.5041 19.6975 20.3992 18.7502 21.1036C17.8028 21.8081 16.7184 22.3063 15.5668 22.5663C13.2176 23.0696 10.8209 23.3185 8.41836 23.3086H8.10659L6.08008 26.8197L13.9263 26.3446C15.7717 26.2344 17.5691 25.7133 19.1873 24.8194C20.8055 23.9256 22.2036 22.6815 23.2794 21.1782L25.7736 21.0668L21.1193 18.3796Z"
|
|
||||||
fill="#173F58"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M17.793 6.51738C19.7999 7.65997 21.2749 9.5483 21.8976 11.7722C22.5203 13.996 22.2403 16.3757 21.1185 18.3944L25.7728 21.0815L24.6074 18.8546C25.2918 17.2389 25.6258 15.4964 25.5874 13.7422C25.549 11.9879 25.1391 10.2617 24.3847 8.67751L20.8587 1.25439L17.793 6.57677V6.51738Z"
|
|
||||||
fill="#D65357"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M17.7942 6.51745L20.8599 1.19507L12.65 1.86315C10.9037 2.00565 9.20733 2.51581 7.67215 3.36016C6.13697 4.20451 4.7977 5.36396 3.74222 6.76241L1.21094 6.87376L5.86523 9.56835C7.05496 7.59561 8.9728 6.16991 11.2047 5.5991C13.4366 5.02828 15.8034 5.35813 17.7942 6.51745Z"
|
|
||||||
fill="#EB5E60"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
export default function OverviewIcon({ className = 'size-6' }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
height="21"
|
|
||||||
viewBox="0 0 21 21"
|
|
||||||
width="21"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M0 4.75C0 2.12665 2.12665 0 4.75 0C7.37335 0 9.5 2.12665 9.5 4.75V7.41667C9.5 7.43794 9.50004 7.45932 9.50009 7.48078C9.50057 7.72335 9.50107 7.97639 9.44037 8.20293C9.27855 8.80684 8.80684 9.27855 8.20293 9.44037C7.97639 9.50107 7.72335 9.50057 7.48078 9.50009C7.45932 9.50004 7.43794 9.5 7.41667 9.5H4.75C2.12665 9.5 0 7.37335 0 4.75ZM4.75 1.5C2.95507 1.5 1.5 2.95507 1.5 4.75C1.5 6.54493 2.95507 8 4.75 8H7.41667C7.57846 8 7.67479 7.99982 7.74713 7.99652C7.79266 7.99444 7.81229 7.99162 7.81714 7.99082C7.90143 7.96732 7.96732 7.90143 7.99082 7.81714C7.99162 7.81229 7.99444 7.79266 7.99652 7.74713C7.99982 7.67479 8 7.57846 8 7.41667V4.75C8 2.95507 6.54493 1.5 4.75 1.5Z"
|
|
||||||
fill="currentColor"
|
|
||||||
fillRule="evenodd"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M13.0192 10.9999C13.0407 11 13.0621 11 13.0833 11H15.75C18.3734 11 20.5 13.1266 20.5 15.75C20.5 18.3734 18.3734 20.5 15.75 20.5C13.1266 20.5 11 18.3734 11 15.75V13.0833C11 13.0621 11 13.0407 10.9999 13.0192C10.9994 12.7766 10.9989 12.5236 11.0596 12.2971C11.2214 11.6932 11.6932 11.2214 12.2971 11.0596C12.5236 10.9989 12.7766 10.9994 13.0192 10.9999ZM12.6829 12.5092C12.5986 12.5327 12.5327 12.5986 12.5092 12.6829C12.5084 12.6877 12.5056 12.7073 12.5035 12.7529C12.5002 12.8252 12.5 12.9215 12.5 13.0833V15.75C12.5 17.5449 13.9551 19 15.75 19C17.5449 19 19 17.5449 19 15.75C19 13.9551 17.5449 12.5 15.75 12.5H13.0833C12.9215 12.5 12.8252 12.5002 12.7529 12.5035C12.7073 12.5056 12.6877 12.5084 12.6829 12.5092Z"
|
|
||||||
fill="currentColor"
|
|
||||||
fillRule="evenodd"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M7.74572 12.5111C7.6166 12.5006 7.4424 12.5 7.15 12.5H4.75C2.95507 12.5 1.5 13.9551 1.5 15.75C1.5 17.5449 2.95507 19 4.75 19C6.54493 19 8 17.5449 8 15.75V13.35C8 13.0576 7.99942 12.8834 7.98887 12.7543C7.98243 12.6755 7.97393 12.6423 7.97118 12.6335C7.94766 12.5888 7.91118 12.5523 7.86654 12.5288C7.85766 12.5261 7.82453 12.5176 7.74572 12.5111ZM7.86913 12.5297L7.86761 12.5292L7.86913 12.5297ZM7.97027 12.6309L7.97082 12.6324L7.97027 12.6309ZM7.86787 11.0161C8.08101 11.0335 8.31418 11.0734 8.54448 11.1907C8.87377 11.3585 9.14148 11.6262 9.30926 11.9555C9.42661 12.1858 9.46647 12.419 9.48388 12.6321C9.50004 12.8298 9.50002 13.0663 9.5 13.3238L9.5 15.75C9.5 18.3734 7.37335 20.5 4.75 20.5C2.12665 20.5 0 18.3734 0 15.75C0 13.1266 2.12665 11 4.75 11L7.17622 11C7.4337 11 7.67019 11 7.86787 11.0161Z"
|
|
||||||
fill="currentColor"
|
|
||||||
fillRule="evenodd"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M11 4.75C11 2.12665 13.1266 0 15.75 0C18.3734 0 20.5 2.12665 20.5 4.75C20.5 7.37335 18.3734 9.5 15.75 9.5H12.8929C12.8837 9.5 12.8746 9.50001 12.8654 9.50002C12.7614 9.5001 12.6535 9.5002 12.5541 9.489C11.7427 9.39758 11.1024 8.75727 11.011 7.94594C10.9998 7.84653 10.9999 7.73858 11 7.63464C11 7.62544 11 7.61627 11 7.60714V4.75ZM15.75 1.5C13.9551 1.5 12.5 2.95507 12.5 4.75V7.60714C12.5 7.67638 12.5 7.7176 12.5006 7.7487C12.501 7.76848 12.5016 7.7771 12.5017 7.77916C12.5152 7.89412 12.6059 7.9848 12.7208 7.99829C12.7229 7.99844 12.7315 7.99897 12.7513 7.99936C12.7824 7.99997 12.8236 8 12.8929 8H15.75C17.5449 8 19 6.54493 19 4.75C19 2.95507 17.5449 1.5 15.75 1.5Z"
|
|
||||||
fill="currentColor"
|
|
||||||
fillRule="evenodd"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
export default function PaymentCardIcon({ className = 'size-4' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 13 12"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M7.167 8.667a.5.5 0 0 0 0 1h2.666a.5.5 0 0 0 0-1H7.167Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M3.603.047C4.18 0 4.896 0 5.81 0h1.38c.914 0 1.63 0 2.207.047.586.048 1.071.147 1.51.37.721.368 1.307.954 1.675 1.676.322.632.39 1.373.41 2.397.008.39.008.834.008 1.34v.026c0 .914 0 1.631-.047 2.207-.048.587-.147 1.072-.37 1.51a3.833 3.833 0 0 1-1.676 1.676c-.439.223-.924.323-1.51.37-.577.048-1.294.048-2.208.048H5.811c-.915 0-1.632 0-2.208-.048-.587-.047-1.071-.147-1.51-.37A3.833 3.833 0 0 1 .418 9.574c-.224-.439-.323-.924-.37-1.51C0 7.487 0 6.77 0 5.856V5.83c0-.506 0-.95.007-1.34.02-1.024.089-1.765.41-2.397A3.833 3.833 0 0 1 2.094.418c.439-.224.923-.323 1.51-.37Zm.082.997c-.525.043-.864.125-1.138.265a2.833 2.833 0 0 0-1.238 1.238c-.17.332-.25.747-.285 1.453h10.952c-.035-.706-.116-1.12-.285-1.453a2.833 2.833 0 0 0-1.238-1.238c-.274-.14-.613-.222-1.138-.265C8.785 1 8.108 1 7.167 1H5.833c-.941 0-1.618 0-2.148.044ZM1.002 5C1 5.254 1 5.53 1 5.833c0 .942 0 1.618.044 2.149.043.525.125.863.265 1.138.271.533.705.966 1.238 1.238.274.14.613.222 1.138.265.53.043 1.207.044 2.148.044h1.334c.941 0 1.618 0 2.148-.044.525-.043.864-.125 1.138-.265a2.833 2.833 0 0 0 1.238-1.238c.14-.275.222-.613.265-1.138.043-.53.044-1.207.044-2.149 0-.303 0-.58-.002-.833H1.002Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
export default function QuestionMarkIcon({ className = 'size-6' }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
height="14"
|
|
||||||
viewBox="0 0 8 14"
|
|
||||||
width="8"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M7.14551 1.9248L6.23145 2.96191C5.58105 1.95996 4.7168 1.45898 3.63867 1.45898C3.1875 1.45898 2.76562 1.54395 2.37305 1.71387C1.98633 1.87793 1.67285 2.10059 1.43262 2.38184C1.19238 2.65723 1.06641 2.95898 1.05469 3.28711L1.56445 3.92871C2.12695 4.64941 2.5752 5.2793 2.90918 5.81836C3.24902 6.35156 3.50684 6.86133 3.68262 7.34766C3.86426 7.83398 3.99316 8.36719 4.06934 8.94727L2.96191 9.58008C2.8916 8.83594 2.75098 8.18848 2.54004 7.6377C2.3291 7.08691 2.08301 6.60352 1.80176 6.1875C1.52051 5.77148 1.23926 5.39355 0.958008 5.05371C0.670898 4.70215 0.439453 4.37988 0.263672 4.08691C0.0878906 3.78809 0 3.47461 0 3.14648C0 2.53125 0.166992 1.98926 0.500977 1.52051C0.84082 1.0459 1.29199 0.673828 1.85449 0.404297C2.41699 0.134766 3.03809 0 3.71777 0C5.19434 0 6.33691 0.641602 7.14551 1.9248ZM3.22559 11.2324C3.7002 11.4141 4.19531 11.7656 4.71094 12.2871L3.66504 13.7549C3.19629 13.3447 2.7041 12.9961 2.18848 12.709L3.22559 11.2324Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,234 +0,0 @@
|
|||||||
export default function SemiColonIcon() {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
fill="none"
|
|
||||||
height="80"
|
|
||||||
viewBox="0 0 30 80"
|
|
||||||
width="30"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M14.5312 0C22.5469 0 29.0625 6.5 29.0625 14.5312C29.0625 22.5469 22.5625 29.0625 14.5312 29.0625C6.51562 29.0625 0 22.5625 0 14.5312C0 6.5 6.51562 0 14.5312 0Z"
|
|
||||||
fill="url(#paint0_linear_389_5191)"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M14.5312 0C22.5469 0 29.0625 6.5 29.0625 14.5312C29.0625 22.5469 22.5625 29.0625 14.5312 29.0625C6.51562 29.0625 0 22.5625 0 14.5312C0 6.5 6.51562 0 14.5312 0Z"
|
|
||||||
fill="url(#paint1_linear_389_5191)"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M14.5312 0C22.5469 0 29.0625 6.5 29.0625 14.5312C29.0625 22.5469 22.5625 29.0625 14.5312 29.0625C6.51562 29.0625 0 22.5625 0 14.5312C0 6.5 6.51562 0 14.5312 0Z"
|
|
||||||
fill="url(#paint2_linear_389_5191)"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M12.4062 63.6094H14.1875C14 68.4844 11.6875 73.0469 7.8125 76.0781C5.95312 77.5312 7.35938 80.4844 9.65625 79.9531L13.2031 79.1406C22.4844 76.9844 29.0625 68.7188 29.0625 59.2031V46.9531C29.0625 40.1094 23.5156 34.5469 16.6562 34.5469H12.4062C5.5625 34.5469 0 40.0937 0 46.9531V51.2031C0 58.0469 5.5625 63.6094 12.4062 63.6094Z"
|
|
||||||
fill="url(#paint3_linear_389_5191)"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M16.6563 34.5469H12.4062C11.875 34.5469 11.3438 34.5781 10.8281 34.6562V63.5C11.3438 63.5625 11.875 63.6094 12.4062 63.6094H14.1875C14.0625 67.0469 12.875 70.3125 10.8281 73V79.6719L13.2031 79.125C22.4844 76.9844 29.0625 68.7188 29.0625 59.2031V46.9531C29.0625 40.0937 23.5 34.5469 16.6563 34.5469Z"
|
|
||||||
fill="url(#paint4_linear_389_5191)"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M0 47.3281V51.2031C0 58.0469 5.54687 63.6094 12.4062 63.6094H14.1875C14 68.4844 11.6875 73.0469 7.8125 76.0781C5.95312 77.5312 7.35938 80.4844 9.65625 79.9531L13.2031 79.1406C22.4844 76.9844 29.0625 68.7188 29.0625 59.2031V47.3281H0Z"
|
|
||||||
fill="url(#paint5_linear_389_5191)"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M0 47.3281V51.2031C0 58.0469 5.54687 63.6094 12.4062 63.6094H14.1875C14 68.4844 11.6875 73.0469 7.8125 76.0781C5.95312 77.5312 7.35938 80.4844 9.65625 79.9531L13.2031 79.1406C22.4844 76.9844 29.0625 68.7188 29.0625 59.2031V47.3281H0Z"
|
|
||||||
fill="url(#paint6_linear_389_5191)"
|
|
||||||
/>
|
|
||||||
<defs>
|
|
||||||
<linearGradient
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
id="paint0_linear_389_5191"
|
|
||||||
x1="7.39953"
|
|
||||||
x2="24.2827"
|
|
||||||
y1="7.39594"
|
|
||||||
y2="24.2791"
|
|
||||||
>
|
|
||||||
<stop stopColor="#766E6E" />
|
|
||||||
<stop
|
|
||||||
offset="0.2493"
|
|
||||||
stopColor="#716B6B"
|
|
||||||
/>
|
|
||||||
<stop
|
|
||||||
offset="0.5076"
|
|
||||||
stopColor="#656464"
|
|
||||||
/>
|
|
||||||
<stop
|
|
||||||
offset="0.769"
|
|
||||||
stopColor="#505757"
|
|
||||||
/>
|
|
||||||
<stop
|
|
||||||
offset="1"
|
|
||||||
stopColor="#384949"
|
|
||||||
/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
id="paint1_linear_389_5191"
|
|
||||||
x1="14.5312"
|
|
||||||
x2="14.5312"
|
|
||||||
y1="16.2458"
|
|
||||||
y2="29.6144"
|
|
||||||
>
|
|
||||||
<stop
|
|
||||||
stopColor="#464646"
|
|
||||||
stopOpacity="0"
|
|
||||||
/>
|
|
||||||
<stop
|
|
||||||
offset="0.6727"
|
|
||||||
stopColor="#252529"
|
|
||||||
stopOpacity="0.463"
|
|
||||||
/>
|
|
||||||
<stop
|
|
||||||
offset="1"
|
|
||||||
stopColor="#000009"
|
|
||||||
/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
id="paint2_linear_389_5191"
|
|
||||||
x1="19.9041"
|
|
||||||
x2="30.1292"
|
|
||||||
y1="14.5277"
|
|
||||||
y2="14.5277"
|
|
||||||
>
|
|
||||||
<stop
|
|
||||||
stopColor="#464646"
|
|
||||||
stopOpacity="0"
|
|
||||||
/>
|
|
||||||
<stop
|
|
||||||
offset="0.6727"
|
|
||||||
stopColor="#252529"
|
|
||||||
stopOpacity="0.463"
|
|
||||||
/>
|
|
||||||
<stop
|
|
||||||
offset="1"
|
|
||||||
stopColor="#000009"
|
|
||||||
/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
id="paint3_linear_389_5191"
|
|
||||||
x1="-5.05656"
|
|
||||||
x2="23.2491"
|
|
||||||
y1="49.6797"
|
|
||||||
y2="61.0247"
|
|
||||||
>
|
|
||||||
<stop stopColor="#766E6E" />
|
|
||||||
<stop
|
|
||||||
offset="0.2493"
|
|
||||||
stopColor="#716B6B"
|
|
||||||
/>
|
|
||||||
<stop
|
|
||||||
offset="0.5076"
|
|
||||||
stopColor="#656464"
|
|
||||||
/>
|
|
||||||
<stop
|
|
||||||
offset="0.769"
|
|
||||||
stopColor="#505757"
|
|
||||||
/>
|
|
||||||
<stop
|
|
||||||
offset="1"
|
|
||||||
stopColor="#384949"
|
|
||||||
/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
id="paint4_linear_389_5191"
|
|
||||||
x1="19.0852"
|
|
||||||
x2="28.8319"
|
|
||||||
y1="57.1078"
|
|
||||||
y2="57.1078"
|
|
||||||
>
|
|
||||||
<stop
|
|
||||||
stopColor="#464646"
|
|
||||||
stopOpacity="0"
|
|
||||||
/>
|
|
||||||
<stop
|
|
||||||
offset="0.6727"
|
|
||||||
stopColor="#252529"
|
|
||||||
stopOpacity="0.463"
|
|
||||||
/>
|
|
||||||
<stop
|
|
||||||
offset="1"
|
|
||||||
stopColor="#000009"
|
|
||||||
/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
id="paint5_linear_389_5191"
|
|
||||||
x1="18.3877"
|
|
||||||
x2="23.7736"
|
|
||||||
y1="63.5977"
|
|
||||||
y2="75.172"
|
|
||||||
>
|
|
||||||
<stop
|
|
||||||
stopColor="#464646"
|
|
||||||
stopOpacity="0"
|
|
||||||
/>
|
|
||||||
<stop
|
|
||||||
offset="0.6727"
|
|
||||||
stopColor="#252529"
|
|
||||||
stopOpacity="0.463"
|
|
||||||
/>
|
|
||||||
<stop
|
|
||||||
offset="1"
|
|
||||||
stopColor="#000009"
|
|
||||||
/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
id="paint6_linear_389_5191"
|
|
||||||
x1="18.412"
|
|
||||||
x2="31.7053"
|
|
||||||
y1="63.4091"
|
|
||||||
y2="74.525"
|
|
||||||
>
|
|
||||||
<stop
|
|
||||||
stopColor="white"
|
|
||||||
stopOpacity="0"
|
|
||||||
/>
|
|
||||||
<stop
|
|
||||||
offset="0.1205"
|
|
||||||
stopColor="white"
|
|
||||||
stopOpacity="0.016"
|
|
||||||
/>
|
|
||||||
<stop
|
|
||||||
offset="0.2454"
|
|
||||||
stopColor="white"
|
|
||||||
stopOpacity="0.065"
|
|
||||||
/>
|
|
||||||
<stop
|
|
||||||
offset="0.3724"
|
|
||||||
stopColor="white"
|
|
||||||
stopOpacity="0.147"
|
|
||||||
/>
|
|
||||||
<stop
|
|
||||||
offset="0.5008"
|
|
||||||
stopColor="white"
|
|
||||||
stopOpacity="0.261"
|
|
||||||
/>
|
|
||||||
<stop
|
|
||||||
offset="0.6304"
|
|
||||||
stopColor="white"
|
|
||||||
stopOpacity="0.408"
|
|
||||||
/>
|
|
||||||
<stop
|
|
||||||
offset="0.761"
|
|
||||||
stopColor="white"
|
|
||||||
stopOpacity="0.588"
|
|
||||||
/>
|
|
||||||
<stop
|
|
||||||
offset="0.8898"
|
|
||||||
stopColor="white"
|
|
||||||
stopOpacity="0.797"
|
|
||||||
/>
|
|
||||||
<stop
|
|
||||||
offset="1"
|
|
||||||
stopColor="white"
|
|
||||||
/>
|
|
||||||
</linearGradient>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
export default function SendIcon({ className = 'size-6' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
aria-hidden
|
|
||||||
className={className}
|
|
||||||
fill="currentColor"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path d="M3.4 20.4l17.45-7.48a1 1 0 000-1.84L3.4 3.6a.993.993 0 00-1.39.91L2 9.12c0 .5.37.93.87.99L17 12 2.87 13.88c-.5.07-.87.5-.87 1l.01 4.61a.993.993 0 001.39.91z" />
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
export default function SettingsIcon({ className = 'size-5' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
aria-hidden
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 20 20"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M8.2 1.8h3.6l.3 1.6c.4.1.8.3 1.1.5l1.5-.7 1.8 1.8-.7 1.5c.2.3.4.7.5 1.1l1.6.3v3.6l-1.6.3c-.1.4-.3.8-.5 1.1l.7 1.5-1.8 1.8-1.5-.7c-.3.2-.7.4-1.1.5l-.3 1.6H8.2l-.3-1.6a5 5 0 0 1-1.1-.5l-1.5.7-1.8-1.8.7-1.5a5 5 0 0 1-.5-1.1L2.1 10.8V7.2l1.6-.3c.1-.4.3-.8.5-1.1l-.7-1.5L5.3 2.5l1.5.7c.3-.2.7-.4 1.1-.5l.3-1.6ZM10 7.2A2.8 2.8 0 1 0 10 12.8 2.8 2.8 0 0 0 10 7.2Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
export default function ShareIcon({ className = 'size-6' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 20 20"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<g clipPath="url(#clip0_867_1043)">
|
|
||||||
<path
|
|
||||||
d="M16.1104 12.2224C15.4799 12.2226 14.8589 12.3761 14.3009 12.6698C13.743 12.9635 13.2649 13.3885 12.9079 13.9082L7.4912 11.4624C7.87107 10.5296 7.87405 9.48571 7.49954 8.55072L12.9112 6.09322C13.4389 6.85884 14.2236 7.40995 15.1228 7.64656C16.0221 7.88317 16.9764 7.78961 17.8126 7.38286C18.6487 6.97611 19.3114 6.2831 19.6804 5.42958C20.0494 4.57605 20.1002 3.61854 19.8236 2.73075C19.547 1.84297 18.9614 1.08373 18.173 0.59077C17.3845 0.0978114 16.4455 -0.0962085 15.5262 0.0439098C14.607 0.184028 13.7684 0.649002 13.1627 1.35448C12.5569 2.05995 12.2241 2.95919 12.2245 3.88906C12.2245 4.11024 12.2432 4.33102 12.2804 4.54906L6.53787 7.15572C5.98428 6.63942 5.29204 6.29589 4.54606 6.16727C3.80007 6.03865 3.03277 6.13053 2.33824 6.43165C1.64371 6.73276 1.05216 7.23002 0.63612 7.86243C0.220084 8.49485 -0.00234847 9.23494 -0.0038981 9.99193C-0.00544772 10.7489 0.213953 11.4899 0.627397 12.124C1.04084 12.7581 1.63035 13.2578 2.32364 13.5618C3.01693 13.8657 3.78385 13.9607 4.53036 13.8352C5.27687 13.7096 5.9705 13.3689 6.5262 12.8549L12.2762 15.4524C12.1411 16.2383 12.2507 17.0467 12.5904 17.7682C12.9301 18.4896 13.4833 19.0892 14.1751 19.4858C14.8669 19.8823 15.6639 20.0566 16.4581 19.985C17.2523 19.9135 18.0053 19.5995 18.6151 19.0857C19.2249 18.5719 19.6621 17.883 19.8673 17.1125C20.0725 16.3419 20.0359 15.5269 19.7624 14.7778C19.489 14.0288 18.9919 13.3819 18.3385 12.9248C17.6851 12.4677 16.9078 12.2225 16.1104 12.2224Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<clipPath id="clip0_867_1043">
|
|
||||||
<rect
|
|
||||||
fill="white"
|
|
||||||
height="20"
|
|
||||||
width="20"
|
|
||||||
/>
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
export default function TagIcon({ className = 'size-4' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 16 16"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M9.68769 0.833879C9.05774 0.82137 8.35751 1.04228 7.2079 1.40497L7.05811 1.45222C6.60807 1.59408 6.33116 1.68137 6.07489 1.80634C5.54513 2.06468 5.08208 2.4417 4.72171 2.9081C4.5474 3.13371 4.40579 3.38718 4.17564 3.79912L2.54539 6.71662C2.02627 7.64532 1.70948 8.21205 1.58801 8.76928C1.31962 10.0005 1.67348 11.285 2.53452 12.205C2.92422 12.6215 3.48653 12.946 4.40801 13.4778L4.5825 13.5786C5.50382 14.1107 6.06604 14.4354 6.62151 14.5647C7.84883 14.8503 9.13816 14.5145 10.0702 13.6665C10.4921 13.2827 10.8245 12.725 11.3692 11.8111L13.0807 8.94047C13.3224 8.53518 13.4711 8.2858 13.5793 8.02203C13.803 7.47675 13.898 6.88722 13.8569 6.29927C13.837 6.01485 13.7741 5.73139 13.6719 5.27069L13.638 5.11737C13.3773 3.94044 13.2185 3.22355 12.8926 2.68426C12.2125 1.55848 11.0027 0.859991 9.68769 0.833879ZM7.39825 2.3935C8.69325 1.98517 9.22392 1.82487 9.66784 1.83368C10.6398 1.85298 11.534 2.36925 12.0367 3.20136C12.2663 3.58139 12.3928 4.12112 12.6867 5.44679C12.8005 5.96029 12.8452 6.16776 12.8593 6.36909C12.8897 6.80366 12.8195 7.2394 12.6542 7.64244C12.5775 7.82915 12.47 8.01209 12.2006 8.46385L10.5618 11.2124C9.94905 12.2402 9.69472 12.6562 9.39725 12.9268C8.70833 13.5536 7.75535 13.8018 6.84819 13.5907C6.45648 13.4995 6.03155 13.2605 4.99526 12.6622C3.95897 12.0639 3.53947 11.8154 3.26466 11.5217C2.62824 10.8417 2.36669 9.89229 2.56507 8.98227C2.65073 8.58931 2.8838 8.16107 3.4675 7.11648L5.02844 4.323C5.285 3.86386 5.38963 3.67921 5.51303 3.51951C5.77938 3.17478 6.12164 2.89611 6.51321 2.70516C6.69461 2.6167 6.89663 2.55167 7.39825 2.3935Z"
|
|
||||||
fill="currentColor"
|
|
||||||
fillRule="evenodd"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M7.50449 4.80417C7.04425 5.60132 7.31738 6.62064 8.11453 7.08088C8.91169 7.54111 9.931 7.26799 10.3912 6.47083C10.8515 5.67368 10.5784 4.65436 9.7812 4.19413C8.98404 3.73389 7.96473 4.00701 7.50449 4.80417ZM8.37052 5.30417C8.18642 5.62303 8.29567 6.03076 8.61453 6.21485C8.93339 6.39895 9.34112 6.2897 9.52522 5.97083C9.70931 5.65197 9.60006 5.24425 9.2812 5.06015C8.96234 4.87606 8.55461 4.98531 8.37052 5.30417Z"
|
|
||||||
fill="currentColor"
|
|
||||||
fillRule="evenodd"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
export default function TicketStarIcon({ className = 'h-[17.5px] w-[21.5px]' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 18 18"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M4.83333 2.4375C2.68172 2.4375 0.9375 4.18172 0.9375 6.33333C0.9375 6.95713 1.29524 7.52566 1.8576 7.79559L2.22313 7.97105C3.0864 8.38542 3.0864 9.61458 2.22313 10.029L1.8576 10.2044C1.29524 10.4743 0.9375 11.0429 0.9375 11.6667C0.9375 13.8183 2.68172 15.5625 4.83333 15.5625H13.1667C15.3183 15.5625 17.0625 13.8183 17.0625 11.6667C17.0625 11.0429 16.7048 10.4743 16.1424 10.2044L15.7769 10.029C14.9136 9.61458 14.9136 8.38542 15.7769 7.97105L16.1424 7.79559C16.7048 7.52566 17.0625 6.95713 17.0625 6.33333C17.0625 4.18173 15.3183 2.4375 13.1667 2.4375H4.83333ZM11.3904 6.60961C11.6101 6.82928 11.6101 7.18544 11.3904 7.40511L7.14775 11.6477C6.92808 11.8674 6.57192 11.8674 6.35225 11.6477C6.13258 11.4281 6.13258 11.0719 6.35225 10.8523L10.5949 6.60961C10.8146 6.38994 11.1707 6.38994 11.3904 6.60961ZM6.75 7.5C6.33579 7.5 6 7.16421 6 6.75C6 6.33579 6.33579 6 6.75 6C7.16421 6 7.5 6.33579 7.5 6.75C7.5 7.16421 7.16421 7.5 6.75 7.5ZM11.25 12C10.8358 12 10.5 11.6642 10.5 11.25C10.5 10.8358 10.8358 10.5 11.25 10.5C11.6642 10.5 12 10.8358 12 11.25C12 11.6642 11.6642 12 11.25 12Z"
|
|
||||||
fill="currentColor"
|
|
||||||
fillRule="evenodd"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,56 +0,0 @@
|
|||||||
import { cn } from '@/lib/cn'
|
|
||||||
|
|
||||||
interface TicketDiscountTwoToneIconProps {
|
|
||||||
className?: string
|
|
||||||
/** رنگ لایه اصلی — مثلاً `text-gray-800` */
|
|
||||||
primaryClassName?: string
|
|
||||||
/** رنگ لایه ثانویه — مثلاً `text-primary`؛ پیشفرض opacity-40 مثل Iconsax */
|
|
||||||
secondaryClassName?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function TicketDiscountTwoToneIcon({
|
|
||||||
className = 'size-6',
|
|
||||||
primaryClassName,
|
|
||||||
secondaryClassName,
|
|
||||||
}: TicketDiscountTwoToneIconProps) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
className={primaryClassName}
|
|
||||||
d="M19.5 12.5C19.5 11.12 20.62 10 22 10V9C22 5 21 4 17 4H7C3 4 2 5 2 9V9.5C3.38 9.5 4.5 10.62 4.5 12C4.5 13.38 3.38 14.5 2 14.5V15C2 19 3 20 7 20H17C21 20 22 19 22 15C20.62 15 19.5 13.88 19.5 12.5Z"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
strokeWidth="1.5"
|
|
||||||
/>
|
|
||||||
<g className={cn('opacity-40', secondaryClassName)}>
|
|
||||||
<path
|
|
||||||
d="M9 14.75L15 8.75"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
strokeWidth="1.5"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M14.9945 14.75H15.0035"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
strokeWidth="2"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M8.99451 9.25H9.00349"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
strokeWidth="2"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
export default function TicketStarIcon({ className = 'h-[17.5px] w-[21.5px]' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 20 20"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M11.694 2.70825C12.8371 2.70825 13.7333 2.70825 14.4536 2.7671C15.187 2.82702 15.7929 2.95107 16.3414 3.23051C17.243 3.68991 17.976 4.42294 18.4354 5.32455C18.7705 5.98222 18.8863 6.7352 18.9297 7.70825H1.06897C1.11244 6.7352 1.22817 5.98222 1.56328 5.32455C2.02267 4.42294 2.7557 3.68991 3.65731 3.23051C4.20575 2.95107 4.81168 2.82702 5.54513 2.7671C6.26542 2.70825 7.16162 2.70825 8.30472 2.70825H11.694Z"
|
|
||||||
fill="#585858"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M1.04291 8.95825C1.04102 9.27831 1.04102 9.62323 1.04102 9.9951V10.0279C1.04101 11.171 1.04101 12.0672 1.09986 12.7875C1.15978 13.5209 1.28383 14.1268 1.56328 14.6753C2.02267 15.5769 2.7557 16.3099 3.65731 16.7693C4.20575 17.0488 4.81168 17.1728 5.54513 17.2327C6.26538 17.2916 7.16152 17.2916 8.30454 17.2916H11.694C12.837 17.2916 13.7333 17.2916 14.4536 17.2327C15.187 17.1728 15.7929 17.0488 16.3414 16.7693C17.243 16.3099 17.976 15.5769 18.4354 14.6753C18.7149 14.1268 18.8389 13.5209 18.8988 12.7875C18.9577 12.0672 18.9577 11.1711 18.9577 10.0281V9.99509C18.9577 9.62322 18.9577 9.27831 18.9558 8.95825H1.04291ZM4.37435 14.1666C4.37435 13.8214 4.65417 13.5416 4.99935 13.5416H6.66602C7.01119 13.5416 7.29102 13.8214 7.29102 14.1666C7.29102 14.5118 7.01119 14.7916 6.66602 14.7916H4.99935C4.65417 14.7916 4.37435 14.5118 4.37435 14.1666ZM8.54102 14.1666C8.54102 13.8214 8.82084 13.5416 9.16602 13.5416H12.4993C12.8445 13.5416 13.1243 13.8214 13.1243 14.1666C13.1243 14.5118 12.8445 14.7916 12.4993 14.7916H9.16602C8.82084 14.7916 8.54102 14.5118 8.54102 14.1666Z"
|
|
||||||
fill="#585858"
|
|
||||||
fillRule="evenodd"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
export default function TriangleLeftIcon({ className = 'size-3' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 6 12"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M5.27796 1.28269C5.57216 0.991107 5.57427 0.516238 5.28269 0.222041C4.99111 -0.0721558 4.51624 -0.0742744 4.22204 0.217309L2.42731 1.9961C1.75134 2.66604 1.19886 3.21359 0.807056 3.70146C0.399628 4.20878 0.104695 4.72372 0.0259091 5.34184C-0.00863636 5.61286 -0.0086363 5.88714 0.0259089 6.15816C0.104695 6.77628 0.399628 7.29122 0.807057 7.79854C1.19886 8.28641 1.75133 8.83395 2.4273 9.50389L4.22204 11.2827C4.51624 11.5743 4.99111 11.5722 5.28269 11.278C5.57427 10.9838 5.57216 10.5089 5.27796 10.2173L3.51499 8.47C2.7995 7.76086 2.30869 7.27282 1.97659 6.85929C1.654 6.4576 1.54332 6.19958 1.51387 5.9685C1.49538 5.82341 1.49538 5.67659 1.51387 5.5315C1.54332 5.30042 1.654 5.0424 1.97659 4.64071C2.30869 4.22718 2.7995 3.73914 3.51499 3.03L5.27796 1.28269Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
export default function UserPlusIcon({ className = 'size-4' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M18.75 15C18.75 14.5858 18.4142 14.25 18 14.25C17.5858 14.25 17.25 14.5858 17.25 15V17.25H15C14.5858 17.25 14.25 17.5858 14.25 18C14.25 18.4142 14.5858 18.75 15 18.75H17.25V21C17.25 21.4142 17.5858 21.75 18 21.75C18.4142 21.75 18.75 21.4142 18.75 21V18.75H21C21.4142 18.75 21.75 18.4142 21.75 18C21.75 17.5858 21.4142 17.25 21 17.25H18.75V15Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M6 6.75C6 4.12665 8.12665 2 10.75 2C13.3734 2 15.5 4.12665 15.5 6.75C15.5 9.37335 13.3734 11.5 10.75 11.5C8.12665 11.5 6 9.37335 6 6.75Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M3 17.75C3 15.1266 5.12665 13 7.75 13H13.75C14.7296 13 15.64 13.2966 16.3963 13.8048C16.1474 14.1382 16 14.5519 16 15V16H15C13.8954 16 13 16.8954 13 18C13 19.1046 13.8954 20 15 20H16V21C16 21.2968 16.0647 21.5785 16.1807 21.8318C15.4696 22.2562 14.6383 22.5 13.75 22.5H7.75C5.12665 22.5 3 20.3734 3 17.75Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
import { cn } from '@/lib/cn'
|
|
||||||
|
|
||||||
interface UserTwoToneIconProps {
|
|
||||||
className?: string
|
|
||||||
/** رنگ لایه اصلی — مثلاً `text-gray-800` */
|
|
||||||
primaryClassName?: string
|
|
||||||
/** رنگ لایه ثانویه — مثلاً `text-primary`؛ پیشفرض opacity-40 مثل Iconsax */
|
|
||||||
secondaryClassName?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function UserTwoToneIcon({ className = 'size-6', primaryClassName, secondaryClassName }: UserTwoToneIconProps) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
className={primaryClassName}
|
|
||||||
d="M12 12C14.7614 12 17 9.76142 17 7C17 4.23858 14.7614 2 12 2C9.23858 2 7 4.23858 7 7C7 9.76142 9.23858 12 12 12Z"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
strokeWidth="1.5"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
className={cn('opacity-40', secondaryClassName)}
|
|
||||||
d="M20.5901 22C20.5901 18.13 16.7402 15 12.0002 15C7.26015 15 3.41016 18.13 3.41016 22"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
strokeWidth="1.5"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
export default function UsersIcon({ className = 'size-4' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 16 11"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M5.6 4.745A3.17 3.17 0 0 1 4.667 2.5c0-.878.357-1.672.933-2.245A2.5 2.5 0 1 0 5.6 4.745ZM5.333 2.5a2.5 2.5 0 1 1 5 0 2.5 2.5 0 0 1-5 0ZM10.066.255A3.17 3.17 0 0 1 11 2.5a3.17 3.17 0 0 1-.934 2.245 2.5 2.5 0 1 0 0-4.49ZM3.333 8.5A2.5 2.5 0 0 1 5.833 6h4a2.5 2.5 0 1 1 0 5h-4a2.5 2.5 0 0 1-2.5-2.5ZM0 7.833a2.5 2.5 0 0 1 2.5-2.5h3.333a3.167 3.167 0 0 0-2.582 5H2.5a2.5 2.5 0 0 1-2.5-2.5ZM13 8.5c0 .683-.216 1.316-.584 1.833h.75a2.5 2.5 0 0 0 0-5H9.834A3.167 3.167 0 0 1 13 8.5Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
export default function VerifiedBadgeIcon({ className = 'size-5' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 16 16"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<g clipPath="url(#clip0_700_5548)">
|
|
||||||
<path
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M5.62309 1.83764C6.30534 -0.552976 9.69332 -0.552976 10.3756 1.83764C10.5934 2.60108 11.3778 3.05392 12.1479 2.86089C14.5593 2.25642 16.2533 5.19049 14.5241 6.97665C13.9719 7.54705 13.9719 8.45273 14.5241 9.02314C16.2533 10.8093 14.5593 13.7434 12.1479 13.1389C11.3778 12.9459 10.5934 13.3987 10.3756 14.1621C9.69332 16.5528 6.30534 16.5528 5.62309 14.1621C5.40522 13.3987 4.62088 12.9459 3.85078 13.1389C1.43932 13.7434 -0.254668 10.8093 1.47454 9.02314C2.02676 8.45273 2.02676 7.54705 1.47454 6.97665C-0.254668 5.19049 1.43932 2.25642 3.85078 2.86089C4.62088 3.05392 5.40522 2.60108 5.62309 1.83764ZM11.0501 6.31999C11.2269 6.10785 11.1982 5.79257 10.9861 5.61579C10.774 5.43901 10.4587 5.46767 10.2819 5.67981L7.97287 8.45065C7.72567 8.74729 7.57387 8.92757 7.44881 9.04049C7.39082 9.09286 7.35642 9.11374 7.33993 9.12171C7.33658 9.12334 7.33419 9.12431 7.33268 9.12487C7.33117 9.12431 7.32879 9.12334 7.32544 9.12171C7.30895 9.11374 7.27455 9.09286 7.21655 9.04049C7.0915 8.92757 6.93969 8.74729 6.6925 8.45065L5.71679 7.27981C5.54001 7.06767 5.22473 7.03901 5.01259 7.21579C4.80045 7.39257 4.77179 7.70785 4.94857 7.91999L5.94557 9.11639C6.16455 9.37922 6.36196 9.61617 6.54635 9.78268C6.74698 9.96384 6.99969 10.1252 7.33268 10.1252C7.66568 10.1252 7.91838 9.96384 8.11901 9.78268C8.30341 9.61617 8.50081 9.37923 8.71979 9.1164L11.0501 6.31999Z"
|
|
||||||
fill="currentColor"
|
|
||||||
fillRule="evenodd"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<clipPath id="clip0_700_5548">
|
|
||||||
<rect
|
|
||||||
fill="white"
|
|
||||||
height="16"
|
|
||||||
width="16"
|
|
||||||
/>
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
export default function VerticalDotsIcon({ className = 'size-6' }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<g clipPath="url(#clip0_410_2263)">
|
|
||||||
<path
|
|
||||||
d="M12 4C13.1046 4 14 3.10457 14 2C14 0.89543 13.1046 0 12 0C10.8954 0 10 0.89543 10 2C10 3.10457 10.8954 4 12 4Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M12 14.0005C13.1046 14.0005 14 13.1051 14 12.0005C14 10.8959 13.1046 10.0005 12 10.0005C10.8954 10.0005 10 10.8959 10 12.0005C10 13.1051 10.8954 14.0005 12 14.0005Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M12 23.9995C13.1046 23.9995 14 23.1041 14 21.9995C14 20.8949 13.1046 19.9995 12 19.9995C10.8954 19.9995 10 20.8949 10 21.9995C10 23.1041 10.8954 23.9995 12 23.9995Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<clipPath id="clip0_410_2263">
|
|
||||||
<rect
|
|
||||||
fill="white"
|
|
||||||
height="24"
|
|
||||||
width="24"
|
|
||||||
/>
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,85 +0,0 @@
|
|||||||
export default function AngleDownIcon({ className = 'size-10' }: { className?: string }) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={className}
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 40 40"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M29.1211 4.76386C28.8456 4.52901 28.5224 4.35684 28.1737 4.25929C27.8251 4.16173 27.4594 4.14111 27.1021 4.19886L6.35378 7.54542C5.27695 7.71526 4.29645 8.26485 3.58962 9.09479C2.88278 9.92472 2.49629 10.9802 2.50003 12.0703V14.1667C2.50003 14.3877 2.58783 14.5997 2.74411 14.7559C2.9004 14.9122 3.11237 15 3.33339 15H29.1667C29.3877 15 29.5997 14.9122 29.7559 14.7559C29.9122 14.5997 30 14.3877 30 14.1667V6.66714C30.0003 6.30513 29.9219 5.94739 29.7701 5.61873C29.6183 5.29008 29.3969 4.99837 29.1211 4.76386Z"
|
|
||||||
fill="url(#paint0_linear_699_3733)"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M31.6666 10.8334H5C4.33718 10.8341 3.70172 11.0977 3.23303 11.5664C2.76435 12.0351 2.50072 12.6706 2.5 13.3334V31.6667C2.50136 32.7713 2.94078 33.8303 3.72188 34.6114C4.50298 35.3925 5.56199 35.832 6.66664 35.8334H31.6666C32.7713 35.832 33.8303 35.3926 34.6115 34.6115C35.3926 33.8303 35.832 32.7713 35.8334 31.6667V15C35.8321 13.8953 35.3927 12.8362 34.6116 12.0551C33.8304 11.274 32.7713 10.8346 31.6666 10.8334Z"
|
|
||||||
fill="url(#paint1_linear_699_3733)"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M35.8336 17.5H25.0002C23.8983 17.5048 22.8431 17.9459 22.0656 18.7268C21.2881 19.5076 20.8516 20.5647 20.8516 21.6667C20.8516 22.7686 21.2881 23.8257 22.0656 24.6066C22.8431 25.3875 23.8983 25.8286 25.0002 25.8334H35.8336C36.2755 25.8329 36.6991 25.6571 37.0116 25.3446C37.324 25.0322 37.4998 24.6085 37.5002 24.1666V19.1666C37.4998 18.7248 37.324 18.3011 37.0116 17.9887C36.6991 17.6762 36.2755 17.5005 35.8336 17.5Z"
|
|
||||||
fill="url(#paint2_linear_699_3733)"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M25.0006 23.3333C25.9211 23.3333 26.6673 22.5871 26.6673 21.6666C26.6673 20.7462 25.9211 20 25.0006 20C24.0802 20 23.334 20.7462 23.334 21.6666C23.334 22.5871 24.0802 23.3333 25.0006 23.3333Z"
|
|
||||||
fill="url(#paint3_linear_699_3733)"
|
|
||||||
/>
|
|
||||||
<defs>
|
|
||||||
<linearGradient
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
id="paint0_linear_699_3733"
|
|
||||||
x1="4.24112"
|
|
||||||
x2="29.6682"
|
|
||||||
y1="9.58354"
|
|
||||||
y2="9.58354"
|
|
||||||
>
|
|
||||||
<stop stopColor="#CCCCCC" />
|
|
||||||
<stop
|
|
||||||
offset="1"
|
|
||||||
stopColor="#919191"
|
|
||||||
/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
id="paint1_linear_699_3733"
|
|
||||||
x1="5.14508"
|
|
||||||
x2="36.2273"
|
|
||||||
y1="23.3334"
|
|
||||||
y2="23.3334"
|
|
||||||
>
|
|
||||||
<stop stopColor="white" />
|
|
||||||
<stop
|
|
||||||
offset="1"
|
|
||||||
stopColor="#DDDDDD"
|
|
||||||
/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
id="paint2_linear_699_3733"
|
|
||||||
x1="22.171"
|
|
||||||
x2="37.6966"
|
|
||||||
y1="21.6666"
|
|
||||||
y2="21.6666"
|
|
||||||
>
|
|
||||||
<stop stopColor="#FED200" />
|
|
||||||
<stop
|
|
||||||
offset="1"
|
|
||||||
stopColor="#F59815"
|
|
||||||
/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
id="paint3_linear_699_3733"
|
|
||||||
x1="23.293"
|
|
||||||
x2="26.5759"
|
|
||||||
y1="21.6666"
|
|
||||||
y2="21.6666"
|
|
||||||
>
|
|
||||||
<stop stopColor="white" />
|
|
||||||
<stop
|
|
||||||
offset="1"
|
|
||||||
stopColor="#F2EBE6"
|
|
||||||
/>
|
|
||||||
</linearGradient>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,69 +0,0 @@
|
|||||||
'use client'
|
|
||||||
|
|
||||||
import Button from '@/components/formElements/Button'
|
|
||||||
import HeatIcon from '@/components/icons/HeatIcon'
|
|
||||||
import HeatIconFill from '@/components/icons/HeatIconFill'
|
|
||||||
import { cn } from '@/lib/cn'
|
|
||||||
import { texts, format } from '@/texts'
|
|
||||||
|
|
||||||
interface StarRatingProps {
|
|
||||||
value: number
|
|
||||||
onChange?: (value: number) => void
|
|
||||||
size?: 'sm' | 'md'
|
|
||||||
className?: string
|
|
||||||
/** Read-only display when onChange is omitted. */
|
|
||||||
label?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const ICON_SIZE = {
|
|
||||||
sm: 'size-3.5',
|
|
||||||
md: 'size-5',
|
|
||||||
} as const
|
|
||||||
|
|
||||||
const StarRating = ({ value, onChange, size = 'md', className, label }: StarRatingProps) => {
|
|
||||||
const interactive = typeof onChange === 'function'
|
|
||||||
const iconClass = ICON_SIZE[size]
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
aria-label={label ?? format(texts.reviews.ratingValueAria, { value })}
|
|
||||||
className={cn('flex items-center gap-1', className)}
|
|
||||||
role={interactive ? 'radiogroup' : 'img'}
|
|
||||||
>
|
|
||||||
{[1, 2, 3, 4, 5].map((star) => {
|
|
||||||
const filled = star <= value
|
|
||||||
const Icon = filled ? HeatIconFill : HeatIcon
|
|
||||||
const colorClass = filled ? 'text-primary' : 'text-tertiary-900/35'
|
|
||||||
|
|
||||||
if (!interactive) {
|
|
||||||
return (
|
|
||||||
<Icon
|
|
||||||
key={star}
|
|
||||||
className={cn(iconClass, colorClass)}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Button
|
|
||||||
key={star}
|
|
||||||
aria-checked={star === value}
|
|
||||||
aria-label={format(texts.reviews.heartAria, { star })}
|
|
||||||
className={cn('min-h-11 min-w-11 px-1 shadow-none transition-transform hover:scale-110', colorClass)}
|
|
||||||
color="default"
|
|
||||||
radius="none"
|
|
||||||
role="radio"
|
|
||||||
variant="light"
|
|
||||||
onClick={() => {
|
|
||||||
onChange(star)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Icon className={iconClass} />
|
|
||||||
</Button>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default StarRating
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
/** Enamad trust seal id (panel) — must match footer badge. */
|
|
||||||
export const ENAMAD_ID = '7400030'
|
|
||||||
|
|
||||||
/** Enamad trust seal code — used in footer links/images only (not the meta tag). */
|
|
||||||
export const ENAMAD_CODE = 'TRxYXZLDTi8LQuOIZe8Z56sZ3pS3baMp'
|
|
||||||
|
|
||||||
export const ENAMAD_URL = `https://trustseal.enamad.ir/?id=${ENAMAD_ID}&Code=${ENAMAD_CODE}`
|
|
||||||
|
|
||||||
/** Self-hosted badge (avoids ORB/blocks on trustseal logo.aspx). Link still goes to ENAMAD_URL. */
|
|
||||||
export const ENAMAD_IMAGE_URL = '/images/enamad.png'
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
/**
|
|
||||||
* Single source of truth for the platform's public contact number.
|
|
||||||
* Was previously hardcoded independently in 5 places (frontend/app/(public)/{layout.tsx,contact/page.tsx},
|
|
||||||
* frontend/components/public/{ContactForm.tsx,PublicFooter.tsx}, frontend/e2e/shared/public-pages.spec.ts)
|
|
||||||
* -- a number change would have needed a coordinated grep-and-replace across all of them.
|
|
||||||
*/
|
|
||||||
export const SITE_PHONE = '+989153641196'
|
|
||||||
|
|
||||||
/** Digits-only form, for `tel:`/`wa.me` links that don't want the leading `+`. */
|
|
||||||
export const SITE_PHONE_DIGITS = SITE_PHONE.slice(1)
|
|
||||||
|
|
||||||
export const SITE_WHATSAPP_URL = (text: string) => `https://wa.me/${SITE_PHONE_DIGITS}?text=${text}`
|
|
||||||
|
|
||||||
/** Official support profiles — used in footer + Organization `sameAs`. */
|
|
||||||
export const SITE_INSTAGRAM_URL = 'https://www.instagram.com/Ghabilee_support/'
|
|
||||||
export const SITE_TELEGRAM_URL = 'https://t.me/Ghabilee_support'
|
|
||||||
|
|
||||||
export const SITE_SOCIAL_SAME_AS = [SITE_INSTAGRAM_URL, SITE_TELEGRAM_URL] as const
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
import { addToast } from '@/lib/toast'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copies `text` to the clipboard and shows a success/failure toast.
|
|
||||||
* Was hand-copied (identical try/writeText/toast/catch shape) in
|
|
||||||
* BookingActionsModal.tsx#handleCopyCode and HostedEventActionsModal.tsx#handleShare —
|
|
||||||
* this is the shared home for any future "copy X" feature.
|
|
||||||
*/
|
|
||||||
const useCopyToClipboard = () => {
|
|
||||||
const copyToClipboard = async (text: string, messages: { successMessage: string; failureMessage: string }) => {
|
|
||||||
try {
|
|
||||||
await navigator.clipboard.writeText(text)
|
|
||||||
addToast({ title: messages.successMessage, color: 'success' })
|
|
||||||
|
|
||||||
return true
|
|
||||||
} catch {
|
|
||||||
addToast({ title: messages.failureMessage, color: 'danger' })
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return { copyToClipboard }
|
|
||||||
}
|
|
||||||
|
|
||||||
export default useCopyToClipboard
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
'use client'
|
|
||||||
|
|
||||||
import { useEffect, useState } from 'react'
|
|
||||||
|
|
||||||
/** Default delay — keeps deferred chrome out of the LCP window on cold loads. */
|
|
||||||
export const DEFERRED_CHROME_DELAY_MS = 4000
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true after `delayMs` so non-critical client UI (PWA banner, etc.) mounts
|
|
||||||
* after the first paint / LCP candidates.
|
|
||||||
*/
|
|
||||||
export function useDeferredClientMount(delayMs = DEFERRED_CHROME_DELAY_MS) {
|
|
||||||
const [ready, setReady] = useState(false)
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const timeoutId = window.setTimeout(() => {
|
|
||||||
setReady(true)
|
|
||||||
}, delayMs)
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
window.clearTimeout(timeoutId)
|
|
||||||
}
|
|
||||||
}, [delayMs])
|
|
||||||
|
|
||||||
return ready
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
type BookingExpiresAt = string | Date | Record<string, unknown> | null | undefined
|
|
||||||
|
|
||||||
const bookingExpiresAtMs = (expiresAt: BookingExpiresAt): number | null => {
|
|
||||||
if (expiresAt == null) return null
|
|
||||||
if (typeof expiresAt === 'string' || expiresAt instanceof Date) {
|
|
||||||
const ms = new Date(expiresAt).getTime()
|
|
||||||
|
|
||||||
return Number.isNaN(ms) ? null : ms
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Whether a pending_payment booking's hold window has passed (client clock). */
|
|
||||||
export const isBookingPaymentExpired = (booking: { status: string; expiresAt?: BookingExpiresAt }): boolean => {
|
|
||||||
const expiresAtMs = bookingExpiresAtMs(booking.expiresAt)
|
|
||||||
|
|
||||||
return booking.status === 'pending_payment' && expiresAtMs != null && expiresAtMs <= Date.now()
|
|
||||||
}
|
|
||||||
@ -1,132 +0,0 @@
|
|||||||
import type { Socket } from 'socket.io-client'
|
|
||||||
|
|
||||||
import { CHAT_SOCKET_NAMESPACE, CHAT_SOCKET_URL } from '@/config/chatSocket'
|
|
||||||
|
|
||||||
let socket: Socket | null = null
|
|
||||||
let connectAbortNonce = 0
|
|
||||||
|
|
||||||
export interface ChatMessageEvent {
|
|
||||||
id: string
|
|
||||||
conversationId: string
|
|
||||||
senderId: string
|
|
||||||
senderFirstName: string | null
|
|
||||||
senderLastName: string | null
|
|
||||||
senderAvatarUrl?: string | null
|
|
||||||
senderGender?: string | null
|
|
||||||
body: string | null
|
|
||||||
imageUrl: string | null
|
|
||||||
createdAt: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ConversationUpdatedEvent {
|
|
||||||
conversationId: string
|
|
||||||
lastMessageAt: string
|
|
||||||
preview: string | null
|
|
||||||
unreadCount?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getChatSocket = () => socket
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Connect chat socket on-demand.
|
|
||||||
*
|
|
||||||
* Important: `socket.io-client` must be loaded lazily to keep anonymous
|
|
||||||
* guest first-load bundles small.
|
|
||||||
*/
|
|
||||||
export const connectChatSocket = async (accessToken: string): Promise<Socket> => {
|
|
||||||
if (socket?.connected) {
|
|
||||||
// Keep the stored auth token current even while already connected: if
|
|
||||||
// this connection later drops (network blip, server restart) and
|
|
||||||
// socket.io-client auto-reconnects, it replays whatever is in
|
|
||||||
// `socket.auth` at that time — a stale token here would make every
|
|
||||||
// reconnect after the token's ~15min TTL fail silently.
|
|
||||||
socket.auth = { token: accessToken }
|
|
||||||
|
|
||||||
return socket
|
|
||||||
}
|
|
||||||
|
|
||||||
if (socket) {
|
|
||||||
socket.auth = { token: accessToken }
|
|
||||||
socket.connect()
|
|
||||||
|
|
||||||
return socket
|
|
||||||
}
|
|
||||||
|
|
||||||
const nonce = ++connectAbortNonce
|
|
||||||
const mod = await import('socket.io-client')
|
|
||||||
const { io } = mod
|
|
||||||
|
|
||||||
// Another tab/navigation/token change can call disconnectChatSocket while
|
|
||||||
// this module is still loading.
|
|
||||||
if (nonce !== connectAbortNonce) {
|
|
||||||
throw new Error('CHAT_SOCKET_CONNECT_ABORTED')
|
|
||||||
}
|
|
||||||
|
|
||||||
socket = io(`${CHAT_SOCKET_URL}${CHAT_SOCKET_NAMESPACE}`, {
|
|
||||||
transports: ['websocket'],
|
|
||||||
autoConnect: true,
|
|
||||||
auth: { token: accessToken },
|
|
||||||
})
|
|
||||||
|
|
||||||
return socket
|
|
||||||
}
|
|
||||||
|
|
||||||
export const disconnectChatSocket = () => {
|
|
||||||
if (!socket) return
|
|
||||||
|
|
||||||
connectAbortNonce += 1
|
|
||||||
socket.removeAllListeners()
|
|
||||||
socket.disconnect()
|
|
||||||
socket = null
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface JoinConversationAck {
|
|
||||||
ok: boolean
|
|
||||||
error?: string
|
|
||||||
conversationId?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export const joinConversationRoom = (conversationId: string): Promise<JoinConversationAck> => {
|
|
||||||
const activeSocket = socket
|
|
||||||
|
|
||||||
if (!activeSocket) return Promise.resolve({ ok: false, error: 'NOT_CONNECTED' })
|
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
activeSocket.timeout(5000).emit('conversation:join', { conversationId }, (error: Error | null, ack?: JoinConversationAck) => {
|
|
||||||
if (error) {
|
|
||||||
resolve({ ok: false, error: 'ACK_TIMEOUT' })
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve(ack ?? { ok: false, error: 'NO_ACK' })
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export const leaveConversationRoom = (conversationId: string) => {
|
|
||||||
socket?.emit('conversation:leave', { conversationId })
|
|
||||||
}
|
|
||||||
|
|
||||||
export const subscribeChatEvents = (handlers: {
|
|
||||||
onMessage?: (message: ChatMessageEvent) => void
|
|
||||||
onConversationUpdated?: (payload: ConversationUpdatedEvent) => void
|
|
||||||
}) => {
|
|
||||||
if (!socket) return () => undefined
|
|
||||||
|
|
||||||
const messageHandler = (payload: { message: ChatMessageEvent }) => {
|
|
||||||
handlers.onMessage?.(payload.message)
|
|
||||||
}
|
|
||||||
|
|
||||||
const conversationHandler = (payload: ConversationUpdatedEvent) => {
|
|
||||||
handlers.onConversationUpdated?.(payload)
|
|
||||||
}
|
|
||||||
|
|
||||||
socket.on('message:new', messageHandler)
|
|
||||||
socket.on('conversation:updated', conversationHandler)
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
socket?.off('message:new', messageHandler)
|
|
||||||
socket?.off('conversation:updated', conversationHandler)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
import Cookies from 'js-cookie'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Synchronous client-only hint that a consumer session likely exists.
|
|
||||||
* Used to suppress guest marketing / nationwide feed flash before AuthContext
|
|
||||||
* finishes hydrating from localStorage (CLS on `/`).
|
|
||||||
*
|
|
||||||
* Returns false during SSR — guest ISR HTML stays unchanged.
|
|
||||||
*/
|
|
||||||
export function hasClientSessionHint(): boolean {
|
|
||||||
if (typeof window === 'undefined') return false
|
|
||||||
|
|
||||||
return Boolean(Cookies.get('accessToken') || localStorage.getItem('user'))
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
'use client'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shared helpers for consumer payment query keys on the current URL.
|
|
||||||
* Used by EventPaymentModalController and EventDetailOverlay dismiss cleanup.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export const PAYMENT_QUERY_KEYS = ['payment', 'bookingId', 'depositId', 'status'] as const
|
|
||||||
|
|
||||||
export const stripPaymentQueryParams = (search: string): string => {
|
|
||||||
const params = new URLSearchParams(search)
|
|
||||||
|
|
||||||
for (const key of PAYMENT_QUERY_KEYS) {
|
|
||||||
params.delete(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
return params.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
export const hasActivePaymentQuery = (search: string): boolean => {
|
|
||||||
const params = new URLSearchParams(search)
|
|
||||||
const mode = params.get('payment')
|
|
||||||
|
|
||||||
return mode === 'checkout' || mode === 'result'
|
|
||||||
}
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
import type { EventManagementBootstrap } from '@/services/eventManagement'
|
|
||||||
|
|
||||||
type ApiEnvelope<T> = { success: true; data: T } | { success: false; message: string }
|
|
||||||
|
|
||||||
const resolveApiBaseUrl = () => {
|
|
||||||
const raw = process.env.NEXT_PUBLIC_API_URL
|
|
||||||
|
|
||||||
if (!raw) throw new Error('NEXT_PUBLIC_API_URL is not configured')
|
|
||||||
const trimmed = raw.replace(/\/+$/, '')
|
|
||||||
|
|
||||||
return trimmed.endsWith('/api/v1') ? trimmed : `${trimmed}/api/v1`
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Private owner data: never enters the public Next.js or persistent browser cache. */
|
|
||||||
export async function fetchEventManagementBootstrapForOwner(
|
|
||||||
eventId: string,
|
|
||||||
accessToken: string
|
|
||||||
): Promise<EventManagementBootstrap | null> {
|
|
||||||
const response = await fetch(`${resolveApiBaseUrl()}/events/${encodeURIComponent(eventId)}/management-bootstrap`, {
|
|
||||||
cache: 'no-store',
|
|
||||||
headers: { Authorization: `Bearer ${accessToken}` },
|
|
||||||
})
|
|
||||||
|
|
||||||
if (response.status === 401 || response.status === 403 || response.status === 404) return null
|
|
||||||
if (!response.ok) throw new Error(`Management bootstrap failed: ${response.status}`)
|
|
||||||
|
|
||||||
const body = (await response.json()) as ApiEnvelope<EventManagementBootstrap>
|
|
||||||
|
|
||||||
return body.success ? body.data : null
|
|
||||||
}
|
|
||||||
@ -87,7 +87,7 @@ const nextConfig = {
|
|||||||
...(basePath ? { basePath, assetPrefix: basePath } : {}),
|
...(basePath ? { basePath, assetPrefix: basePath } : {}),
|
||||||
allowedDevOrigins: ['192.168.100.51', '192.168.100.52'],
|
allowedDevOrigins: ['192.168.100.51', '192.168.100.52'],
|
||||||
|
|
||||||
transpilePackages: ['mapir-react-component', 'react-mapbox-gl', 'arcaptcha-react'],
|
transpilePackages: ['mapir-react-component', 'react-mapbox-gl'],
|
||||||
|
|
||||||
env: {
|
env: {
|
||||||
NEXT_PUBLIC_MAP_API_KEY: process.env.MAP_API_KEY || process.env.NEXT_PUBLIC_MAP_API_KEY || '',
|
NEXT_PUBLIC_MAP_API_KEY: process.env.MAP_API_KEY || process.env.NEXT_PUBLIC_MAP_API_KEY || '',
|
||||||
|
|||||||
@ -53,7 +53,6 @@
|
|||||||
"@tiptap/react": "^3.11.0",
|
"@tiptap/react": "^3.11.0",
|
||||||
"@tiptap/starter-kit": "^3.11.0",
|
"@tiptap/starter-kit": "^3.11.0",
|
||||||
"@types/jalaali-js": "^1.2.0",
|
"@types/jalaali-js": "^1.2.0",
|
||||||
"arcaptcha-react": "^0.4.0",
|
|
||||||
"axios": "1.18.1",
|
"axios": "1.18.1",
|
||||||
"clsx": "2.1.1",
|
"clsx": "2.1.1",
|
||||||
"dayjs": "^1.11.19",
|
"dayjs": "^1.11.19",
|
||||||
|
|||||||
354
services/chat.ts
354
services/chat.ts
@ -1,354 +0,0 @@
|
|||||||
import type {
|
|
||||||
ConversationParticipantResponseDto,
|
|
||||||
ConversationResponseDto,
|
|
||||||
MessageReplyToDto,
|
|
||||||
MessageResponseDto,
|
|
||||||
SendMessageDto,
|
|
||||||
} from '@/api/generated/models'
|
|
||||||
import {
|
|
||||||
createServiceError,
|
|
||||||
errorResult,
|
|
||||||
handleServiceError,
|
|
||||||
type ServiceCallOptions,
|
|
||||||
type ServiceResult,
|
|
||||||
shouldBubbleErrorToParent,
|
|
||||||
successResult,
|
|
||||||
} from '@/services/errorHandler'
|
|
||||||
import { unwrapApiData } from '@/services/apiResponse'
|
|
||||||
import { getChat } from '@/api/generated/chat/chat'
|
|
||||||
import { texts } from '@/texts'
|
|
||||||
import { parseRemittanceList } from '@/helpers/listResponse'
|
|
||||||
|
|
||||||
export type Conversation = ConversationResponseDto
|
|
||||||
|
|
||||||
export type ChatMessage = MessageResponseDto
|
|
||||||
|
|
||||||
export type ChatMessageReplyTo = MessageReplyToDto
|
|
||||||
|
|
||||||
export type ConversationTypeFilter = 'direct' | 'event_group'
|
|
||||||
|
|
||||||
export const CONVERSATIONS_PAGE_SIZE = 20
|
|
||||||
|
|
||||||
/** Direction-based history page (same field meaning in before / after / around modes). */
|
|
||||||
export interface ChatMessagesPage {
|
|
||||||
items: ChatMessage[]
|
|
||||||
olderCursor: string | null
|
|
||||||
newerCursor: string | null
|
|
||||||
hasMoreBefore: boolean
|
|
||||||
hasMoreAfter: boolean
|
|
||||||
aroundMessageId: string | null
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ListMessagesParams {
|
|
||||||
before?: string
|
|
||||||
after?: string
|
|
||||||
around?: string
|
|
||||||
pageSize?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type SendChatMessagePayload = Pick<SendMessageDto, 'body' | 'imageUrl' | 'replyToMessageId'>
|
|
||||||
|
|
||||||
export interface ConversationsPage {
|
|
||||||
items: Conversation[]
|
|
||||||
totalItemsCount: number
|
|
||||||
}
|
|
||||||
|
|
||||||
const chatApi = getChat()
|
|
||||||
|
|
||||||
export const LIST_CONVERSATIONS = async (
|
|
||||||
params?: { type?: ConversationTypeFilter; page?: number; pageSize?: number },
|
|
||||||
options?: ServiceCallOptions
|
|
||||||
): Promise<ServiceResult<ConversationsPage>> => {
|
|
||||||
const page = params?.page ?? 1
|
|
||||||
const pageSize = params?.pageSize ?? CONVERSATIONS_PAGE_SIZE
|
|
||||||
|
|
||||||
try {
|
|
||||||
const res = await chatApi.chatControllerListMine({
|
|
||||||
page,
|
|
||||||
pageSize,
|
|
||||||
sort: '-lastMessageAt',
|
|
||||||
...(params?.type ? { 'filters[type]': params.type } : {}),
|
|
||||||
})
|
|
||||||
|
|
||||||
const payload = res.data
|
|
||||||
|
|
||||||
if (!payload.success) {
|
|
||||||
throw createServiceError(payload.message || texts.chats.listConversationsFailed)
|
|
||||||
}
|
|
||||||
|
|
||||||
const parsed = parseRemittanceList<Conversation>(unwrapApiData(payload) ?? {}, 'items', page, pageSize)
|
|
||||||
|
|
||||||
return successResult({ items: parsed.items, totalItemsCount: parsed.pagination.totalItemsCount })
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const GET_CONVERSATION = async (conversationId: string, options?: ServiceCallOptions): Promise<ServiceResult<Conversation>> => {
|
|
||||||
try {
|
|
||||||
const res = await chatApi.chatControllerGetOne(conversationId)
|
|
||||||
const payload = res.data
|
|
||||||
|
|
||||||
if (!payload.success) {
|
|
||||||
throw createServiceError(payload.message || texts.chats.getConversationFailed)
|
|
||||||
}
|
|
||||||
|
|
||||||
const conversation = unwrapApiData(payload)
|
|
||||||
|
|
||||||
if (!conversation?.id) {
|
|
||||||
throw createServiceError(texts.common.invalidServerResponse)
|
|
||||||
}
|
|
||||||
|
|
||||||
return successResult(conversation)
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const GET_UNREAD_CHAT_COUNT = async (options?: ServiceCallOptions): Promise<ServiceResult<{ totalUnread: number }>> => {
|
|
||||||
try {
|
|
||||||
const res = await chatApi.chatControllerUnreadCount()
|
|
||||||
const payload = res.data
|
|
||||||
|
|
||||||
if (!payload.success) {
|
|
||||||
throw createServiceError(payload.message || texts.chats.unreadCountFailed)
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = unwrapApiData(payload)
|
|
||||||
|
|
||||||
return successResult({ totalUnread: data?.totalUnread ?? 0 })
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const MARK_CONVERSATION_READ = async (
|
|
||||||
conversationId: string,
|
|
||||||
lastSeenMessageId: string,
|
|
||||||
options?: ServiceCallOptions
|
|
||||||
): Promise<ServiceResult<{ totalUnread: number }>> => {
|
|
||||||
try {
|
|
||||||
const res = await chatApi.chatControllerMarkRead(conversationId, { lastSeenMessageId })
|
|
||||||
const payload = res.data
|
|
||||||
|
|
||||||
if (!payload.success) {
|
|
||||||
throw createServiceError(payload.message || texts.chats.markReadFailed)
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = unwrapApiData(payload)
|
|
||||||
|
|
||||||
return successResult({ totalUnread: data?.totalUnread ?? 0 })
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const MESSAGES_PAGE_SIZE = 50
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetches one page of conversation history.
|
|
||||||
*
|
|
||||||
* Cursor modes are mutually exclusive (`before` | `after` | `around`). Response
|
|
||||||
* cursors are direction-based: `olderCursor` → next `before`, `newerCursor` →
|
|
||||||
* next `after`, regardless of which mode produced the page.
|
|
||||||
*/
|
|
||||||
export const LIST_MESSAGES = async (
|
|
||||||
conversationId: string,
|
|
||||||
params?: ListMessagesParams,
|
|
||||||
options?: ServiceCallOptions
|
|
||||||
): Promise<ServiceResult<ChatMessagesPage>> => {
|
|
||||||
try {
|
|
||||||
const pageSize = params?.pageSize ?? MESSAGES_PAGE_SIZE
|
|
||||||
const res = await chatApi.chatControllerListMessages(conversationId, {
|
|
||||||
pageSize,
|
|
||||||
...(params?.before ? { before: params.before } : {}),
|
|
||||||
...(params?.after ? { after: params.after } : {}),
|
|
||||||
...(params?.around ? { around: params.around } : {}),
|
|
||||||
})
|
|
||||||
|
|
||||||
const payload = res.data
|
|
||||||
|
|
||||||
if (!payload.success) {
|
|
||||||
throw createServiceError(payload.message || texts.chats.listMessagesFailed)
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = unwrapApiData(payload)
|
|
||||||
const parsed = parseRemittanceList<ChatMessage>(data ?? {}, 'items', 1, pageSize)
|
|
||||||
const meta = data?.response
|
|
||||||
|
|
||||||
return successResult({
|
|
||||||
items: parsed.items,
|
|
||||||
olderCursor: meta?.olderCursor ?? null,
|
|
||||||
newerCursor: meta?.newerCursor ?? null,
|
|
||||||
hasMoreBefore: meta?.hasMoreBefore ?? false,
|
|
||||||
hasMoreAfter: meta?.hasMoreAfter ?? false,
|
|
||||||
aroundMessageId: meta?.aroundMessageId ?? null,
|
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const SEND_MESSAGE = async (
|
|
||||||
conversationId: string,
|
|
||||||
payload: SendChatMessagePayload,
|
|
||||||
options?: ServiceCallOptions
|
|
||||||
): Promise<ServiceResult<ChatMessage>> => {
|
|
||||||
try {
|
|
||||||
const res = await chatApi.chatControllerSendGroup(conversationId, payload)
|
|
||||||
|
|
||||||
const responsePayload = res.data
|
|
||||||
|
|
||||||
if (!responsePayload.success) {
|
|
||||||
throw createServiceError(responsePayload.message || texts.chats.sendFailed, responsePayload.code)
|
|
||||||
}
|
|
||||||
|
|
||||||
const message = unwrapApiData(responsePayload)
|
|
||||||
|
|
||||||
if (!message?.id) {
|
|
||||||
throw createServiceError(texts.common.invalidServerResponse)
|
|
||||||
}
|
|
||||||
|
|
||||||
return successResult(message)
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends the first (or a subsequent) message of a direct conversation by the
|
|
||||||
* other participant's user id, without needing a conversationId up front.
|
|
||||||
* Backend resolves/creates the canonical direct conversation for the pair
|
|
||||||
* (`get_or_create_direct_conversation`) and inserts the message in one call —
|
|
||||||
* see docs/workflows/fa/chat.md, "جریان A — پیام مستقیم".
|
|
||||||
*/
|
|
||||||
export const SEND_DIRECT_MESSAGE = async (
|
|
||||||
otherUserId: string,
|
|
||||||
payload: SendChatMessagePayload,
|
|
||||||
options?: ServiceCallOptions
|
|
||||||
): Promise<ServiceResult<ChatMessage>> => {
|
|
||||||
try {
|
|
||||||
const res = await chatApi.chatControllerSendDirect(otherUserId, payload)
|
|
||||||
|
|
||||||
const responsePayload = res.data
|
|
||||||
|
|
||||||
if (!responsePayload.success) {
|
|
||||||
throw createServiceError(responsePayload.message || texts.chats.sendFailed, responsePayload.code)
|
|
||||||
}
|
|
||||||
|
|
||||||
const message = unwrapApiData(responsePayload)
|
|
||||||
|
|
||||||
if (!message?.id) {
|
|
||||||
throw createServiceError(texts.common.invalidServerResponse)
|
|
||||||
}
|
|
||||||
|
|
||||||
return successResult(message)
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ENSURE_DIRECT_CONVERSATION = async (
|
|
||||||
otherUserId: string,
|
|
||||||
options?: ServiceCallOptions
|
|
||||||
): Promise<ServiceResult<Conversation>> => {
|
|
||||||
try {
|
|
||||||
const res = await chatApi.chatControllerEnsureDirect(otherUserId)
|
|
||||||
const payload = res.data
|
|
||||||
|
|
||||||
if (!payload.success) {
|
|
||||||
throw createServiceError(payload.message || texts.chats.openConversationFailed, payload.code)
|
|
||||||
}
|
|
||||||
|
|
||||||
const conversation = unwrapApiData(payload)
|
|
||||||
|
|
||||||
if (!conversation?.id) {
|
|
||||||
throw createServiceError(texts.common.invalidServerResponse)
|
|
||||||
}
|
|
||||||
|
|
||||||
return successResult(conversation)
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ChatParticipant = ConversationParticipantResponseDto
|
|
||||||
|
|
||||||
export const LIST_PARTICIPANTS = async (
|
|
||||||
conversationId: string,
|
|
||||||
params?: { page?: number; pageSize?: number },
|
|
||||||
options?: ServiceCallOptions
|
|
||||||
): Promise<ServiceResult<{ items: ChatParticipant[] }>> => {
|
|
||||||
try {
|
|
||||||
const res = await chatApi.chatControllerListParticipants(conversationId, {
|
|
||||||
page: params?.page ?? 1,
|
|
||||||
pageSize: params?.pageSize ?? 100,
|
|
||||||
sort: 'joinedAt',
|
|
||||||
})
|
|
||||||
const payload = res.data
|
|
||||||
|
|
||||||
if (!payload.success) {
|
|
||||||
throw createServiceError(payload.message || texts.chats.listParticipantsFailed)
|
|
||||||
}
|
|
||||||
|
|
||||||
const parsed = parseRemittanceList<ChatParticipant>(unwrapApiData(payload) ?? {}, 'items')
|
|
||||||
|
|
||||||
return successResult({ items: parsed.items })
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,62 +0,0 @@
|
|||||||
import axiosInstance from '@/config/axios'
|
|
||||||
import { texts } from '@/texts'
|
|
||||||
import { API_ROUTES } from '@/services/config'
|
|
||||||
import {
|
|
||||||
createServiceError,
|
|
||||||
errorResult,
|
|
||||||
handleServiceError,
|
|
||||||
type ServiceCallOptions,
|
|
||||||
type ServiceResult,
|
|
||||||
shouldBubbleErrorToParent,
|
|
||||||
successResult,
|
|
||||||
} from '@/services/errorHandler'
|
|
||||||
import { unwrapApiData, type ApiResponse } from '@/services/apiResponse'
|
|
||||||
|
|
||||||
export interface ContactMessage {
|
|
||||||
id: string
|
|
||||||
fullName: string
|
|
||||||
mobile: string
|
|
||||||
subject: string
|
|
||||||
message: string
|
|
||||||
readAt: string | null
|
|
||||||
readBy: string | null
|
|
||||||
createdAt: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CreateContactMessagePayload {
|
|
||||||
fullName: string
|
|
||||||
mobile: string
|
|
||||||
subject: string
|
|
||||||
message: string
|
|
||||||
arcaptchaToken: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export const CREATE_CONTACT_MESSAGE = async (
|
|
||||||
payload: CreateContactMessagePayload,
|
|
||||||
options?: ServiceCallOptions
|
|
||||||
): Promise<ServiceResult<ContactMessage>> => {
|
|
||||||
try {
|
|
||||||
const res = await axiosInstance.post<ApiResponse<ContactMessage>>(API_ROUTES.CONTACT_MESSAGES.CREATE, payload)
|
|
||||||
const body = res.data
|
|
||||||
|
|
||||||
if (!body.success) {
|
|
||||||
throw createServiceError(body.message || texts.chats.sendFailed)
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = unwrapApiData(body)
|
|
||||||
|
|
||||||
if (!data?.id) {
|
|
||||||
throw createServiceError(texts.common.invalidServerResponse)
|
|
||||||
}
|
|
||||||
|
|
||||||
return successResult(data)
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,165 +0,0 @@
|
|||||||
import { z } from 'zod'
|
|
||||||
|
|
||||||
import {
|
|
||||||
errorResult,
|
|
||||||
handleServiceError,
|
|
||||||
type ServiceCallOptions,
|
|
||||||
type ServiceResult,
|
|
||||||
shouldBubbleErrorToParent,
|
|
||||||
successResult,
|
|
||||||
} from '@/services/errorHandler'
|
|
||||||
import { unwrapApiDataUnknown, unwrapApiPayload } from '@/helpers/listResponse'
|
|
||||||
import { ANALYTICS_EVENTS, trackAnalyticsEventOnce } from '@/lib/analytics'
|
|
||||||
import { API_ROUTES } from '@/services/config'
|
|
||||||
import axiosInstance from '@/config/axios'
|
|
||||||
import { texts } from '@/texts'
|
|
||||||
|
|
||||||
export interface MyIdentityVerification {
|
|
||||||
id: string
|
|
||||||
status: 'pending' | 'verified' | 'rejected'
|
|
||||||
nationalCode: string | null
|
|
||||||
contractVersion?: string | null
|
|
||||||
contractAcceptedAt?: string | null
|
|
||||||
contractAcceptanceId?: string | null
|
|
||||||
reason?: { code: string; label: string } | null
|
|
||||||
rejectionReason?: string | null
|
|
||||||
createdAt: string
|
|
||||||
reviewedAt?: string | null
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IdentityRejectionReason {
|
|
||||||
id: number
|
|
||||||
code: string
|
|
||||||
label: string
|
|
||||||
sortOrder: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RequestHostContractOtpPayload {
|
|
||||||
nationalCode: string
|
|
||||||
contractAccepted: true
|
|
||||||
contractVersion: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const identityVerificationSchema = z.object({
|
|
||||||
id: z.string().min(1),
|
|
||||||
status: z.enum(['pending', 'verified', 'rejected']),
|
|
||||||
nationalCode: z.string().nullable().optional(),
|
|
||||||
contractVersion: z.string().nullable().optional(),
|
|
||||||
contractAcceptedAt: z.string().nullable().optional(),
|
|
||||||
contractAcceptanceId: z.string().nullable().optional(),
|
|
||||||
reason: z.object({ code: z.string(), label: z.string() }).nullable().optional(),
|
|
||||||
rejectionReason: z.string().nullable().optional(),
|
|
||||||
createdAt: z.string(),
|
|
||||||
reviewedAt: z.string().nullable().optional(),
|
|
||||||
})
|
|
||||||
|
|
||||||
const rejectionReasonSchema = z.object({
|
|
||||||
id: z.number(),
|
|
||||||
code: z.string(),
|
|
||||||
label: z.string(),
|
|
||||||
sortOrder: z.number(),
|
|
||||||
})
|
|
||||||
|
|
||||||
const otpRequestedSchema = z.object({
|
|
||||||
purpose: z.literal('host_contract'),
|
|
||||||
expiresIn: z.number(),
|
|
||||||
contractVersion: z.string(),
|
|
||||||
})
|
|
||||||
|
|
||||||
export const GET_MY_IDENTITY_VERIFICATION = async (options?: ServiceCallOptions): Promise<ServiceResult<MyIdentityVerification | null>> => {
|
|
||||||
try {
|
|
||||||
const res = await axiosInstance.get('identity/verifications/me')
|
|
||||||
const payload = unwrapApiDataUnknown(res.data)
|
|
||||||
const latest: unknown = Array.isArray(payload) ? payload[0] : payload
|
|
||||||
|
|
||||||
if (!latest || typeof latest !== 'object' || !('id' in latest)) return successResult(null)
|
|
||||||
const parsed = identityVerificationSchema.safeParse(latest)
|
|
||||||
|
|
||||||
if (!parsed.success) throw new Error(texts.common.invalidServerResponse)
|
|
||||||
|
|
||||||
return successResult({
|
|
||||||
...parsed.data,
|
|
||||||
nationalCode: parsed.data.nationalCode ?? null,
|
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const REQUEST_HOST_CONTRACT_OTP = async (
|
|
||||||
data: RequestHostContractOtpPayload,
|
|
||||||
options?: ServiceCallOptions
|
|
||||||
): Promise<ServiceResult<{ purpose: 'host_contract'; expiresIn: number; contractVersion: string }>> => {
|
|
||||||
try {
|
|
||||||
const res = await axiosInstance.post(API_ROUTES.IDENTITY.REQUEST_OTP, data)
|
|
||||||
const parsed = otpRequestedSchema.safeParse(unwrapApiPayload(res.data))
|
|
||||||
|
|
||||||
if (!parsed.success) throw new Error(texts.common.invalidServerResponse)
|
|
||||||
|
|
||||||
return successResult(parsed.data)
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const CONFIRM_HOST_CONTRACT_OTP = async (
|
|
||||||
code: string,
|
|
||||||
options?: ServiceCallOptions
|
|
||||||
): Promise<ServiceResult<MyIdentityVerification>> => {
|
|
||||||
try {
|
|
||||||
const res = await axiosInstance.post(API_ROUTES.IDENTITY.CONFIRM_OTP, { code })
|
|
||||||
const parsed = identityVerificationSchema.safeParse(unwrapApiPayload(res.data))
|
|
||||||
|
|
||||||
if (!parsed.success) throw new Error(texts.common.invalidServerResponse)
|
|
||||||
|
|
||||||
trackAnalyticsEventOnce(ANALYTICS_EVENTS.IDENTITY_VERIFICATION_SUBMITTED, parsed.data.id, {
|
|
||||||
verification_id: parsed.data.id,
|
|
||||||
verification_status: parsed.data.status,
|
|
||||||
})
|
|
||||||
|
|
||||||
return successResult({
|
|
||||||
...parsed.data,
|
|
||||||
nationalCode: parsed.data.nationalCode ?? null,
|
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const GET_IDENTITY_REJECTION_REASONS = async (options?: ServiceCallOptions): Promise<ServiceResult<IdentityRejectionReason[]>> => {
|
|
||||||
try {
|
|
||||||
const res = await axiosInstance.get(API_ROUTES.IDENTITY.REJECTION_REASONS)
|
|
||||||
const payload = unwrapApiDataUnknown(res.data)
|
|
||||||
const parsed = z.array(rejectionReasonSchema).safeParse(Array.isArray(payload) ? payload : [])
|
|
||||||
|
|
||||||
if (!parsed.success) throw new Error(texts.common.invalidServerResponse)
|
|
||||||
|
|
||||||
return successResult(parsed.data)
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
import type { MyEventsGuestItemDto, MyEventsHostItemDto, MyEventsListControllerList200, PaginationMetaDto } from '@/api/generated/models'
|
|
||||||
import { getMyEvents } from '@/api/generated/my-events/my-events'
|
|
||||||
import { unwrapApiPayload } from '@/helpers/listResponse'
|
|
||||||
|
|
||||||
export const MY_EVENTS_PAGE_SIZE = 20
|
|
||||||
|
|
||||||
export type MyEventsRole = 'guest' | 'host'
|
|
||||||
export type MyEventsGuestStatus = 'upcoming' | 'held' | 'cancelled'
|
|
||||||
export type MyEventsHostStatus = 'pending_review' | 'published' | 'rejected'
|
|
||||||
export type MyEventsStatus = MyEventsGuestStatus | MyEventsHostStatus
|
|
||||||
export type MyEventsGuestItem = MyEventsGuestItemDto
|
|
||||||
export type MyEventsHostItem = MyEventsHostItemDto
|
|
||||||
|
|
||||||
export interface MyEventsPage<TItem> {
|
|
||||||
role: MyEventsRole
|
|
||||||
status: MyEventsStatus
|
|
||||||
canHost: boolean
|
|
||||||
availableRoles: MyEventsRole[]
|
|
||||||
items: TItem[]
|
|
||||||
response: PaginationMetaDto
|
|
||||||
}
|
|
||||||
|
|
||||||
const myEventsApi = getMyEvents()
|
|
||||||
|
|
||||||
/** Fetches one server-filtered lifecycle page for the My Events screen. */
|
|
||||||
export const fetchMyEventsPage = async <TItem extends MyEventsGuestItem | MyEventsHostItem>({
|
|
||||||
role,
|
|
||||||
status,
|
|
||||||
page,
|
|
||||||
pageSize = MY_EVENTS_PAGE_SIZE,
|
|
||||||
signal,
|
|
||||||
}: {
|
|
||||||
role: MyEventsRole
|
|
||||||
status: MyEventsStatus
|
|
||||||
page: number
|
|
||||||
pageSize?: number
|
|
||||||
signal?: AbortSignal
|
|
||||||
}): Promise<MyEventsPage<TItem>> => {
|
|
||||||
const response = await myEventsApi.myEventsListControllerList({ role, status, page, pageSize }, { signal })
|
|
||||||
const payload = unwrapApiPayload<MyEventsListControllerList200>(response.data)
|
|
||||||
|
|
||||||
return payload as MyEventsPage<TItem>
|
|
||||||
}
|
|
||||||
@ -1,84 +0,0 @@
|
|||||||
import type { NotificationResponseDto } from '@/api/generated/models'
|
|
||||||
import {
|
|
||||||
createServiceError,
|
|
||||||
errorResult,
|
|
||||||
handleServiceError,
|
|
||||||
type ServiceCallOptions,
|
|
||||||
type ServiceResult,
|
|
||||||
shouldBubbleErrorToParent,
|
|
||||||
successResult,
|
|
||||||
} from '@/services/errorHandler'
|
|
||||||
import { unwrapApiData } from '@/services/apiResponse'
|
|
||||||
import { getNotifications } from '@/api/generated/notifications/notifications'
|
|
||||||
import { parseRemittanceList } from '@/helpers/listResponse'
|
|
||||||
import { texts } from '@/texts'
|
|
||||||
|
|
||||||
export type InAppNotification = NotificationResponseDto
|
|
||||||
|
|
||||||
const notificationsApi = getNotifications()
|
|
||||||
|
|
||||||
export const LIST_NOTIFICATIONS = async (options?: ServiceCallOptions): Promise<ServiceResult<{ items: InAppNotification[] }>> => {
|
|
||||||
try {
|
|
||||||
const res = await notificationsApi.notificationsControllerListMine({ page: 1, pageSize: 30, sort: '-createdAt' })
|
|
||||||
|
|
||||||
const parsed = parseRemittanceList<InAppNotification>(res.data, 'items')
|
|
||||||
|
|
||||||
return successResult({ items: parsed.items })
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const GET_UNREAD_NOTIFICATION_COUNT = async (options?: ServiceCallOptions): Promise<ServiceResult<{ totalUnread: number }>> => {
|
|
||||||
try {
|
|
||||||
const res = await notificationsApi.notificationsControllerUnreadCount()
|
|
||||||
|
|
||||||
if (!res.data.success) throw createServiceError(res.data.message)
|
|
||||||
const payload = unwrapApiData(res.data)
|
|
||||||
const totalUnread = Number(payload?.totalUnread ?? 0)
|
|
||||||
|
|
||||||
return successResult({ totalUnread: Number.isFinite(totalUnread) ? totalUnread : 0 })
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const MARK_NOTIFICATION_READ = async (
|
|
||||||
notificationId: string,
|
|
||||||
options?: ServiceCallOptions
|
|
||||||
): Promise<ServiceResult<InAppNotification>> => {
|
|
||||||
try {
|
|
||||||
const res = await notificationsApi.notificationsControllerMarkAsRead(notificationId)
|
|
||||||
|
|
||||||
if (!res.data.success) throw createServiceError(res.data.message)
|
|
||||||
const payload = unwrapApiData(res.data)
|
|
||||||
|
|
||||||
if (!payload?.id) {
|
|
||||||
throw createServiceError(texts.common.invalidServerResponse)
|
|
||||||
}
|
|
||||||
|
|
||||||
return successResult(payload)
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const countUnreadNotifications = (items: InAppNotification[]): number => items.filter((item) => !item.readAt).length
|
|
||||||
@ -1,189 +0,0 @@
|
|||||||
import { z } from 'zod'
|
|
||||||
|
|
||||||
import type {
|
|
||||||
CreatePaymentResponseDto,
|
|
||||||
PaymentCheckoutResponseDto,
|
|
||||||
PaymentReceiptResponseDto,
|
|
||||||
PaymentResponseDto,
|
|
||||||
} from '@/api/generated/models'
|
|
||||||
import type { BookingStatus } from '@/api/generated/models'
|
|
||||||
import {
|
|
||||||
createServiceError,
|
|
||||||
errorResult,
|
|
||||||
handleServiceError,
|
|
||||||
type ServiceCallOptions,
|
|
||||||
type ServiceResult,
|
|
||||||
shouldBubbleErrorToParent,
|
|
||||||
successResult,
|
|
||||||
} from '@/services/errorHandler'
|
|
||||||
import { unwrapApiData } from '@/services/apiResponse'
|
|
||||||
import { getBookings } from '@/api/generated/bookings/bookings'
|
|
||||||
import { getEvents } from '@/api/generated/events/events'
|
|
||||||
import { getFinancial } from '@/api/generated/financial/financial'
|
|
||||||
import { unwrapApiPayload } from '@/helpers/listResponse'
|
|
||||||
import { texts } from '@/texts'
|
|
||||||
|
|
||||||
// docs/workflows/fa/payment.md — consumer checkout for a `pending_payment`
|
|
||||||
// booking. Payment creation is a *second, separate* call from booking
|
|
||||||
// creation (owned by saza2's services/bookings.ts) — this file only covers
|
|
||||||
// the payment leg: reading the booking/event to render the checkout
|
|
||||||
// screen, then POST /bookings/:bookingId/payments.
|
|
||||||
|
|
||||||
export interface BookingForPayment {
|
|
||||||
id: string
|
|
||||||
eventId: string
|
|
||||||
bookingCode: string
|
|
||||||
status: BookingStatus
|
|
||||||
expiresAt: string | null
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface EventSummaryForPayment {
|
|
||||||
id: string
|
|
||||||
slug?: string | null
|
|
||||||
title: string
|
|
||||||
price: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type PaymentCheckout = PaymentCheckoutResponseDto
|
|
||||||
|
|
||||||
export type Payment = PaymentResponseDto
|
|
||||||
|
|
||||||
// Orval snapshot may lag backend fields returned at runtime for checkout.
|
|
||||||
export type CreatePaymentResult = CreatePaymentResponseDto & {
|
|
||||||
depositId?: string | null
|
|
||||||
depositAmount?: number
|
|
||||||
walletBalanceUsed?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type PaymentReceipt = PaymentReceiptResponseDto
|
|
||||||
|
|
||||||
const bookingForPaymentSchema = z.object({
|
|
||||||
id: z.string().min(1),
|
|
||||||
eventId: z.string().min(1),
|
|
||||||
bookingCode: z.string(),
|
|
||||||
status: z.enum(['pending_payment', 'confirmed', 'cancelled', 'expired', 'refunded', 'no_show']),
|
|
||||||
expiresAt: z.string().nullable(),
|
|
||||||
})
|
|
||||||
|
|
||||||
const paymentReceiptSchema = z.object({
|
|
||||||
id: z.string().min(1),
|
|
||||||
paymentId: z.string().min(1),
|
|
||||||
userId: z.string().min(1),
|
|
||||||
bookingId: z.string().min(1),
|
|
||||||
eventId: z.string().min(1),
|
|
||||||
receiptCode: z.string(),
|
|
||||||
snapshot: z.record(z.string(), z.unknown()),
|
|
||||||
issuedAt: z.string(),
|
|
||||||
})
|
|
||||||
|
|
||||||
const bookingsApi = getBookings()
|
|
||||||
const eventsApi = getEvents()
|
|
||||||
const financialApi = getFinancial()
|
|
||||||
|
|
||||||
export const GET_BOOKING_FOR_PAYMENT = async (
|
|
||||||
bookingId: string,
|
|
||||||
options?: ServiceCallOptions
|
|
||||||
): Promise<ServiceResult<BookingForPayment>> => {
|
|
||||||
try {
|
|
||||||
const res = await bookingsApi.bookingsControllerFindOne(bookingId)
|
|
||||||
const parsed = bookingForPaymentSchema.safeParse(unwrapApiPayload(res.data))
|
|
||||||
|
|
||||||
if (!parsed.success) throw createServiceError(texts.common.invalidServerResponse)
|
|
||||||
|
|
||||||
return successResult(parsed.data)
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Booking detail (GET /bookings/:id) intentionally doesn't carry the
|
|
||||||
// event's price/title — only `eventId` — so the checkout screen needs a
|
|
||||||
// second read against the public event-detail endpoint.
|
|
||||||
export const GET_EVENT_SUMMARY = async (eventId: string, options?: ServiceCallOptions): Promise<ServiceResult<EventSummaryForPayment>> => {
|
|
||||||
try {
|
|
||||||
const res = await eventsApi.eventsControllerFindOne(eventId)
|
|
||||||
const payload = unwrapApiPayload(res.data)
|
|
||||||
|
|
||||||
if (!payload?.id) {
|
|
||||||
throw createServiceError(texts.common.invalidServerResponse)
|
|
||||||
}
|
|
||||||
|
|
||||||
return successResult({
|
|
||||||
id: payload.id as string,
|
|
||||||
slug: typeof payload.slug === 'string' ? payload.slug : null,
|
|
||||||
title: payload.title as string,
|
|
||||||
price: Number(payload.price ?? 0),
|
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// payment.md "تصمیم ۲": `walletAmount` is a single clamp-friendly number —
|
|
||||||
// the backend clamps to min(requested, wallet.balance, totalAmount)
|
|
||||||
// regardless, so the frontend just sends what the "use wallet" toggle
|
|
||||||
// implies.
|
|
||||||
export const CREATE_PAYMENT = async (
|
|
||||||
bookingId: string,
|
|
||||||
walletAmount: number,
|
|
||||||
options?: ServiceCallOptions & { discountCode?: string }
|
|
||||||
): Promise<ServiceResult<CreatePaymentResult>> => {
|
|
||||||
try {
|
|
||||||
const res = await financialApi.paymentsControllerCreate(bookingId, {
|
|
||||||
walletAmount,
|
|
||||||
discountCode: options?.discountCode?.trim() || undefined,
|
|
||||||
})
|
|
||||||
const payload = res.data
|
|
||||||
|
|
||||||
if (!payload.success) {
|
|
||||||
throw createServiceError(payload.message || texts.wallet.paymentFailed)
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = unwrapApiData(payload)
|
|
||||||
|
|
||||||
if (!result?.id) {
|
|
||||||
throw createServiceError(texts.common.invalidServerResponse)
|
|
||||||
}
|
|
||||||
|
|
||||||
return successResult(result)
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const GET_PAYMENT_RECEIPT = async (paymentId: string, options?: ServiceCallOptions): Promise<ServiceResult<PaymentReceipt>> => {
|
|
||||||
try {
|
|
||||||
const res = await financialApi.paymentsControllerReceipt(paymentId)
|
|
||||||
const parsed = paymentReceiptSchema.safeParse(unwrapApiPayload(res.data))
|
|
||||||
|
|
||||||
if (!parsed.success) throw createServiceError(texts.common.invalidServerResponse)
|
|
||||||
|
|
||||||
return successResult(parsed.data)
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
import axiosInstance from '@/config/axios'
|
|
||||||
import { unwrapApiPayload } from '@/helpers/listResponse'
|
|
||||||
|
|
||||||
export interface SettlementRequest {
|
|
||||||
id: string
|
|
||||||
settlementCode: string
|
|
||||||
organizerId: string
|
|
||||||
bankAccountId: string
|
|
||||||
totalAmount: number
|
|
||||||
status: 'pending' | 'processing' | 'completed' | 'failed'
|
|
||||||
processedAt?: string | null
|
|
||||||
failureReason?: string | null
|
|
||||||
manualTrackingCode?: string | null
|
|
||||||
manualReceiptUrl?: string | null
|
|
||||||
manualNote?: string | null
|
|
||||||
createdAt: string
|
|
||||||
updatedAt: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export const LIST_MY_SETTLEMENTS = async (): Promise<{ items: SettlementRequest[] }> => {
|
|
||||||
const response = await axiosInstance.get('settlements/me', {
|
|
||||||
params: { page: 1, pageSize: 30, sort: '-createdAt' },
|
|
||||||
})
|
|
||||||
const payload = unwrapApiPayload<{ items?: SettlementRequest[] }>(response.data)
|
|
||||||
|
|
||||||
return { items: Array.isArray(payload.items) ? payload.items : [] }
|
|
||||||
}
|
|
||||||
@ -1,117 +0,0 @@
|
|||||||
import type { UserBlockResponseDto } from '@/api/generated/models'
|
|
||||||
import {
|
|
||||||
createServiceError,
|
|
||||||
errorResult,
|
|
||||||
handleServiceError,
|
|
||||||
type ServiceCallOptions,
|
|
||||||
type ServiceResult,
|
|
||||||
shouldBubbleErrorToParent,
|
|
||||||
successResult,
|
|
||||||
} from '@/services/errorHandler'
|
|
||||||
import { unwrapApiData } from '@/services/apiResponse'
|
|
||||||
import { getUserBlocks } from '@/api/generated/user-blocks/user-blocks'
|
|
||||||
import { texts } from '@/texts'
|
|
||||||
import { parseRemittanceList } from '@/helpers/listResponse'
|
|
||||||
|
|
||||||
// docs/workflows/fa/user-blocking-reporting.md, Flow A — a directed block
|
|
||||||
// record (`blocker_id` = current user, `blocked_id` = the other user).
|
|
||||||
// Effect is mutual: once either side has a row against the other, new
|
|
||||||
// *direct* messages between them are rejected in both directions. Event
|
|
||||||
// group chats are never affected.
|
|
||||||
|
|
||||||
export type UserBlock = UserBlockResponseDto
|
|
||||||
|
|
||||||
const userBlocksApi = getUserBlocks()
|
|
||||||
|
|
||||||
export const BLOCK_USER = async (blockedId: string, options?: ServiceCallOptions): Promise<ServiceResult<UserBlock>> => {
|
|
||||||
try {
|
|
||||||
const res = await userBlocksApi.userBlocksControllerCreate({ blockedId })
|
|
||||||
const payload = res.data
|
|
||||||
|
|
||||||
if (!payload.success) {
|
|
||||||
throw createServiceError(payload.message || texts.chats.blockUserFailed, payload.code)
|
|
||||||
}
|
|
||||||
|
|
||||||
const block = unwrapApiData(payload)
|
|
||||||
|
|
||||||
if (!block?.id) {
|
|
||||||
throw createServiceError(texts.common.invalidServerResponse)
|
|
||||||
}
|
|
||||||
|
|
||||||
return successResult(block)
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const UNBLOCK_USER = async (blockedId: string, options?: ServiceCallOptions): Promise<ServiceResult<UserBlock>> => {
|
|
||||||
try {
|
|
||||||
const res = await userBlocksApi.userBlocksControllerUnblock(blockedId)
|
|
||||||
const payload = res.data
|
|
||||||
|
|
||||||
if (!payload.success) {
|
|
||||||
throw createServiceError(payload.message || texts.chats.unblockUserFailed, payload.code)
|
|
||||||
}
|
|
||||||
|
|
||||||
const block = unwrapApiData(payload)
|
|
||||||
|
|
||||||
if (!block?.id) {
|
|
||||||
throw createServiceError(texts.common.invalidServerResponse)
|
|
||||||
}
|
|
||||||
|
|
||||||
return successResult(block)
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the current user has an active block row against
|
|
||||||
* `otherUserId`. Used to toggle the header menu between «مسدود کردن» and
|
|
||||||
* «رفع مسدودیت» — there's no dedicated "is blocked" endpoint, so this
|
|
||||||
* reuses `GET /user-blocks/me?filters[blockedId]=...` (paginated, so a
|
|
||||||
* single-row page is enough to answer a yes/no question).
|
|
||||||
*
|
|
||||||
* Note: this only reflects blocks *I* created (`blocker_id = me`), not
|
|
||||||
* ones the other person may have created against me — matching the known
|
|
||||||
* gap documented in user-blocking-reporting.md ("هیچ endpoint «چه کسی مرا
|
|
||||||
* مسدود کرده» وجود ندارد").
|
|
||||||
*/
|
|
||||||
export const GET_MY_BLOCK_STATUS = async (
|
|
||||||
otherUserId: string,
|
|
||||||
options?: ServiceCallOptions
|
|
||||||
): Promise<ServiceResult<{ isBlocked: boolean }>> => {
|
|
||||||
try {
|
|
||||||
const res = await userBlocksApi.userBlocksControllerListMine({ page: 1, pageSize: 1, 'filters[blockedId]': otherUserId })
|
|
||||||
|
|
||||||
const payload = res.data
|
|
||||||
|
|
||||||
if (!payload.success) {
|
|
||||||
throw createServiceError(payload.message || texts.chats.blockStatusFailed)
|
|
||||||
}
|
|
||||||
|
|
||||||
const parsed = parseRemittanceList<UserBlock>(unwrapApiData(payload) ?? {}, 'items')
|
|
||||||
|
|
||||||
return successResult({ isBlocked: parsed.items.length > 0 })
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,131 +0,0 @@
|
|||||||
import type { CreateUserReportDto, ReportReasonResponseDto, UserReportResponseDto } from '@/api/generated/models'
|
|
||||||
import {
|
|
||||||
createServiceError,
|
|
||||||
errorResult,
|
|
||||||
handleServiceError,
|
|
||||||
type ServiceCallOptions,
|
|
||||||
type ServiceResult,
|
|
||||||
shouldBubbleErrorToParent,
|
|
||||||
successResult,
|
|
||||||
} from '@/services/errorHandler'
|
|
||||||
import { unwrapApiData } from '@/services/apiResponse'
|
|
||||||
import { getUserReports } from '@/api/generated/user-reports/user-reports'
|
|
||||||
import { texts } from '@/texts'
|
|
||||||
|
|
||||||
// docs/workflows/fa/user-blocking-reporting.md, Flow B — purely
|
|
||||||
// informational: creating a report never blocks, hides, or notifies
|
|
||||||
// anyone by itself. It only creates a `pending` row an admin reviews later.
|
|
||||||
|
|
||||||
export type ReportReason = ReportReasonResponseDto
|
|
||||||
|
|
||||||
export type UserReport = UserReportResponseDto
|
|
||||||
|
|
||||||
const userReportsApi = getUserReports()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Public, unauthenticated — safe to fetch ahead of time (e.g. when the
|
|
||||||
* report menu item is rendered) so the reason list is ready by the time
|
|
||||||
* the user opens the report form.
|
|
||||||
*/
|
|
||||||
export const LIST_REPORT_REASONS = async (options?: ServiceCallOptions): Promise<ServiceResult<ReportReason[]>> => {
|
|
||||||
try {
|
|
||||||
const res = await userReportsApi.userReportsControllerListReportReasons()
|
|
||||||
const payload = res.data
|
|
||||||
|
|
||||||
if (!payload.success) {
|
|
||||||
throw createServiceError(payload.message || texts.chats.listReportReasonsFailed)
|
|
||||||
}
|
|
||||||
|
|
||||||
return successResult(unwrapApiData(payload) ?? [])
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* At least one of `reasonId` / `description` is required — mirrors the
|
|
||||||
* backend's `CreateUserReportDto` cross-field rule
|
|
||||||
* (`user_reports_content_chk`).
|
|
||||||
*/
|
|
||||||
export const REPORT_USER = async (
|
|
||||||
reportedId: string,
|
|
||||||
payload: { reasonId?: number; description?: string },
|
|
||||||
options?: ServiceCallOptions
|
|
||||||
): Promise<ServiceResult<UserReport>> => {
|
|
||||||
try {
|
|
||||||
const res = await userReportsApi.userReportsControllerCreate({
|
|
||||||
reportedId,
|
|
||||||
...payload,
|
|
||||||
})
|
|
||||||
|
|
||||||
const responsePayload = res.data
|
|
||||||
|
|
||||||
if (!responsePayload.success) {
|
|
||||||
throw createServiceError(responsePayload.message || texts.chats.submitReportFailed, responsePayload.code)
|
|
||||||
}
|
|
||||||
|
|
||||||
const report = unwrapApiData(responsePayload)
|
|
||||||
|
|
||||||
if (!report?.id) {
|
|
||||||
throw createServiceError(texts.common.invalidServerResponse)
|
|
||||||
}
|
|
||||||
|
|
||||||
return successResult(report)
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reports one specific chat message. The server derives and persists the
|
|
||||||
* conversation, sender, and immutable message snapshot; the client cannot
|
|
||||||
* forge those moderation fields.
|
|
||||||
*/
|
|
||||||
export const REPORT_MESSAGE = async (
|
|
||||||
reportedId: string,
|
|
||||||
messageId: string,
|
|
||||||
payload: { reasonId?: number; description?: string },
|
|
||||||
options?: ServiceCallOptions
|
|
||||||
): Promise<ServiceResult<UserReport>> => {
|
|
||||||
try {
|
|
||||||
const request: CreateUserReportDto = {
|
|
||||||
reportedId,
|
|
||||||
messageId,
|
|
||||||
...payload,
|
|
||||||
}
|
|
||||||
const res = await userReportsApi.userReportsControllerCreate(request)
|
|
||||||
const responsePayload = res.data
|
|
||||||
|
|
||||||
if (!responsePayload.success) {
|
|
||||||
throw createServiceError(responsePayload.message || texts.chats.submitReportFailed, responsePayload.code)
|
|
||||||
}
|
|
||||||
|
|
||||||
const report = unwrapApiData(responsePayload)
|
|
||||||
|
|
||||||
if (!report?.id) {
|
|
||||||
throw createServiceError(texts.common.invalidServerResponse)
|
|
||||||
}
|
|
||||||
|
|
||||||
return successResult(report)
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,146 +0,0 @@
|
|||||||
import type { BankAccountOwnerType, BankAccountResponseDto, CreateBankAccountDto, WithdrawalResponseDto } from '@/api/generated/models'
|
|
||||||
import {
|
|
||||||
createServiceError,
|
|
||||||
errorResult,
|
|
||||||
handleServiceError,
|
|
||||||
type ServiceCallOptions,
|
|
||||||
type ServiceResult,
|
|
||||||
shouldBubbleErrorToParent,
|
|
||||||
successResult,
|
|
||||||
} from '@/services/errorHandler'
|
|
||||||
import { unwrapApiData } from '@/services/apiResponse'
|
|
||||||
import { getFinancial } from '@/api/generated/financial/financial'
|
|
||||||
import { parseRemittanceList, unwrapApiPayload } from '@/helpers/listResponse'
|
|
||||||
import { ANALYTICS_EVENTS, trackAnalyticsEventOnce } from '@/lib/analytics'
|
|
||||||
import { texts } from '@/texts'
|
|
||||||
|
|
||||||
// docs/workflows/fa/settlement-withdrawal.md — Path A (self-service wallet
|
|
||||||
// withdrawal). Distinct from admin settlement (Path B), which never
|
|
||||||
// touches `wallets.balance` — out of scope here.
|
|
||||||
|
|
||||||
export type { BankAccountOwnerType }
|
|
||||||
export type BankAccount = BankAccountResponseDto & {
|
|
||||||
verificationStatus?: 'pending_review' | 'approved' | 'rejected'
|
|
||||||
rejectionReason?: string | null
|
|
||||||
nationalCode?: string | null
|
|
||||||
}
|
|
||||||
export type CreateBankAccountPayload = CreateBankAccountDto & {
|
|
||||||
nationalCode?: string
|
|
||||||
}
|
|
||||||
export type WithdrawalRequest = WithdrawalResponseDto
|
|
||||||
|
|
||||||
const financialApi = getFinancial()
|
|
||||||
|
|
||||||
export const LIST_BANK_ACCOUNTS = async (options?: ServiceCallOptions): Promise<ServiceResult<BankAccount[]>> => {
|
|
||||||
try {
|
|
||||||
const res = await financialApi.bankAccountsControllerListMine()
|
|
||||||
const payload = unwrapApiPayload(res.data)
|
|
||||||
const items = Array.isArray(payload)
|
|
||||||
? payload
|
|
||||||
: Array.isArray((payload as { items?: unknown[] }).items)
|
|
||||||
? (payload as { items: unknown[] }).items
|
|
||||||
: []
|
|
||||||
|
|
||||||
return successResult(items as BankAccount[])
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const CREATE_BANK_ACCOUNT = async (
|
|
||||||
payload: CreateBankAccountPayload,
|
|
||||||
options?: ServiceCallOptions
|
|
||||||
): Promise<ServiceResult<BankAccount>> => {
|
|
||||||
try {
|
|
||||||
const res = await financialApi.bankAccountsControllerCreate(payload)
|
|
||||||
const body = res.data
|
|
||||||
|
|
||||||
if (!body.success) {
|
|
||||||
throw createServiceError(body.message || texts.wallet.bankAccountCreateFailed)
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = unwrapApiData(body)
|
|
||||||
|
|
||||||
if (!result?.id) {
|
|
||||||
throw createServiceError(texts.common.invalidServerResponse)
|
|
||||||
}
|
|
||||||
|
|
||||||
return successResult(result)
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const LIST_WITHDRAWAL_REQUESTS = async (options?: ServiceCallOptions): Promise<ServiceResult<{ items: WithdrawalRequest[] }>> => {
|
|
||||||
try {
|
|
||||||
const res = await financialApi.withdrawalRequestsControllerListMine({ page: 1, pageSize: 30, sort: '-createdAt' })
|
|
||||||
|
|
||||||
const parsed = parseRemittanceList<WithdrawalRequest>(res.data, 'items')
|
|
||||||
|
|
||||||
return successResult({ items: parsed.items })
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// amount is in Toman (platform-wide convention — see payment.md's note on
|
|
||||||
// the matching CreatePaymentDto Swagger typo; CreateWithdrawalRequestDto
|
|
||||||
// has the same "Rials" typo in its Swagger annotation).
|
|
||||||
export const CREATE_WITHDRAWAL_REQUEST = async (
|
|
||||||
bankAccountId: string,
|
|
||||||
amount: number,
|
|
||||||
options?: ServiceCallOptions
|
|
||||||
): Promise<ServiceResult<WithdrawalRequest>> => {
|
|
||||||
try {
|
|
||||||
const res = await financialApi.withdrawalRequestsControllerCreate({
|
|
||||||
bankAccountId,
|
|
||||||
amount,
|
|
||||||
})
|
|
||||||
const payload = res.data
|
|
||||||
|
|
||||||
if (!payload.success) {
|
|
||||||
throw createServiceError(payload.message || texts.wallet.withdrawalCreateFailed)
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = unwrapApiData(payload)
|
|
||||||
|
|
||||||
if (!result?.id) {
|
|
||||||
throw createServiceError(texts.common.invalidServerResponse)
|
|
||||||
}
|
|
||||||
|
|
||||||
trackAnalyticsEventOnce(ANALYTICS_EVENTS.WITHDRAWAL_REQUESTED, result.id, {
|
|
||||||
withdrawal_id: result.id,
|
|
||||||
value: amount * 10,
|
|
||||||
currency: 'IRR',
|
|
||||||
withdrawal_status: result.status,
|
|
||||||
})
|
|
||||||
|
|
||||||
return successResult(result)
|
|
||||||
} catch (error) {
|
|
||||||
const normalizedError = handleServiceError(error, options)
|
|
||||||
|
|
||||||
if (shouldBubbleErrorToParent(options)) {
|
|
||||||
throw normalizedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return errorResult(normalizedError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
import { z } from 'zod'
|
|
||||||
|
|
||||||
import { convertPersianToEnglish } from '@/helpers'
|
|
||||||
import { texts } from '@/texts'
|
|
||||||
|
|
||||||
const toEnglishDigits = (value: string) => convertPersianToEnglish(value).trim()
|
|
||||||
const v = texts.validation.identity
|
|
||||||
const nationalId = texts.validation.nationalId
|
|
||||||
|
|
||||||
export const IdentityVerificationFormValidation = z
|
|
||||||
.object({
|
|
||||||
nationalCode: z
|
|
||||||
.string()
|
|
||||||
.min(1, nationalId.nationalCodeRequired)
|
|
||||||
.refine((value) => /^\d{10}$/.test(toEnglishDigits(value)), {
|
|
||||||
message: nationalId.nationalCodeDigits,
|
|
||||||
}),
|
|
||||||
contractAccepted: z.boolean().optional(),
|
|
||||||
})
|
|
||||||
.superRefine((values, ctx) => {
|
|
||||||
if (values.contractAccepted !== true) {
|
|
||||||
ctx.addIssue({
|
|
||||||
code: 'custom',
|
|
||||||
path: ['contractAccepted'],
|
|
||||||
message: v.contractRequired,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
export const IdentityContractOtpValidation = z.object({
|
|
||||||
code: z
|
|
||||||
.string()
|
|
||||||
.min(1, v.otpRequired)
|
|
||||||
.refine((value) => /^\d{4}$/.test(toEnglishDigits(value)), {
|
|
||||||
message: v.otpDigits,
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
|
|
||||||
export type IdentityVerificationFormValues = z.infer<typeof IdentityVerificationFormValidation>
|
|
||||||
export type IdentityContractOtpValues = z.infer<typeof IdentityContractOtpValidation>
|
|
||||||
|
|
||||||
export const normalizeNationalCode = (value: string) => toEnglishDigits(value)
|
|
||||||
export const normalizeOtpCode = (value: string) => toEnglishDigits(value)
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
import { z } from 'zod'
|
|
||||||
|
|
||||||
import { texts } from '@/texts'
|
|
||||||
|
|
||||||
const v = texts.validation.profile
|
|
||||||
const person = texts.validation.person
|
|
||||||
|
|
||||||
export const UpdateProfileFormValidation = z.object({
|
|
||||||
firstName: z.string().trim().min(1, person.firstNameRequired).max(100, person.firstNameMax),
|
|
||||||
lastName: z.string().trim().min(1, person.lastNameRequired).max(100, person.lastNameMax),
|
|
||||||
// z.enum keeps input/output identical so zodResolver matches useForm<UpdateProfileFormValues>
|
|
||||||
gender: z.enum(['male', 'female'], { message: person.genderRequired }),
|
|
||||||
bio: z.string().trim().max(2000, v.bioMax).optional().or(z.literal('')),
|
|
||||||
// انتخاب استان فعلاً در فرم پروفایل غیرفعال است.
|
|
||||||
// provinceId: z.string().optional().or(z.literal('')),
|
|
||||||
cityId: z.string().optional().or(z.literal('')),
|
|
||||||
defaultAddress: z.string().trim().max(500, v.addressMax).optional().or(z.literal('')),
|
|
||||||
})
|
|
||||||
|
|
||||||
export type UpdateProfileFormValues = z.infer<typeof UpdateProfileFormValidation>
|
|
||||||
Loading…
Reference in New Issue
Block a user