PageSourceSearch

https://petwellhk.com/assets/ReviewProduct-D7E0kHyR.js

js petwellhk.com collected 2026-10-06 05:23:34 UTC 51,698 bytes, 102 lines download raw bytes

1import{r as m,j as e,p as et,N as ke,L as W}from"./react-vendor-BDHNqS4B.js";import{b as Me}from"./Header-BkbupWq-.js";import{F as Te}from"./Footer-CtylQEAH.js";import{c as Ee,e as Be,D as Fe,j as Oe,k as tt,l as ze,m as _e,L as X,I as te,o as rt,B as K,ai as He,U as M,b as O,n as fe,a4 as J,h as st,u as at,A as it}from"./main-m_sUF2N4.js";import{R as nt,a as lt}from"./radio-group-8WfHeakx.js";import{T as Ke}from"./textarea-D7qsgB_p.js";import{b as ot,e as ct}from"./reportService-tEzofQZ6.js";import{b as me,R as dt}from"./ReviewPriceDisplay-DfIoLGNY.js";import{W as Se}from"./WishlistHeartButton-XMsXQ-jB.js";import{u as mt}from"./useSEO-CoArDrdl.js";import{b as ut,c as xt,T as pt,g as ht}from"./usePriceReviewProducts-BeYKlbKA.js";import{e as ft,d as gt,i as ue,j as G,r as vt}from"./priceReviewPricing-BlvAWvXm.js";import{S as jt,R as wt,F as ge}from"./ReviewAuthorLink-IWaLqPnT.js";import{S as re}from"./star-Dim9pf51.js";import{u as Nt,c as ve,d as je}from"./query-7-WHkg5t.js";import{T as yt}from"./trash-2-e__PZJrZ.js";import{C as ie,A as qe}from"./chevron-right-CpkQxGj-.js";import{C as bt}from"./clock-CRHi7pcr.js";import{S as xe}from"./store-DWI30bPC.js";import{E as pe}from"./external-link-BIpC4MGv.js";import{S as Rt}from"./share-2-CCPUIaWa.js";import{S as Pt}from"./scale-B2l5za8q.js";import{S as kt}from"./shield-check-we62WOC3.js";import{S as St}from"./sparkles-BcmYxR0H.js";import{B as Ct}from"./badge-check-CHAeghjg.js";import{C as $t}from"./calendar-KPQ2FJpt.js";import"./amplify-DYDcjoow.js";import"./check-DS0-tR9o.js";import"./tag-D40gy_Nl.js";import"./phone-B2rvvDkK.js";import"./type-CVgQCqWZ.js";import"./index-CFf87M6S.js";import"./heart-DRwCktcb.js";import"./priceReviewApi-BFijUeFQ.js";import"./userReviewApi-BPRYI5-q.js";/**
2 * @license lucide-react v0.462.0 - ISC
3 *
4 * This source code is licensed under the ISC license.
5 * See the LICENSE file in the root directory of this source tree.
6 */const Dt=Ee("Pencil",[["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}],["path",{d:"m15 5 4 4",key:"1mk7zo"}]]);/**
7 * @license lucide-react v0.462.0 - ISC
8 *
9 * This source code is licensed under the ISC license.
10 * See the LICENSE file in the root directory of this source tree.
11 */const Ue=Ee("Truck",[["path",{d:"M14 18V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v11a1 1 0 0 0 1 1h2",key:"wrbu53"}],["path",{d:"M15 18H9",key:"1lyqi6"}],["path",{d:"M19 18h2a1 1 0 0 0 1-1v-3.65a1 1 0 0 0-.22-.624l-3.48-4.35A1 1 0 0 0 17.52 8H14",key:"lysw3i"}],["circle",{cx:"17",cy:"18",r:"2",key:"332jqn"}],["circle",{cx:"7",cy:"18",r:"2",key:"19iecd"}]]),Ce=[{value:"price",label:"價格有誤"},{value:"discontinued",label:"產品已下架"},{value:"image_name",label:"圖片或名稱不對"},{value:"store_missing",label:"此店舖沒有此產品"},{value:"other",label:"其他"}],It=({open:t,onOpenChange:r,productId:l,productName:o,storeName:u})=>{const{isAuthenticated:i,userInfo:n}=Be(),f=i===!0,[v,b]=m.useState("price"),[N,A]=m.useState(""),[z,s]=m.useState(""),[j,R]=m.useState(""),[T,E]=m.useState(""),[P,$]=m.useState(!1);m.useEffect(()=>{if(!t)return;(async()=>{var D;if(!f||!(n!=null&&n.email))return;const y=n.username&&!n.username.includes("@")?n.username:"";R(n.email),s(I=>I||y);try{const h=[...await He(n.rawEmail||n.email)].sort((H,x)=>{const S=C=>{var B,d,q;return+!!((B=C.firstName)!=null&&B.trim())+ +!!((d=C.lastName)!=null&&d.trim())+ +!!((q=C.phone)!=null&&q.trim())};return S(x)-S(H)})[0],_=[h==null?void 0:h.firstName,h==null?void 0:h.lastName].filter(Boolean).join(" ").trim();s(_||y||n.email),E(((D=h==null?void 0:h.phone)==null?void 0:D.trim())||"")}catch(I){console.warn("Unable to prefill price report contact info:",I),s(h=>h||y||n.email)}})()},[t,f,n==null?void 0:n.email,n==null?void 0:n.rawEmail,n==null?void 0:n.username]);const g=()=>{b("price"),A(""),f||(s(""),R(""),E(""))},p=c=>{!c&&!P&&g(),r(c)},k=async()=>{var H,x;const c=j.trim().toLowerCase(),y=T.trim(),D=z.trim(),I=/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(c);if(!f&&(!c||!y||!I)){M.error("請填寫有效電郵及電話號碼");return}const h=((H=Ce.find(S=>S.value===v))==null?void 0:H.label)??v,_=["[Price / Product Data Report]",`Product ID: ${l}`,`Product: ${o}`,u?`Store: ${u}`:null,`Reason: ${h}`,N.trim()?`Note: ${N.trim().slice(0,1e3)}
11`:null].filter(Boolean).join(`
12`);$(!0);try{const S=((x=n==null?void 0:n.email)==null?void 0:x.trim().toLowerCase())||"";await ot({reporterId:f?(n==null?void 0:n.userId)??null:null,feedbackCategory:"BUG",message:_,contact:{reporterName:D||(n!=null&&n.username&&!n.username.includes("@")?n.username:S)||"Guest",reporterEmail:c||S,reporterPhone:y}}),M.success("多謝你的舉報!我哋會盡快核查。",{duration:3e3}),g(),r(!1)}catch(S){console.error("Failed to submit price report:",S),M.error("暫時未能提交,請稍後再試")}finally{$(!1)}};return e.jsx(Fe,{open:t,onOpenChange:p,children:e.jsxs(Oe,{className:"max-w-md",children:[e.jsxs(tt,{children:[e.jsx(ze,{children:"舉報資料問題"}),e.jsx(_e,{className:"line-clamp-2",children:u?`${u} · ${o}`:o})]}),e.jsx(nt,{value:v,onValueChange:b,className:"gap-3 py-2",children:Ce.map(c=>e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(lt,{value:c.value,id:`reason-${c.value}`}),e.jsx(X,{htmlFor:`reason-${c.value}`,className:"cursor-pointer font-normal",children:c.label})]},c.value))}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(X,{htmlFor:"report-note",className:"text-sm",children:"補充說明(選填)"}),e.jsx(Ke,{id:"report-note",value:N,onChange:c=>A(c.target.value.slice(0,1e3)),placeholder:"例如:實際價格、缺貨日期等",rows:3})]}),!f&&e.jsxs("div",{className:"space-y-3 rounded-lg border bg-muted/30 p-3",children:[e.jsx("p",{className:"text-sm font-medium",children:"聯絡資料"}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(X,{htmlFor:"price-report-name",className:"text-xs text-muted-foreground",children:"姓名(選填)"}),e.jsx(te,{id:"price-report-name",value:z,onChange:c=>s(c.target.value),placeholder:"請輸入姓名"})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(X,{htmlFor:"price-report-email",className:"text-xs text-muted-foreground",children:"電郵 *"}),e.jsx(te,{id:"price-report-email",type:"email",value:j,onChange:c=>R(c.target.value),placeholder:"[email protected]"})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(X,{htmlFor:"price-report-phone",className:"text-xs text-muted-foreground",children:"電話號碼 *"}),e.jsx(te,{id:"price-report-phone",type:"tel",value:T,onChange:c=>E(c.target.value),placeholder:"請輸入電話"})]})]}),e.jsx(rt,{children:e.jsx(K,{onClick:k,disabled:P,className:"w-full sm:w-auto",children:P?"提交中…":"提交舉報"})})]})})},At=[{pattern:/receive tomorrow if the order placed before 10pm/i,zh:"晚上 10 點前下單,最快明天送達"},{pattern:/free shipping on order delivered by hktvmall at a specific purchase amount/i,zh:"HKTVmall 派送訂單滿指定金額免運費"},{pattern:/the product will be delivered by hktvmall/i,zh:"由 HKTVmall 派送"},{pattern:/enjoy free delivery for orders above hkd\s?(\d+)/i,zh:"滿 HK$$1 免運費"},{pattern:/free shipping for orders above hkd\s?(\d+)/i,zh:"滿 HK$$1 免運費"},{pattern:/free shipping/i,zh:"免運費"},{pattern:/8-?hour delivery|h-?our delivery/i,zh:"8 小時送貨"}];function he(t,r){const l=String(t||"").trim();if(!l)return"運費以店舖頁面為準";if(r!=null&&r.toLowerCase().startsWith("en")||Mt(l))return l;const o=l.split(/\s*[.;]\s*/).map(u=>Lt(u.trim())).filter(Boolean);return o.length?Tt(o).join(";"):l}function Lt(t){if(!t)return"";for(const r of At)if(r.pattern.test(t))return t.replace(r.pattern,r.zh);return t}function Mt(t){return/[\u3400-\u9fff]/.test(t)}function Tt(t){return[...new Set(t)]}const $e={1:"非常差",2:"不太滿意",3:"普通",4:"滿意",5:"非常好"},ne=10,le=1e3;function Et({open:t,onOpenChange:r,productName:l,editingReview:o,isSaving:u,onSubmit:i,initialValues:n=null,requireLoginToPost:f=!1}){const[v,b]=m.useState(5),[N,A]=m.useState(0),[z,s]=m.useState(""),[j,R]=m.useState(""),[T,E]=m.useState(!1),[P,$]=m.useState(!1),[g,p]=m.useState(!1),k=m.useRef(null),c=m.useRef(null);m.useEffect(()=>{var C,B;if(!t){c.current=null;return}const x=n?{rating:n.rating??5,title:n.title??"",description:n.description??"",anonymous:!!n.anonymous,showTitle:!!n.showTitle||!!((C=n.title)!=null&&C.trim()),mode:o?"edit-draft":"draft",id:(o==null?void 0:o.id)??"draft"}:o?{rating:o.rating,title:o.title??"",description:o.description??"",anonymous:!!o.anonymous,showTitle:!!((B=o.title)!=null&&B.trim()),mode:"edit",id:o.id}:{rating:5,title:"",description:"",anonymous:!1,showTitle:!1,mode:"defaults",id:"defaults"},S=JSON.stringify(x);c.current!==S&&(c.current=S,b(x.rating&&x.rating>=1?x.rating:5),s(x.title),R(x.description),E(x.anonymous),$(x.showTitle),p(!1),A(0))},[t,o,n]);const y=N||v,D=j.trim(),I=D.length>0&&D.length<ne,h=D.length>=ne&&v>=1,_=m.useMemo(()=>$e[y]??"請選擇評分",[y]),H=()=>{p(!0),h&&i({rating:v,title:z.trim(),description:D,anonymous:T})};return e.jsx(Fe,{open:t,onOpenChange:r,children:e.jsxs(Oe,{className:"flex max-h-[min(92vh,720px)] max-w-lg flex-col gap-0 overflow-hidden border-[hsl(var(--review-line))] p-0 sm:rounded-lg",children:[e.jsxs("div",{className:"shrink-0 border-b border-[hsl(var(--review-line))] bg-[hsl(var(--review-canvas))]/40 px-5 py-4 sm:px-6",children:[e.jsx(ze,{className:"text-[17px] font-semibold tracking-tight",children:o?"編輯評價":"撰寫產品評價"}),e.jsx(_e,{className:"mt-1 line-clamp-2 text-[13px] leading-relaxed text-muted-foreground",children:l})]}),e.jsxs("div",{className:"min-h-0 flex-1 overflow-y-auto px-5 py-5 sm:px-6",children:[e.jsxs("section",{className:"rounded-lg border border-[hsl(var(--review-line))] bg-white px-4 py-5",children:[e.jsx("p",{className:"text-center text-[12px] font-medium uppercase tracking-wide text-muted-foreground",children:"整體評分"}),e.jsx("p",{className:O("mt-2 text-center text-[15px] font-semibold transition-colors",y?"text-foreground":"text-muted-foreground"),"aria-live":"polite",children:_}),e.jsx("div",{className:"mt-4 flex items-center justify-center gap-2",role:"radiogroup","aria-label":"產品評分",children:[1,2,3,4,5].map(x=>{const S=x<=y;return e.jsx("button",{type:"button",role:"radio","aria-checked":v===x,"aria-label":`${x} 星 · ${$e[x]}`,className:O("flex h-11 w-11 items-center justify-center rounded-full transition-all","focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2",S?"scale-105":"scale-100 opacity-70 hover:opacity-100"),onMouseEnter:()=>A(x),onMouseLeave:()=>A(0),onFocus:()=>A(x),onBlur:()=>A(0),onClick:()=>{b(x),p(!1),window.requestAnimationFrame(()=>{var C;return(C=k.current)==null?void 0:C.focus()})},children:e.jsx(re,{className:O("h-8 w-8 transition-colors",S?"fill-amber-400 text-amber-400":"text-muted-foreground
12/40")})},x)})})]}),e.jsxs("section",{className:"mt-5",children:[e.jsxs("div",{className:"flex items-baseline justify-between gap-2",children:[e.jsxs("label",{htmlFor:"review-body",className:"text-[13px] font-semibold text-foreground",children:["評價內容",e.jsx("span",{className:"ml-1 text-primary",children:"*"})]}),e.jsxs("span",{className:O("text-[11px] tabular-nums",j.length>le?"text-destructive":"text-muted-foreground"),children:[j.length,"/",le]})]}),e.jsx("p",{className:"mt-1 text-[12px] leading-relaxed text-muted-foreground",children:"分享寵物食後反應、品質或性價比,幫助其他主人做決定。"}),e.jsx(Ke,{id:"review-body",ref:k,value:j,onChange:x=>R(x.target.value.slice(0,le)),onBlur:()=>p(!0),placeholder:"例如:我隻狗食咗兩星期,毛色同精神都好好,性價比高。",className:O("mt-2.5 min-h-[180px] resize-none rounded-md border-[hsl(var(--review-line))] text-[14px] leading-relaxed",g&&I&&"border-destructive/60 focus-visible:ring-destructive/30")}),g&&!D?e.jsx("p",{className:"mt-1.5 text-[12px] text-destructive",children:"請填寫評價內容"}):null,g&&I?e.jsxs("p",{className:"mt-1.5 text-[12px] text-destructive",children:["請至少輸入 ",ne," 個字,方便其他用家了解你的體驗"]}):null,e.jsx("div",{className:"mt-3",children:P?e.jsxs("div",{children:[e.jsx("label",{htmlFor:"review-title",className:"text-[13px] font-medium text-muted-foreground",children:"標題(可選)"}),e.jsx(te,{id:"review-title",value:z,onChange:x=>s(x.target.value),placeholder:"一句話總結,例如:適口性高",className:"mt-1.5 border-[hsl(var(--review-line))] text-[14px]",maxLength:80})]}):e.jsx("button",{type:"button",className:"text-[13px] font-medium text-primary hover:underline",onClick:()=>$(!0),children:"+ 加入標題(可選)"})})]}),e.jsxs("section",{className:"mt-5 flex items-center justify-between gap-4 rounded-lg border border-[hsl(var(--review-line))] bg-[hsl(var(--review-canvas))]/25 px-4 py-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"text-[13px] font-medium text-foreground",children:"匿名發佈"}),e.jsx("p",{className:"mt-0.5 text-[12px] text-muted-foreground",children:"其他人只會見到「PetWell 用戶」"})]}),e.jsx(jt,{id:"review-anonymous",checked:T,onCheckedChange:E,"aria-label":"匿名發佈評價"})]})]}),e.jsxs("div",{className:"shrink-0 border-t border-[hsl(var(--review-line))] bg-white px-5 py-4 sm:px-6",children:[f&&!o?e.jsx("p",{className:"mb-3 text-center text-[12px] text-muted-foreground",children:"需要登入或建立帳戶後才能發佈評價,你寫嘅內容會被保留"}):null,e.jsxs("div",{className:"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",children:[e.jsx(K,{type:"button",variant:"ghost",className:"h-10 text-[13px] text-muted-foreground",onClick:()=>r(!1),disabled:u,children:"取消"}),e.jsx(K,{type:"button",className:"h-10 min-w-[120px] rounded-md text-[14px] font-semibold",onClick:H,disabled:u||!h,children:u?e.jsxs(e.Fragment,{children:[e.jsx(fe,{className:"mr-2 h-4 w-4 animate-spin"}),"提交中…"]}):o?"儲存評價":f?"登入並發佈":"發佈評價"})]}),e.jsx("p",{className:"mt-2 text-center text-[11px] text-muted-foreground sm:text-right",children:"每位用戶只可為同一產品評價一次"})]})]})})}const Bt=`
13  query ProductReviewsByProductIdAndCreatedAt(
14    $productId: ID!
15    $createdAt: ModelStringKeyConditionInput
16    $sortDirection: ModelSortDirection
17    $limit: Int
18    $nextToken: String
19  ) {
20    productReviewsByProductIdAndCreatedAt(
21      productId: $productId
22      createdAt: $createdAt
23      sortDirection: $sortDirection
24      limit: $limit
25      nextToken: $nextToken
26    ) {
27      items {
28        id
29        reviewerId
30        reviewer {
31          id
32          firstName
33          lastName
34          displayName
35          profileImage
36        }
37        title
38        description
39        rating
40        fileAttachments
41        productId
42        source
43        anonymous
44        createdAt
45      }
46      nextToken
47    }
48  }
49`,Ft=`
50  mutation CreateProductReview($input: CreateProductReviewInput!) {
51    createProductReview(input: $input) {
52      id
53      reviewerId
54      title
55      description
56      rating
57      fileAttachments
58      anonymous
59      productId
60      source
61      createdAt
62    }
63  }
64`,Ot=`
65  mutation UpdateProductReview($input: UpdateProductReviewInput!) {
66    updateProductReview(input: $input) {
67      id
68      reviewerId
69      title
70      description
71      rating
72      fileAttachments
73      anonymous
74      productId
75      source
76      createdAt
77      updatedAt
78    }
79  }
80`,zt=`
81  mutation DeleteProductReview($input: DeleteProductReviewInput!) {
82    deleteProductReview(input: $input) {
83      id
84      productId
85      rating
86    }
87  }
88`,_t=`
89  mutation UpdatePriceProductRating(
90    $productId: ID!
91    $reviewRating: Float!
92    $delta: Int!
93    $oldReviewRating: Float
94  ) {
95    updatePriceProductRating(
96      productId: $productId
97      reviewRating: $reviewRating
98      delta: $delta
99      oldReviewRating: $oldReviewRating
100    )
101  }
102`;async function Ht(t,r){return(await J(Bt,{productId:t,sortDirection:"DESC",limit:r==null?void 0:r.limit,nextToken:(r==null?void 0:r.nextToken)??void 0},{authMode:"apiKey"})).productReviewsByProductIdAndCreatedAt}async function Kt(t){const r=await J(Ft,{input:{...t,source:"petwell"}},{authMode:"userPool"});return we({productId:t.productId,reviewRating:t.rating,delta:1}).catch(()=>{}),r.createProductReview}async function qt(t,r){const l=await J(Ot,{input:t},{authMode:"userPool"});return we({productId:r.productId,reviewRating:t.rating,delta:0,oldReviewRating:r.oldReviewRating}).catch(()=>{}),l.updateProductReview}async function Ut(t,r){const l=await J(zt,{input:{id:t}},{authMode:"userPool"});return await we({productId:r.productId,reviewRating:r.reviewRating,delta:-1}),l.deleteProductReview}async function we(t){return J(_t,{productId:t.productId,reviewRating:t.reviewRating,delta:t.delta,oldReviewRating:t.oldReviewRating??void 0},{authMode:"userPool"})}function Wt(t){return Nt({queryKey:["productReviews",t],queryFn:({pageParam:r})=>Ht(t,{limit:20,nextToken:r}),initialPageParam:null,getNextPageParam:r=>r.nextToken??void 0,enabled:!!t})}function Gt(t){const r=ve();return je({mutationFn:l=>Kt(l),onSuccess:()=>{r.invalidateQueries({queryKey:["productReviews",t]}),r.invalidateQueries({queryKey:["priceReviewProduct",t]}),r.invalidateQueries({queryKey:["priceReviewProducts"]})}})}function Qt(t){const r=ve();return je({mutationFn:l=>qt(l.input,{productId:t,oldReviewRating:l.oldReviewRating}),onSuccess:()=>{r.invalidateQueries({queryKey:["productReviews",t]}),r.invalidateQueries({queryKey:["priceReviewProduct",t]}),r.invalidateQueries({queryKey:["priceReviewProducts"]})}})}function Vt(t){const r=ve();return je({mutationFn:l=>Ut(l.id,{productId:t,reviewRating:l.reviewRating}),onSuccess:()=>{r.invalidateQueries({queryKey:["productReviews",t]}),r.invalidateQueries({queryKey:["priceReviewProduct",t]}),r.invalidateQueries({queryKey:["priceReviewProducts"]})}})}const Ne="petwell.productReview.draft";function Yt(t){if(!(typeof window>"u"))try{window.sessionStorage.setItem(Ne,JSON.stringify(t))}catch{}}function Xt(){if(typeof window>"u")return null;try{const t=window.sessionStorage.getItem(Ne);if(!t)return null;const r=JSON.parse(t);return typeof r.productId!="string"||typeof r.rating!="number"||typeof r.description!="string"?null:{productId:r.productId,rating:r.rating,title:typeof r.title=="string"?r.title:"",description:r.description,anonymous:!!r.anonymous,showTitle:!!r.showTitle}}catch{return null}}function De(){if(!(typeof window>"u"))try{window.sessionStorage.removeItem(Ne)}catch{}}function oe(t){const r=Xt();return!r||r.productId!==t?null:r}function Jt(t){if(!t)return"";const r=new Date(t);return Number.isNaN(r.getTime())?"":r.toLocaleDateString("zh-HK",{year:"numeric",month:"short",day:"numeric"})}function ce(t){return{rating:t.rating,title:t.title,description:t.description,anonymous:t.anonymous,showTitle:t.showTitle||!!t.title.trim()}}function Zt({productId:t,productName:r,avgRating:l,numReviews:o=0}){const{isAuthenticated:u,userInfo:i,requiresProfileCompletion:n}=Be(),{openPanel:f,onAuthSuccess:v}=st(),{data:b,isLoading:N,fetchNextPage:A,hasNextPage:z,isFetchingNextPage:s}=Wt(t),j=Gt(t),R=Qt(t),T=Vt(t),[E,P]=m.useState(!1),[$,g]=m.useState(null),[p,k]=m.useState(null),[c,y]=m.useState(null),D=m.useRef(!1),I=m.useRef(!1),h=m.useMemo(()=>(b==null?void 0:b.pages.flatMap(a=>a.items))??[],[b]),_=l??(h.length?h.reduce((a,w)=>a+w.rating,0)/h.length:0),H=o||h.length,x=u===!0&&!!(i!=null&&i.userId),S=x&&!n,C=h.find(a=>a.reviewerId===(i==null?void 0:i.userId)),B=a=>{if(g(null),a)k(a);else{const w=oe(t);k(w?ce(w):null)}P(!0)},d=a=>{if(a){if(!x){f("LANDING");return}k(null),g(a),P(!0);return}if(x&&C){k(null),g(C),P(!0);return}B(null)},q=a=>{if(!a&&D.current){D.current=!1,P(!1);return}a||(g(null),k(null)),P(a)},Z=()=>
102{if(I.current)return;I.current=!0;const a=oe(t),w=h.find(U=>U.reviewerId===(i==null?void 0:i.userId));a&&w?(g(w),k(ce(a)),P(!0)):a?B(ce(a)):w?(g(w),k(null),P(!0)):B(null),De(),M.success("登入成功!你可以繼續發佈評價")};m.useEffect(()=>{!S||I.current||oe(t)&&Z()},[S,t,h,i==null?void 0:i.userId]);const Ge=a=>{const w={productId:t,rating:a.rating,title:a.title,description:a.description,anonymous:a.anonymous,showTitle:!!a.title.trim()};Yt(w),I.current=!1,v(()=>{Z()}),D.current=!0,P(!1),f("LANDING")},Qe=async a=>{if(!x||!(i!=null&&i.userId)){Ge(a);return}try{$?(await R.mutateAsync({input:{id:$.id,title:a.title||null,description:a.description,rating:a.rating,anonymous:a.anonymous},oldReviewRating:$.rating}),M.success("已更新評價")):C?(await R.mutateAsync({input:{id:C.id,title:a.title||null,description:a.description,rating:a.rating,anonymous:a.anonymous},oldReviewRating:C.rating}),M.success("已更新評價")):(await j.mutateAsync({reviewerId:i.userId,productId:t,title:a.title||null,description:a.description,rating:a.rating,anonymous:a.anonymous}),M.success("已提交評價")),De(),k(null),P(!1),g(null)}catch(w){M.error(w instanceof Error?w.message:"提交失敗,請稍後再試")}},Ve=async a=>{if(window.confirm("確定要刪除此評價?"))try{await T.mutateAsync({id:a.id,reviewRating:a.rating}),M.success("已刪除評價")}catch(w){M.error(w instanceof Error?w.message:"刪除失敗")}},Ye=async a=>{var Q,V,Y;const w=window.prompt("請簡述舉報原因:");if(!(w!=null&&w.trim()))return;let U=null;if(u===!0&&(i!=null&&i.email)){const F=i.username&&!i.username.includes("@")?i.username:i.email;try{const L=[...await He(i.rawEmail||i.email)].sort((Je,Ze)=>{const ye=ae=>{var be,Re,Pe;return+!!((be=ae.firstName)!=null&&be.trim())+ +!!((Re=ae.lastName)!=null&&Re.trim())+ +!!((Pe=ae.phone)!=null&&Pe.trim())};return ye(Ze)-ye(Je)})[0];U={reporterName:[L==null?void 0:L.firstName,L==null?void 0:L.lastName].filter(Boolean).join(" ").trim()||F,reporterEmail:((L==null?void 0:L.email)||i.email).trim().toLowerCase(),reporterPhone:((Q=L==null?void 0:L.phone)==null?void 0:Q.trim())||""}}catch{U={reporterName:F,reporterEmail:i.email.trim().toLowerCase(),reporterPhone:""}}}else{const F=((V=window.prompt("請輸入你的電郵(方便跟進):"))==null?void 0:V.trim().toLowerCase())||"",se=((Y=window.prompt("請輸入你的電話號碼(方便跟進):"))==null?void 0:Y.trim())||"",L=/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(F);if(!F||!se||!L){M.error("請填寫有效電郵及電話號碼");return}U={reporterName:"Guest",reporterEmail:F,reporterPhone:se}}y(a.id);try{await ct({reporterId:(i==null?void 0:i.userId)??null,relatedReviewId:a.id,placeName:r,message:w.trim(),contact:U}),M.success("已提交舉報,多謝你的回饋")}catch(F){M.error(F instanceof Error?F.message:"舉報失敗")}finally{y(null)}},Xe=j.isPending||R.isPending;return e.jsxs("div",{children:[e.jsxs("div",{className:"mb-4 flex flex-wrap items-center justify-between gap-3",children:[e.jsx("div",{children:H>0?e.jsxs("p",{className:"text-[12px] text-muted-foreground",children:["平均 ",_.toFixed(1)," 星 · ",H," 個評價"]}):e.jsx("p",{className:"text-[12px] text-muted-foreground",children:"暫時未有評價"})}),e.jsx(K,{size:"sm",className:"h-9 rounded-md text-[13px]",onClick:()=>d(),children:C?"編輯我的評價":"撰寫評價"})]}),N?e.jsxs("div",{className:"flex items-center justify-center py-10 text-muted-foreground",children:[e.jsx(fe,{className:"mr-2 h-4 w-4 animate-spin"}),"載入評價中…"]}):h.length===0?e.jsxs("div",{className:"rounded-lg border border-dashed border-[hsl(var(--review-line))] bg-[hsl(var(--review-canvas))]/30 px-4 py-10 text-center",children:[e.jsx("p",{className:"text-[14px] font-medium",children:"暫時未有評價"}),e.jsx("p",{className:"mt-1 text-[13px] text-muted-foreground",children:"分享你用過呢款產品嘅心得,幫到其他寵物主人。"}),e.jsx(K,{variant:"outline",size:"sm",className:"mt-4",onClick:()=>d(),children:"成為第一個評價"})]}):e.jsxs(e.Fragment,{children:[e.jsx(er,{reviews:h,avgRating:_}),e.jsx("div",{className:"mt-4 divide-y divide-[hsl(var(--review-line))]",children:h.map(a=>{var U,Q,V,Y;const w=a.reviewerId===(i==null?void 0:i.userId);return e.jsx("article",{className:"py-4 first:pt-0 last:pb-0",children:e.jsx("div",{className:"flex items-start gap-3",children:e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"mb-1 flex flex-wrap items-center justify-between gap-2",children:[e.jsx(wt,{reviewerId:a.reviewerId||((U=a.reviewer)==null?void 0:U.id),anonymous:a.anonymous,source:a.source,displayName:((Q=a.reviewer)==null?void 0:Q.displayName)||((V=a.reviewer)==null?void 0:V.firstName)||null,profileImage:(Y=a.reviewer)==null?void 0:Y.profileImage,avatarClassName:"h-9 w-9"}),e.jsx("span",{className:"text-[11px] text-muted-foreground",children:Jt(a.createdAt)})]}),e.jsx("div",{className:"mt-1 flex items-center",children:[1,2,3,4,5].map(F=>e.jsx(re,{className:O("h-3.5 w-3.5",F<=Math.round(a.rating)?"fill-amber-400 text-amber-400":"text-muted")},F))}),a.title?e.jsx("h4",{className:"mt-2 text-[13px] font-semibold",children:a.title}):null,e.jsx("p",{className:"mt-1 text-[13px] leading-relaxed text-muted-foreground",children:a.description}),e.jsx("div",{className:"mt-2 flex flex-wrap gap-2",children:w?e.jsxs(e.Fragment,{children:[e.jsxs("button",{type:"button",className:"inline-flex items-center gap-1 text-[11px] text-muted-foreground hover:text-foreground",onClick:()=>d(a),children:[e.jsx(Dt,{className:"h-3 w-3"}),"編輯"]}),e.jsxs("button",{type:"button",className:"inline-flex items-center gap-1 text-[11px] text-destructive hover:text-destructive",onClick:()=>Ve(a),children:[e.jsx(yt,{className:"h-3 w-3"}),"刪除"]})]}):e.jsxs("button",{type:"button",className:"inline-flex items-center gap-1 text-[11px] text-muted-foreground hover:text-foreground",onClick:()=>Ye(a),disabled:c===a.id,children:[e.jsx(ge,{className:"h-3 w-3"}),"舉報"]})})]})})},a.id)})}),z?e.jsx(K,{variant:"outline",size:"sm",className:"mt-4",onClick:()=>A(),disabled:s,children:s?"載入中…":"載入更多評價"}):null]}),e.jsx(Et,{open:E,onOpenChange:q,productName:r,editingReview:$,isSaving:Xe,onSubmit:Qe,initialValues:p,requireLoginToPost:!x})]})}function er({reviews:t,avgRating:r}){return e.jsxs("div",{className:"flex flex-wrap items-center gap-4 border-b border-[hsl(var(--review-line))] pb-5 md:gap-6",children:[e.jsxs("div",{className:"text-center",children:[e.jsx("p",{className:"review-display text-4xl",children:r.toFixed(1)}),e.jsx("div",{className:"mt-1 flex items-center justify-center",children:[1,2,3,4,5].map(l=>e.jsx(re,{className:O("h-4 w-4",l<=Math.round(r)?"fill-amber-400 text-amber-400":"text-muted")},l))}),e.jsxs("p",{className:"mt-1 text-[11px] text-muted-foreground",children:[t.length," 個評價"]})]}),e.jsx("div",{className:"min-w-[180px] flex-1 space-y-1",children:[5,4,3,2,1].map(l
102=>{const o=t.filter(i=>Math.round(i.rating)===l).length,u=t.length?o/t.length*100:0;return e.jsxs("div",{className:"flex items-center gap-2 text-[11px]",children:[e.jsx("span",{className:"w-3 text-muted-foreground",children:l}),e.jsx(re,{className:"h-3 w-3 shrink-0 fill-amber-400 text-amber-400"}),e.jsx("div",{className:"h-1.5 flex-1 overflow-hidden rounded-full bg-[hsl(var(--review-canvas))]",children:e.jsx("div",{className:"h-full rounded-full bg-amber-400",style:{width:`${u}%`}})}),e.jsx("span",{className:"w-5 text-right tabular-nums text-muted-foreground",children:o})]},l)})})]})}const tr=[{label:"適用階段",value:"成犬 (1歲以上)"},{label:"主要成份",value:"脫水家禽蛋白、米、動物脂肪"},{label:"蛋白質含量",value:"25%"},{label:"脂肪含量",value:"14%"},{label:"產地",value:"法國"},{label:"保存期",value:"18個月"}],We=[{id:"3m",label:"近3個月",months:3},{id:"6m",label:"近6個月",months:6},{id:"1y",label:"近1年",months:12},{id:"all",label:"歷史",months:24}];function rr(t,r,l=24){const o=[],u=new Date;let i=r;for(let n=l-1;n>=0;n--){i=(i*9301+49297)%233280;const f=(i/233280-.5)*.18,v=Math.sin((l-n)/4)*.05,b=Math.round(t*(1+f+v)),N=new Date(u.getFullYear(),u.getMonth()-n,1);o.push({date:`${N.getFullYear()}-${String(N.getMonth()+1).padStart(2,"0")}`,price:b})}return o}const Qr=()=>{var C,B;const{id:t}=et(),{data:r,isLoading:l,isError:o,error:u}=ut(t),{i18n:i}=at(),n=m.useRef(null),[f,v]=m.useState(!1),[b,N]=m.useState(void 0),[A,z]=m.useState("6m"),s=r==null?void 0:r.product,j=m.useMemo(()=>s?ft(s.offers):[],[s]),R=(C=s==null?void 0:s.specs)!=null&&C.length?s.specs:tr,T=s?gt(j[0]??s.offers[0]):500,E=m.useMemo(()=>{var d;return rr(T,((d=s==null?void 0:s.id)==null?void 0:d.length)??7)},[T,s==null?void 0:s.id]),P=((B=We.find(d=>d.id===A))==null?void 0:B.months)??6,$=m.useMemo(()=>E.slice(-P),[E,P]),g=m.useMemo(()=>{const d=$.map(q=>q.price);return d.length===0?{low:0,high:0,avg:0}:{low:Math.min(...d),high:Math.max(...d),avg:Math.round(d.reduce((q,Z)=>q+Z,0)/d.length)}},[$]),p=j[0],k=j[j.length-1],c=p?ue(p):0,y=k?ue(k):0,D=p&&k?vt(y-c):0,I=k&&p&&y>c?Math.round(D/y*100):0,h=s?xt(s):void 0,_=s&&p?`${s.name} 香港格價:最低 ${G(c)},比較 ${s.storeCount} 間寵物店報價、運費及購買連結。`:"",H=s&&p?{"@context":"https://schema.org","@graph":[{"@type":"Product","@id":`${h}#product`,name:s.name,image:s.image?[s.image]:void 0,brand:{"@type":"Brand",name:s.brand},category:s.category,description:_,...s.numReviews&&s.avgRating?{aggregateRating:{"@type":"AggregateRating",ratingValue:s.avgRating,reviewCount:s.numReviews,bestRating:5,worstRating:1}}:{},offers:{"@type":"AggregateOffer",priceCurrency:"HKD",lowPrice:c,highPrice:y,offerCount:s.storeCount,offers:j.slice(0,10).map(d=>({"@type":"Offer",price:d.price,priceCurrency:"HKD",url:d.url,availability:"https://schema.org/InStock",seller:{"@type":"Organization",name:d.store}}))}},{"@type":"BreadcrumbList",itemListElement:[{"@type":"ListItem",position:1,name:"PetWell Review",item:"https://petwellhk.com/review"},{"@type":"ListItem",position:2,name:s.brand,item:`https://petwellhk.com/review/brand/${encodeURIComponent(s.brand)}`},{"@type":"ListItem",position:3,name:s.name,item:h}]}]}:void 0;mt({title:s&&p?`${s.name} 最低 ${G(c)} 格價比較 | PetWell Review`:"產品比較 | PetWell",description:_,keywords:s?`${s.name}, ${s.brand}, 香港寵物用品格價, pet product price hk, 寵物店價格`:void 0,ogImage:s==null?void 0:s.image,ogType:"product",canonicalUrl:h,structuredData:H});const x=async()=>{const d=window.location.href;try{navigator.share?await navigator.share({title:s==null?void 0:s.name,url:d}):(await navigator.clipboard.writeText(d),M.success("已複製連結"))}catch{}};if(l)return e.jsx(Ae,{children:e.jsxs("div",{className:"review-panel mx-auto mt-10 flex max-w-lg items-center justify-center p-12 text-[14px] text-muted-foreground",children:[e.jsx(fe,{className:"mr-2 h-5 w-5 animate-spin text-primary"}),"正在整理報價…"]})});if(o){const d=u.message;return/not found/i.test(d)?e.jsx(ke,{to:"/review",replace:!0}):e.jsx(Ae,{children:e.jsxs("div",{className:"review-panel mx-auto mt-10 max-w-lg p-8 text-center",children:[e.jsx("h1",{className:"review-display text-xl",children:"暫時未能載入"}),e.jsx("p",{className:"mt-2 text-[14px] text-muted-foreground",children:d}),e.jsx(K,{asChild:!0,className:"mt-4 rounded-md",children:e.jsx(W,{to:"/review",children:"返回格價"})})]})})}if(!s||!p)return e.jsx(ke,{to:"/review",replace:!0});const S=Math.max(1,y-c);return e.jsxs("div",{className:"review-page min-h-screen pb-[4.5rem] text-foreground md:pb-0",children:[e.jsx(Me,{}),e.jsx("div",{className:"border-b border-[hsl(var(--review-line))] bg-white",children:e.jsxs("div",{className:"container mx-auto flex items-center gap-1 overflow-x-auto whitespace-nowrap px-4 py-2.5 text-[12px] text-muted-foreground",children:[e.jsxs(W,{to:"/review",className:"inline-flex items-center gap-1 hover:text-primary",children:[e.jsx(it,{className:"h-3 w-3"})," 格價"]}),e.jsx(ie,{className:"h-3 w-3 shrink-0 opacity-40"}),e.jsx(W,{to:`/review/brand/${encodeURIComponent(s.brand)}`,className:"hover:text-primary",children:s.brand}),e.jsx(ie,{className:"h-3 w-3 shrink-0 opacity-40"}),e.jsx("span",{className:"truncate font-medium text-foreground",children:s.name})]})}),e.jsx("section",{className:"container mx-auto px-4 py-4 md:py-6",children:e.jsxs("div",{className:"grid gap-4 lg:grid-cols-[minmax(0,380px)_minmax(0,1fr)] lg:gap-6 xl:grid-cols-[400px_minmax(0,1fr)]",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsx("div",{className:"overflow-hidden",children:e.jsx("div",{className:"relative aspect-square max-h-[320px] bg-[hsl(var(--review-canvas))]/40 sm:max-h-[360px] lg:max-h-none",children:e.jsx(sr,{src:s.image,alt:s.name})})}),e.jsx("div",{className:"md:hidden",children:e.jsx(Ie,{product:s})})]}),e.jsxs("div",{className:"lg:sticky lg:top-[calc(var(--header-height)+0.75rem)] lg:self-start",children:[e.jsx("div",{className:"hidden md:block",children:e.jsx(Ie,{product:s})}),e.jsxs("div",{className:"mt-0 md:mt-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"review-savings-pill roun
102ded-sm px-2 py-0.5 text-[11px]",children:"最低價"}),e.jsxs("span",{className:"text-[12px] text-muted-foreground",children:[s.storeCount," 間店舖比價"]}),s.lastUpdated&&e.jsxs("span",{className:"ml-auto hidden items-center gap-1 text-[11px] text-muted-foreground sm:flex",children:[e.jsx(bt,{className:"h-3 w-3"}),Le(s.lastUpdated)]})]}),e.jsxs("div",{className:"mt-3",children:[e.jsx(me,{offer:p,highlight:!0,className:"text-left [&>p]:text-[26px] [&_.review-price-value]:text-[26px]"}),D>0&&e.jsxs("p",{className:"mt-2 text-[13px] text-muted-foreground",children:["最高 ",e.jsx("span",{className:"review-price-struck text-[13px]",children:G(y)}),e.jsx("span",{className:"mx-1.5 text-foreground/25",children:"·"}),"慳 ",e.jsxs("span",{className:"font-semibold text-primary",children:[I,"%"]})]})]}),e.jsxs("div",{className:"mt-4 flex items-center gap-2.5 rounded-md bg-[hsl(var(--review-canvas))]/50 p-3",children:[e.jsx("div",{className:"flex h-9 w-9 shrink-0 items-center justify-center rounded-md bg-primary/10",children:e.jsx(xe,{className:"h-4 w-4 text-primary"})}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("p",{className:"truncate text-[14px] font-semibold",children:p.store}),e.jsxs("p",{className:"flex items-center gap-1 text-[11px] text-muted-foreground",children:[e.jsx(Ue,{className:"h-3 w-3 shrink-0"}),he(p.shipping,i.language),e.jsx("span",{className:"text-foreground/30",children:"·"}),Le(p.lastSeenAt||s.lastUpdated)]})]})]}),e.jsxs("div",{className:"mt-4 flex flex-wrap items-center gap-2",children:[e.jsx(K,{asChild:!0,className:"h-9 rounded-md px-4 text-[13px] font-semibold",children:e.jsxs("a",{href:p.url,target:"_blank",rel:"noopener noreferrer",children:["去 ",p.store," 購買 ",e.jsx(pe,{className:"ml-1.5 h-3.5 w-3.5"})]})}),e.jsx(Se,{productId:s.id,currentLowest:c,variant:"labeled",className:"h-9 shrink-0 rounded-md px-3 text-[13px]"}),e.jsx(K,{variant:"outline",size:"icon",className:"h-9 w-9 shrink-0 rounded-md border-[hsl(var(--review-line))]",onClick:x,"aria-label":"分享",children:e.jsx(Rt,{className:"h-3.5 w-3.5"})}),j.length>1&&e.jsxs("button",{type:"button",onClick:()=>{var d;return(d=n.current)==null?void 0:d.scrollIntoView({behavior:"smooth",block:"start"})},className:"flex w-full basis-full items-center gap-1 py-1 text-[12px] font-medium text-primary hover:underline sm:w-auto sm:basis-auto",children:[e.jsx(Pt,{className:"h-3.5 w-3.5"}),"睇晒 ",j.length," 間店舖報價",e.jsx(ie,{className:"h-3.5 w-3.5"})]})]})]}),e.jsxs("p",{className:"mt-2.5 hidden items-center gap-1.5 text-[11px] text-muted-foreground md:flex",children:[e.jsx(kt,{className:"h-3.5 w-3.5 shrink-0 text-primary"}),"價格及庫存可能隨時變動,落單前請以店舖頁面為準"]})]})]})}),e.jsx("section",{ref:n,className:"scroll-mt-[calc(var(--header-height)+0.5rem)] border-t border-[hsl(var(--review-line))]",children:e.jsx("div",{className:"container mx-auto px-4 py-6 md:py-8",children:e.jsx(ee,{title:"店舖比價",subtitle:`由平至貴 · 共 ${j.length} 個報價`,footer:e.jsxs("p",{className:"mt-3 flex flex-wrap items-center justify-end gap-1 text-[11px] text-muted-foreground",children:[e.jsx(ge,{className:"h-3 w-3"}),"發現價格、連結或庫存有問題?",e.jsx("button",{type:"button",onClick:()=>{N(void 0),v(!0)},className:"font-medium text-primary hover:underline",children:"歡迎回報"})]}),children:e.jsxs("div",{className:"review-stagger divide-y divide-[hsl(var(--review-line))]",children:[e.jsxs("div",{className:"review-offer-header",children:[e.jsx("span",{children:"#"}),e.jsx("span",{children:"店舖"}),e.jsx("span",{className:"hidden md:block",children:"運費"}),e.jsx("span",{className:"text-right",children:"價格"}),e.jsx("span",{className:"text-center",children:"購買"}),e.jsx("span",{})]}),j.map((d,q)=>e.jsx(ir,{offer:d,rank:q+1,lowestPrice:c,priceRange:S,language:i.language,productImage:s.image,onReport:()=>{N(d.store),v(!0)}},d.id))]})})})}),e.jsx("section",{className:"border-t border-[hsl(var(--review-line))]",children:e.jsxs("div",{className:"container mx-auto space-y-10 px-4 py-8 md:space-y-12 md:py-10",children:[e.jsx(ee,{title:`用戶評價${s.numReviews?` (${s.numReviews})`:""}`,subtitle:s.numReviews&&s.avgRating?`平均 ${s.avgRating.toFixed(1)} 星`:void 0,children:e.jsx(Zt,{productId:s.id,productName:s.name,avgRating:s.avgRating,numReviews:s.numReviews})}),e.jsxs("div",{className:"grid gap-8 border-t border-[hsl(var(--review-line))] pt-10 md:pt-12 lg:grid-cols-2 lg:gap-12",children:[e.jsx(ee,{title:"產品規格",subtitle:s.description?"產品說明及規格表":"示範規格資料",children:e.jsx(cr,{description:s.description,specs:R})}),e.jsx(ee,{title:"價格走勢",subtitle:"每月最低成交價 · 示範資料",className:"lg:border-l lg:border-[hsl(var(--review-line))] lg:pl-12",children:e.jsx(lr,{points:$,currentPrice:c,range:A,onRangeChange:z,stats:g})})]})]})}),(r==null?void 0:r.related)&&r.related.length>0&&e.jsx("section",{className:"border-t border-[hsl(var(--review-line))]",children:e.jsxs("div",{className:"container mx-auto px-4 py-6 md:py-8",children:[e.jsxs("div",{className:"mb-3 flex items-center justify-between",children:[e.jsx("h2",{className:"review-display text-xl",children:"相關產品"}),e.jsxs(W,{to:"/review",className:"flex items-center gap-0.5 text-[12px] font-medium text-primary hover:underline",children:["全部格價 ",e.jsx(qe,{className:"h-3.5 w-3.5"})]})]}),e.jsx("div",{className:"review-deal-rail -mx-4 flex gap-2 overflow-x-auto px-4 pb-1 md:mx-0 md:grid md:grid-cols-4 md:gap-2 md:overflow-visible md:px-0 md:pb-0 lg:grid-cols-5",children:r.related.map(d=>e.jsx(nr,{product:d},d.id))})]})}),e.jsx("section",{className:"border-t border-[hsl(var(--review-line))] bg-white",children:e.jsxs("div",{className:"container mx-auto grid gap-4 px-4 py-6 md:grid-cols-[1.4fr_1fr] md:py-8",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-[12px] text-muted-foreground",children:"關於 PetWell 格價"}),e.jsxs("h2",{className:"review-display mt-1.5 text-lg leading-snug md:text-xl",children:["我哋唔賣嘢,只係幫你",e.jsx("span",{className:"text-primary",children:"睇清楚"}),"價錢"]}),e.jsx("p",{className:"mt-2 max-w-lg text-[13px] leading-relaxed text-muted-foreground",children:"所有價格由 PetWell 編
102輯部整理自香港寵物店公開報價。落單前請以店舖頁面為準。"})]}),e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx(de,{icon:St,label:"想我哋加邊款?",sub:"WhatsApp 編輯部",href:"https://wa.me/85255954078"}),e.jsx(de,{icon:xe,label:"店主合作",sub:"加入比價聯盟",href:"/other-services",internal:!0}),e.jsx(de,{icon:pt,label:"格價公平守則",sub:"點解信得過",href:"/about",internal:!0})]})]})}),e.jsx("div",{className:"fixed bottom-0 left-0 right-0 z-30 border-t border-[hsl(var(--review-line))] bg-white/95 p-3 backdrop-blur-md md:hidden",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx(me,{offer:p,highlight:!0,className:"text-left"}),e.jsxs("p",{className:"truncate text-[11px] text-muted-foreground",children:[p.store," · 最低價"]})]}),e.jsx(Se,{productId:s.id,currentLowest:c,size:"sm"}),e.jsx(K,{asChild:!0,size:"lg",className:"h-10 shrink-0 rounded-md px-4 text-[14px] font-semibold",children:e.jsx("a",{href:p.url,target:"_blank",rel:"noopener noreferrer",children:"去購買"})})]})}),e.jsx(It,{open:f,onOpenChange:v,productId:s.id,productName:s.name,storeName:b}),e.jsx(Te,{})]})};function Ie({product:t}){return e.jsxs("div",{children:[e.jsxs("div",{className:"mb-1.5 flex flex-wrap items-center gap-2",children:[e.jsx(W,{to:`/review/brand/${encodeURIComponent(t.brand)}`,className:"review-chip border border-primary/20 bg-secondary/60 px-2 py-0.5 text-[11px] font-semibold text-primary hover:border-primary/40",children:t.brand}),e.jsx("span",{className:"text-[11px] text-muted-foreground",children:mr(t.category)}),t.size&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"text-muted-foreground/30",children:"·"}),e.jsx("span",{className:"text-[11px] text-muted-foreground",children:t.size})]})]}),e.jsx("h1",{className:"review-display text-xl leading-snug md:text-2xl",children:t.name})]})}function sr({src:t,alt:r}){const[l,o]=m.useState(!1);return!t||l?e.jsx("div",{className:"flex h-full items-center justify-center text-[13px] text-muted-foreground",children:"—"}):e.jsx("img",{src:t,alt:r,className:"h-full w-full object-contain p-4 md:p-6",onError:()=>o(!0)})}function ar({src:t,alt:r}){const[l,o]=m.useState(!1);return!t||l?e.jsx("div",{className:"flex h-full items-center justify-center bg-[hsl(var(--review-canvas))]/60",children:e.jsx(xe,{className:"h-4 w-4 text-muted-foreground/50"})}):e.jsx("img",{src:t,alt:r,loading:"lazy",className:"h-full w-full object-contain p-1",onError:()=>o(!0)})}function ir({offer:t,rank:r,lowestPrice:l,priceRange:o,language:u,productImage:i,onReport:n}){const f=r===1,v=o>0?(ue(t)-l)/o*100:0,b=t.imageUrl||i,N=dr(t);return e.jsxs("div",{className:O("border-b border-[hsl(var(--review-line))] px-3 py-3 last:border-b-0 md:px-5 md:py-3.5",f?"bg-primary/[0.04]":"bg-white","flex items-center gap-3 md:grid md:review-offer-row"),children:[e.jsx("div",{className:"flex justify-center",children:r<=3?e.jsx("span",{className:O("flex h-7 w-7 items-center justify-center rounded-sm text-[11px] font-bold md:h-8 md:w-8 md:text-xs",r===1&&"review-savings-pill",r===2&&"bg-foreground
102/75 text-white",r===3&&"bg-muted-foreground/55 text-white"),children:r}):e.jsx("span",{className:"text-[13px] font-medium tabular-nums text-muted-foreground",children:r})}),e.jsx("div",{className:"min-w-0 flex-1 md:flex-none",children:e.jsxs("div",{className:"flex items-start gap-2.5",children:[e.jsx("div",{className:"h-11 w-11 shrink-0 overflow-hidden rounded-md border border-[hsl(var(--review-line))] bg-[hsl(var(--review-canvas))]/50 md:h-12 md:w-12",children:e.jsx(ar,{src:b,alt:t.store})}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-1.5",children:[e.jsx("p",{className:"truncate text-[13px] font-semibold md:text-[14px]",children:t.store}),f&&e.jsxs("span",{className:"review-savings-pill inline-flex items-center gap-0.5 rounded-sm px-1.5 py-px text-[9px] md:text-[10px]",children:[e.jsx(Ct,{className:"h-2.5 w-2.5"})," 最低"]})]}),N&&e.jsx("p",{className:"truncate text-[11px] text-muted-foreground",children:N}),e.jsxs("p",{className:"mt-0.5 flex items-center gap-1 text-[11px] text-muted-foreground md:hidden",children:[e.jsx(Ue,{className:"h-3 w-3 shrink-0"}),he(t.shipping,u)]}),e.jsx("div",{className:"mt-1.5 hidden md:block",children:e.jsx("div",{className:"review-offer-position",children:e.jsx("div",{className:"review-offer-position-fill transition-all",style:{width:`${Math.max(4,v)}%`,opacity:f?1:.35+(1-v/100)*.45}})})})]})]})}),e.jsx("p",{className:"hidden truncate text-[11px] text-muted-foreground md:block",children:he(t.shipping,u)}),e.jsx(me,{offer:t,highlight:f,className:"shrink-0 md:block"}),e.jsx("div",{className:"hidden justify-center md:flex",children:e.jsx(K,{asChild:!0,size:"sm",variant:f?"default":"outline",className:O("h-8 rounded-md text-[12px]",!f&&"border-[hsl(var(--review-line))]"),children:e.jsxs("a",{href:t.url,target:"_blank",rel:"noopener noreferrer",children:["前往 ",e.jsx(pe,{className:"ml-1 h-3 w-3"})]})})}),e.jsxs("div",{className:"flex items-center justify-end gap-0.5 md:justify-center",children:[e.jsx("a",{href:t.url,target:"_blank",rel:"noopener noreferrer",className:"inline-flex h-8 w-8 items-center justify-center rounded-md bg-primary text-primary-foreground md:hidden","aria-label":`前往 ${t.store}`,children:e.jsx(pe,{className:"h-3.5 w-3.5"})}),e.jsx("button",{type:"button",onClick:n,"aria-label":`回報 ${t.store} 價格`,className:"rounded-sm p-1 text-muted-foreground hover:text-primary",children:e.jsx(ge,{className:"h-3.5 w-3.5"})})]})]})}function nr({product:t}){return e.jsxs(W,{to:ht(t),className:"review-deal-rail-item review-panel review-card-product flex w-[140px] shrink-0 flex-col overflow-hidden bg-white md:w-auto",children:[e.jsx("div",{className:"relative aspect-square bg-[hsl(var(--review-canvas))]/40 p-2.5",children:t.image?e.jsx("img",{src:t.image,alt:t.name,loading:"lazy",className:"h-full w-full object-contain transition-transform group-hover:scale-[1.03]"}):e.jsx("div",{className:"flex h-full items-center justify-center text-[11px] text-muted-foreground",children:"—"})}),e.jsxs("div",{className:"space-y-1 p-2.5 pt-2",children:[e.jsx("p",{className:"truncate text-[10px] font-medium text-primary",children:t.brand}),e.jsx("h3",{className:"line-clamp-2 min-h-[2rem] text-[11px] leading-snug text-foreground",children:t.name}),e.jsx(dt,{product:t,size:"sm",showPurchaseNote:!1})]})]})}function de({icon:t,label:r,sub:l,href:o,internal:u}){const i="group flex items-center gap-3 rounded-md border border-[hsl(var(--review-line))] bg-white px-3 py-2.5 transition-colors hover:border-primary/30",n=e.jsxs(e.Fragment,{children:[e.jsx(t,{className:"h-4 w-4 shrink-0 text-primary",strokeWidth:2}),e.jsxs("div",{className:"flex-1 text-left",children:[e.jsx("p",{className:"text-[13px] font-medium",children:r}),e.jsx("p",{className:"text-[11px] text-muted-foreground",children:l})]}),e.jsx(qe,{className:"h-3.5 w-3.5 text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100"})]});return u?e.jsx(W,{to:o,className:i,children:n}):e.jsx("a",{href:o,target:"_blank",rel:"noopener noreferrer",className:i,children:n})}function ee({title:t,subtitle:r,children:l,footer:o,className:u}){return e.jsxs("div",{className:O("min-w-0",u),children:[e.jsxs("div",{className:"mb-4",children:[e.jsx("h2",{className:"review-display text-[18px] leading-snug md:text-xl",children:t}),r&&e.jsx("p",{className:"mt-1 text-[12px] text-muted-foreground",children:r})]}),l,o]})}function lr({points:t,currentPrice:r,range:l,onRangeChange:o,stats:u}){return e.jsxs("div",{children:[e.jsx("div",{className:"mb-4 flex flex-wrap items-center justify-end gap-2",children:e.jsxs("div",{className:"inline-flex items-center gap-1",children:[e.jsx($t,{className:"h-3.5 w-3.5 text-muted-foreground"}),We.map(i=>e.jsx("button",{type:"button",onClick:()=>o(i.id),className:O("rounded-sm px-2.5 py-1 text-[11px] transition-colors",l===i.id?"font-semibold text-primary":"text-muted-foreground hover:text-foreground"),children:i.label},i.id))]})}),e.jsx(or,{points:t,current:r}),e.jsxs("div",{className:"mt-4 flex flex-wrap gap-6 text-[12px]",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-muted-foreground",children:"期內最低"}),e.jsxs("p",{className:"review-price mt-0.5",children:[e.jsx("span",{className:"review-price-symbol text-[10px]",children:"HK$"}),e.jsx("span",{className:"review-price-value text-[16px]",children:u.low})]})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-muted-foreground",children:"平均價"}),e.jsx("p",{className:"mt-0.5 text-[16px] font-bold tabular-nums",children:G(u.avg)})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-muted-foreground",children:"期內最高"}),e.jsx("p",{className:"mt-0.5 text-[16px] font-bold tabular-nums text-muted-foreground",children:G(u.high)})]})]}),e.jsx("p",{className:"mt-4 text-[11px] text-muted-foreground",children:"* 走勢以每月最低成交價計算,僅供參考。"})]})}function or({points:t,current:r,height:l=140}){const[o,u]=m.useState(null),i=800,n=l,f=12,v=16,b=t.map(g=>g.price),N=Math.min(...b,r),A=Math.max(...b,r),z=Math.max(A-N,1),s=(i-f*2)/Math.max(t.length-1,1),j=g=>v+(1-(g-N)/z)*(n-v*2),R=g=>f+g*s,T=t.map((g,p)=>`${p===0?"M":"L"} ${R(p)} ${j(g.price)}`).join(" "),E=`${T} L ${R(t.length-1)} ${n-v} L ${R(0)} ${n-v} Z`,P=b.indexOf(N),$=o!==null?t[o]:null;return e.jsxs("div",{className:"relative",children:[e.jsxs("svg",{viewBox:`0 0 ${i} ${n}`,preserveAspectRatio:"none",className:"w-full select-none",style:{height:l},onMouseLeave:()=>u(null),onMouseMove:g=>{const p=g.currentTarget.getBoundingClientRect(),k=(g.clientX-p.left)/p.width*i,c=Math.round((k-f)/s);u(Math.max(0,Math.min(t.length-1,c)))},children:[e.jsx("defs",{children:e.jsxs("linearGradient",{id:"review-spark-fill",x1:"0",x2:"0",y1:"0",y2:"1",children:[e.jsx("stop",{offset:"0%",stopColor:"hsl(var(--primary))",stopOpacity:"0.25"}),e.jsx("stop",{offset:"100%",stopColor:"hsl(var(--primary))",stopOpacity:"0"})]})}),e.jsx("path",{d:E,fill:"url(#review-spark-fill)"}),e.jsx("path",{d:T,fill:"none",stroke:"hsl(var(--primary))",strokeWidth:"2.5"}),e.jsx("circle",{cx:R(P),cy:j(N),r:"5",fill:"hsl(var(--primary))"}),o!==null&&e.jsxs(e.Fragment,{children:[e.jsx("line",{x1:R(o),x2:R(o),y1:v,y2:n-v,stroke:"hsl(var(--foreground))",strokeOpacity:"0.2",strokeDasharray:"3 3"}),e.jsx("circle",{cx:R(o),cy:j(t[o].price),r:"4",fill:"hsl(var(--foreground))"})]})]}),$&&e.jsxs("div",{className:"pointer-events-none absolute -top-1 rounded-md bg-foreground px-2.5 py-1.5 text-[11px] text-background shadow-lg",style:{left:`${(o*s+f)/i*100}%`,transform:"translate(-50%, -100%)"},children:[e.jsx("div",{className:"font-semibold",children:G($.price)}),e.jsx("div",{className:"opacity-70",children:$.date})]})]})}function cr({description:t,specs:r}){return e.jsxs("div",{children:[t&&e.jsx("p",{className:"mb-5 text-[14px] leading-relaxed text-muted-foreground",children:t}),e.jsx("div",{className:"divide-y divide-[hsl(var(--review-line))]",children:r.map((l,o)=>e.jsxs("div",{className:"grid grid-cols-[100px_1fr] gap-3 py-3 text-[13px] md:grid-cols-[130px_1fr]",children:[e.jsx("p",{className:"text-[12px] font-medium text-muted-foreground",children:l.label}),e.jsx("p",{className:"font-medium",children:l.value})]},`${l.label}-${o}
102`))}),!t&&e.jsx("p",{className:"mt-3 text-[11px] text-muted-foreground",children:"* 規格為示範資料。"})]})}function Ae({children:t}){return e.jsxs("div",{className:"review-page min-h-screen",children:[e.jsx(Me,{}),e.jsx("main",{className:"container mx-auto px-4 py-8",children:t}),e.jsx(Te,{})]})}function Le(t){if(!t)return"最近更新";const r=new Date(t);return Number.isNaN(r.getTime())?"最近更新":r.toLocaleDateString("zh-HK",{month:"short",day:"2-digit"})}function dr(t){try{const l=new URL(t.url).hostname.replace(/^www\./i,"");if(l)return l}catch{}return t.platform.trim()||null}function mr(t){switch(t){case"food":return"糧食";case"medicine":return"藥品";case"treats":return"零食";case"supplies":return"日用品";default:return"其他"}}export{Qr as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.