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,
|
UserMinus,
|
||||||
Shirt,
|
Shirt,
|
||||||
BadgeCheck,
|
BadgeCheck,
|
||||||
|
ArrowRight,
|
||||||
|
MessageCircle,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import HeaderWithSupport from "../components/HeaderWithSupport";
|
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { DrawerContent, Drawer } from "../components/ui/drawer";
|
import { DrawerContent, Drawer } from "../components/ui/drawer";
|
||||||
import { Button } from "../components/ui/button";
|
import { Button } from "../components/ui/button";
|
||||||
@ -283,96 +284,115 @@ export default function Seller() {
|
|||||||
<div className="border-b border-WHITE3 mt-6" />
|
<div className="border-b border-WHITE3 mt-6" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Mobile header */}
|
{/* Mobile brand header (cover + overlapping logo + stats + actions) */}
|
||||||
<div className="relative lg:hidden">
|
<div className="lg:hidden">
|
||||||
<HeaderWithSupport
|
{/* Cover */}
|
||||||
title={seller?.storeName || ""}
|
<div className="relative h-[150px] bg-gradient-to-br from-VITROWN_BLUE to-[#14213d]">
|
||||||
onBack={handleBack}
|
<div className="absolute inset-0 bg-gradient-to-t from-black/35 to-transparent" />
|
||||||
/>
|
<button
|
||||||
<div className="flex flex-col items-center justify-center gap-2 pt-2">
|
type="button"
|
||||||
<SellerLogo src={seller?.storeLogo} alt="store logo" />
|
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>
|
</div>
|
||||||
|
|
||||||
<div className="w-full">
|
<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) */}
|
{/* Search Bar (mobile) */}
|
||||||
<div className="lg:hidden">
|
<div className="lg:hidden">
|
||||||
<SearchTopBar
|
<SearchTopBar
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user