feat(seller): mobile brand header redesign (cover + overlapping logo)
Bring the seller page mobile header in line with the design / desktop: replace the plain top bar + centered logo with a cover banner, a floating circular back button (safe-area aware), an overlapping rounded logo, the store name + verified badge + @handle, a clean borderless stats row (محصول / دنبالکننده / امتیاز), the description, and follow + message-icon actions. Search bar and product masonry unchanged. Desktop untouched. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
252d3f8f50
commit
e6574b1e9e
@ -19,8 +19,9 @@ import {
|
||||
UserMinus,
|
||||
Shirt,
|
||||
BadgeCheck,
|
||||
ArrowRight,
|
||||
MessageCircle,
|
||||
} from "lucide-react";
|
||||
import HeaderWithSupport from "../components/HeaderWithSupport";
|
||||
import { useState, useEffect } from "react";
|
||||
import { DrawerContent, Drawer } from "../components/ui/drawer";
|
||||
import { Button } from "../components/ui/button";
|
||||
@ -283,96 +284,115 @@ export default function Seller() {
|
||||
<div className="border-b border-WHITE3 mt-6" />
|
||||
</div>
|
||||
|
||||
{/* Mobile header */}
|
||||
<div className="relative lg:hidden">
|
||||
<HeaderWithSupport
|
||||
title={seller?.storeName || ""}
|
||||
onBack={handleBack}
|
||||
/>
|
||||
<div className="flex flex-col items-center justify-center gap-2 pt-2">
|
||||
<SellerLogo src={seller?.storeLogo} alt="store logo" />
|
||||
{/* Mobile brand header (cover + overlapping logo + stats + actions) */}
|
||||
<div className="lg:hidden">
|
||||
{/* Cover */}
|
||||
<div className="relative h-[150px] bg-gradient-to-br from-VITROWN_BLUE to-[#14213d]">
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-black/35 to-transparent" />
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleBack}
|
||||
aria-label="بازگشت"
|
||||
className="absolute z-20 right-4 w-10 h-10 rounded-full bg-WHITE/90 backdrop-blur shadow-md flex items-center justify-center text-BLACK"
|
||||
style={{ top: "calc(env(safe-area-inset-top, 0px) + 12px)" }}
|
||||
>
|
||||
<ArrowRight size={22} />
|
||||
</button>
|
||||
</div>
|
||||
{/* Head */}
|
||||
<div className="px-4 -mt-10 relative z-10">
|
||||
<div className="w-[84px] h-[84px] rounded-[24px] border-4 border-WHITE shadow-md overflow-hidden bg-WHITE3">
|
||||
{seller?.storeLogo ? (
|
||||
<img
|
||||
src={seller.storeLogo}
|
||||
alt={seller?.storeName || "store"}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
<h1 className="flex items-center gap-1.5 text-[21px] font-extrabold mt-3">
|
||||
{seller?.storeName}
|
||||
{seller?.isVerified ? (
|
||||
<BadgeCheck className="text-BLUE" size={18} />
|
||||
) : null}
|
||||
</h1>
|
||||
{seller?.username ? (
|
||||
<p className="text-GRAY text-[13px] mt-0.5" dir="ltr">
|
||||
@{seller.username}
|
||||
</p>
|
||||
) : null}
|
||||
{/* Stats */}
|
||||
<div className="flex gap-8 py-3.5 mt-3 border-y border-WHITE3">
|
||||
<div>
|
||||
<b className="block text-[17px] font-extrabold">
|
||||
{seller?.productCount ?? 0}
|
||||
</b>
|
||||
<span className="text-GRAY text-[11.5px]">محصول</span>
|
||||
</div>
|
||||
<div>
|
||||
<b className="block text-[17px] font-extrabold">
|
||||
{seller?.followerCount ?? 0}
|
||||
</b>
|
||||
<span className="text-GRAY text-[11.5px]">دنبالکننده</span>
|
||||
</div>
|
||||
<div>
|
||||
<b className="flex items-center gap-1 text-[17px] font-extrabold">
|
||||
{seller?.productReviewsCount ? seller?.reviewAverage : "—"}
|
||||
{seller?.productReviewsCount ? (
|
||||
<Star size={14} className="fill-BLACK" />
|
||||
) : null}
|
||||
</b>
|
||||
<span className="text-GRAY text-[11.5px]">امتیاز</span>
|
||||
</div>
|
||||
</div>
|
||||
{/* Description */}
|
||||
{seller?.storeDescription ? (
|
||||
<div className="mt-3">
|
||||
<ReadMoreText
|
||||
sellerData={seller}
|
||||
text={seller?.storeDescription || ""}
|
||||
maxLength={150}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
{/* Actions */}
|
||||
<div className="flex gap-2.5 mt-4">
|
||||
<Button
|
||||
variant="dark"
|
||||
size="lg"
|
||||
className="flex-1"
|
||||
onClick={handleFollowToggle}
|
||||
disabled={isFollowMutating || isFollowStatusLoading}
|
||||
>
|
||||
{isFollowed ? (
|
||||
<>
|
||||
<Check size={22} />
|
||||
دنبال شده
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<UserPlus size={22} />
|
||||
دنبال کردن
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="lg"
|
||||
className="shrink-0 px-4"
|
||||
aria-label="ارسال پیام"
|
||||
onClick={() => {
|
||||
handleCreateChatThread();
|
||||
}}
|
||||
disabled={!seller?.id || isCreatingChatThread}
|
||||
>
|
||||
<MessageCircle size={22} />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full">
|
||||
<div className="w-full p-4 lg:hidden">
|
||||
<div className="flex px-4 border bg-WHITE3 rounded-[10px] w-full py-2">
|
||||
<div className="w-full border-l flex-2 flex flex-col items-center justify-center">
|
||||
<p className="text-R12">{seller?.followerCount}</p>
|
||||
<p className="text-R12">دنبال کننده</p>
|
||||
</div>
|
||||
<div className="w-full flex-3 flex flex-col items-center justify-center">
|
||||
{seller?.productReviewsCount ? (
|
||||
<>
|
||||
<div className="flex items-center gap-1">
|
||||
<p className="text-R12">{seller?.reviewAverage}</p>
|
||||
<p className="text-R8">
|
||||
(از {seller?.productReviewsCount} نظر)
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-1 items-center flex-row-reverse">
|
||||
{Array.from({ length: 5 }).map((_, index) => (
|
||||
<Star
|
||||
key={index}
|
||||
className={
|
||||
index < (seller?.reviewAverage || 0)
|
||||
? "fill-BLACK"
|
||||
: "fill-White"
|
||||
}
|
||||
size={12}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<p className="text-R12">بدون امتیاز</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="w-full border-r flex-2 flex flex-col items-center justify-center">
|
||||
<p className="text-R12">{seller?.productCount}</p>
|
||||
<p className="text-R12">تعداد محصولات</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-6 px-4 lg:hidden">
|
||||
<ReadMoreText
|
||||
sellerData={seller}
|
||||
text={seller?.storeDescription || ""}
|
||||
maxLength={150}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-4 px-4 w-full flex py-4 gap-4 lg:hidden">
|
||||
<Button
|
||||
variant="dark"
|
||||
size="lg"
|
||||
className="w-full"
|
||||
onClick={handleFollowToggle}
|
||||
disabled={isFollowMutating || isFollowStatusLoading}
|
||||
>
|
||||
{isFollowed ? (
|
||||
<>
|
||||
<Check size={24} />
|
||||
دنبال شده
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<UserPlus size={24} />
|
||||
دنبال کردن
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={() => {
|
||||
handleCreateChatThread();
|
||||
}}
|
||||
disabled={!seller?.id || isCreatingChatThread}
|
||||
size="lg"
|
||||
className="w-full"
|
||||
>
|
||||
{isCreatingChatThread ? "در حال اتصال..." : "ارسال پیام"}
|
||||
</Button>
|
||||
</div>
|
||||
{/* Search Bar (mobile) */}
|
||||
<div className="lg:hidden">
|
||||
<SearchTopBar
|
||||
|
||||
Loading…
Reference in New Issue
Block a user