- ModalEditProfile now lets users optionally change email, password,
and card number, plus a two-step OTP flow to change their mobile
number. All fields remain optional except when actively submitted.
- Particle background: dropped canvas shadowBlur and the warp effect
on links (the most expensive per-frame draw calls), disabled
detectRetina (was rendering at 2-3x resolution on high-DPI
screens), capped fps at 30, and paused rendering when the tab is
hidden or the canvas is out of viewport (pauseOnBlur /
pauseOnOutsideViewport) — this was the main site-wide slowdown
since it renders on every page via the root layout.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replaces the hardcoded "⚠️ اتصال سرویسها" text (shown for every product)
with data.has_connection_notice / data.connection_notice from the
config's own see() response, so it's opt-in per service instead of
always-on for the whole category.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
For categories with has_extra_description, the buy button now stays
disabled until the user ticks "توضیحات سرویس را مطالعه کردم" — mirrors
the pattern used for the Shahkar/advanced-verification gates.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Wires up the previously-disabled "edit profile" button/modal to save
national_id via POST /profile/national-id, so it's no longer only
collectible through the inline field during a Shahkar-gated purchase.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
When the backend responds with requires_shahkar_verification (for
purchases between the 100M and 200M thresholds), show an inline
national-code input instead of failing outright, and resubmit the
buy request with nationalCode once the user fills it in.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Putting "آموزش" only inside the DNS management modal wasn't enough -
mobile users expect a direct button next to "مدیریت DNS", same as
the desktop row already has.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The "آموزش" button only appeared in the desktop-only action row, and
the modal that opens for DNS on mobile (ModalDnsConfig) never had a
tutorial link at all, unlike ModalConfigDetails for other config
types. DNS users therefore had no way to reach /tutorial on mobile.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Matches the admin's new repeater (emoji + title + items per section)
instead of a single plain-text block.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replaces the hardcoded DNS-only content and isDns/category-label check
with data from the config's `has_extra_description` / `extra_description`
fields, so any product can opt into showing free-text extra info.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Media (images/videos) now render in a responsive grid with a
full-screen lightbox on tap instead of a stacked full-width column.
- Multiple attached files (attachments[]) each get their own icon,
title, and download button, replacing the single hidden file link.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Render the download button for a tutorial's uploaded file field
(it was fetched from the API but never displayed).
- Recognize mov/avi/wmv as video (the backend already accepts them as
uploads) and add a download fallback for any media type the browser
can't play inline instead of a dead "unknown file type" message.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KMLvfLviDB12t4U9UijE4k
- Drop the now-unused "expired" filter option/status (the API never
returns expired services anymore).
- Show the order code next to each service in the config card and in
the service details modal.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KMLvfLviDB12t4U9UijE4k
This commit adds functionality to the layout component to retrieve the shop ID from the URL query parameters and dispatch it to the Redux store using the setShopId action.
This commit updates the useAxios hook to include the Shop-ID header in the request configuration. It retrieves the shop ID from the state and adds it to the headers if it exists. This change ensures that the Shop-ID is sent along with the request when making API calls.
Co-authored-by: [Author Name]