- HeaderWithSupport is now lg:hidden (all its callers are desktop-full-width
store/profile pages), removing the stray mobile back+support bar on desktop.
- Constrain + title the previously mobile-only pages so their content doesn't
stretch edge-to-edge on desktop: store edit/create form (StoreForm), add
product, shipping method, financial sub-pages (cash-funds/reports/
transactions), order detail, instagram auth; and profile add/edit address,
set detail, and payment result. Forms use a narrow centered column, lists/
details a wider one. Transactions keeps its filter button (header restyled,
not hidden).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- useMyStores + team hooks (invite by phone / list / remove) in use-seller-hooks.
- useStoreOwnership rewritten to allow staff (not just the owner) via my-stores;
exposes `role` so callers can gate owner-only UI, and no longer redirects
members away from a store they help manage.
- Store settings: owner-only items (financial, shipping, edit store, instagram
sync, team) hidden from staff; new "مدیریت اعضای تیم" entry (owner-only).
- New /store/:storeId/team page: invite by phone + members list with pending/
active status + remove (owner-only, redirects staff). MyLayout keeps store mode
on the team route.
- StoreForm edit is owner-only (redirects staff). Profile "enter my store" now
routes owners to their store and staff to the store they manage.
- Chat already split earlier: seller inbox vs personal buyer inbox.
Depends on the seller-team backend; ships on this branch, not main.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Banner editor in store edit: color swatches + custom color picker, or
image/GIF upload with a 1600x500 dimension hint. Renders the chosen banner
(image cover / solid color) on the public seller page, falling back to the
default gradient.
- Sellers list: drop the desktop name overlay (match mobile, image-only tiles).
- Seller page mobile header: chat moved top-left under the banner, search+filter
beside the follow button, followers/product counts removed (rating kept),
compacted so products fill more of the screen, circular logo, thinner action row.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Most browsers (everything but Safari/WebKit) can't decode HEIC in <img> or
canvas, so picking an iPhone HEIC photo broke the preview and the crop editor,
and could reach the backend in a format it couldn't process. Convert HEIC/HEIF
to JPEG right after selection via heic2any (dynamically imported, browser-only).
- new util app/utils/convert-heic.ts: isHeic() detection (MIME or extension
when iOS reports no type) + convertHeicToJpeg()/convertHeicFiles(); never
throws — falls back to the original file on failure.
- wired into the product image picker (store.add.manual) and the store
logo picker (StoreForm).
- adds heic2any dependency.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The crop canvas was sized to cropArea.width/height, which are the editor's
on-screen (CSS) pixels — a few hundred px. Phone photos were therefore
downscaled to that size before upload, so cropped product images came out
blurry (most visibly on iPhone, whose source photos are large).
Size the canvas to the crop region in the source image's native pixels
(adjustedCropWidth/Height, already computed) and draw 1:1. Bumped JPEG
quality 0.9 -> 0.92. The backend still caps the final image to 1600px webp,
so output size stays bounded.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>