- 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.