text: (()=>{"use strict";const t=new class{constructor(){this.API_HOST="https://api.appworks-school.tw/api/1.0",this.accessToken=void 0}async getProducts(t,e){const i=await fetch(`${this.API_HOST}/products/${t}?paging=${e}`);return await i.json()}async getCampaigns(){const t=await fetch(`${this.API_HOST}/marketing/campaigns`);return await t.json()}async searchProducts(t,e){const i=await fetch(`${this.API_HOST}/products/search?keyword=${t}&paging=${e}`);return await i.json()}async getProduct(t){const e=await fetch(`${this.API_HOST}/products/details?id=${t}`);return await e.json()}async checkout(t){if(!this.accessToken)throw new Error("請先登入");const e=await fetch(`${this.API_HOST}/order/checkout`,{body:JSON.stringify(t),headers:new Headers({"Content-Type":"application/json",Authorization:`Bearer ${this.accessToken}`}),method:"POST"});if(401===e.status)throw new Error("請先登入");if(403===e.status)throw new Error("內容錯誤或權限不足");return await e.json()}async signin(t){const e=await fetch(`${this.API_HOST}/user/signin`,{body:JSON.stringify(t),headers:new Headers({"Content-Type":"application/json"}),method:"POST"}),i=await e.json();return this.accessToken=i.data.access_token,i}};new class extends class{constructor(t,e,i,s){this.model=t,this.view=e,this.fb=i,this.tappay=s,this.view.bindInputSearchPressEnter(this.redirectToIndexPageWithTag),this.view.bindClickProfile(this.handleClickProfile.bind(this))}init(){this.view.handleTag(this.paramsTag),this.view.renderCount(this.model.cart.items.length)}get paramsNumber(){return this.getParams("number")}get paramsId(){return this.getParams("id")}get paramsTag(){return this.getParams("tag")||"all"}getParams(t){return new URLSearchParams(window.location.search).get(t)}redirectToIndexPageWithTag(t){window.location.href=`/?tag=${t}`}async handleClickProfile(){this.fb.jwtToken?window.location.href="/profile.html":await this.fb.login()&&window.alert("登入成功！")}}{constructor(t,e,i,s){super(t,e,i,s)}init(){super.init(),this.fb.init(),this.getProduct()}handleClickColorCode(t){this.model.changeColorCode(t),this.onProductVariantChanged(this.model.product,this.model.selectedColorCode,this.model.selectedSize,this.model.quantity)}handleClickSize(t){this.model.changeSize(t),this.onProductVariantChanged(this.model.product,this.model.selectedColorCode,this.model.selectedSize,this.model.quantity)}handleClickIncrement(){this.model.incrementQuantity(),this.onProductVariantChanged(this.model.product,this.model.selectedColorCode,this.model.selectedSize,this.model.quantity)}handleClickDecrement(){this.model.decrementQuantity(),this.onProductVariantChanged(this.model.product,this.model.selectedColorCode,this.model.selectedSize,this.model.quantity)}handleClickAddToCart(){this.model.addToCart(),this.view.renderCount(this.model.cart.items.length)}onProductChanged(t,e,i,s){this.view.renderProductDetail(t),this.view.renderProductVariant(t,e,i,s),this.view.bindClickColorCode(this.handleClickColorCode.bind(this)),this.view.bindClickSize(this.handleClickSize.bind(this)),this.view.bindClickIncrement(this.handleClickIncrement.bind(this)),this.view.bindClickDecrement(this.handleClickDecrement.bind(this)),this.view.bindClickAddToCart(this.handleClickAddToCart.bind(this))}onProductVariantChanged(t,e,i,s){this.view.renderProductVariant(t,e,i,s),this.view.bindClickColorCode(this.handleClickColorCode.bind(this)),this.view.bindClickSize(this.handleClickSize.bind(this))}getProduct(){t.getProduct(this.paramsId).then((({data:t})=>{this.model.setProduct(t),this.onProductChanged(this.model.product,this.model.selectedColorCode,this.model.selectedSize,this.model.quantity)}))}}(new class extends class{constructor(t){this.cart=t}}{constructor(t){super(t),this.product=void 0,this.selectedColorCode=void 0,this.selectedSize=void 0,this.quantity=void 0}findFirstValidVariant(t,e){return t.variants.find((t=>(!e||t.color_code===e)&&t.stock>0))}findEqualVariant(t,e){return this.product.variants.find((i=>i.color_code===t&&i.size===e))}setProduct(t){this.product=t;const e=this.findFirstValidVariant(this.product);this.selectedColorCode=e.color_code,this.selectedSize=e.size,this.quantity=1}changeColorCode(t){const e=this.product.colors[t].code;this.selectedColorCode!==e&&(this.selectedColorCode=e,0===this.findEqualVariant(this.selectedColorCode,this.selectedSize).stock&&(this.selectedSize=this.findFirstValidVariant(this.product,this.selectedColorCode).size),this.quantity=1)}changeSize(t){const e=this.product.sizes[t],i=this.selectedSize!==e,s=0!==this.findEqualVariant(this.selectedColorCode,e).stock;i&&s&&(this.selectedSize=e,this.quantity=1)}incrementQuantity(){this.quantity===this.findEqualVariant(this.selectedColorCode,this.selectedSize).stock||(this.quantity+=1)}decrementQuantity(){1===this.quantity||(this.quantity-=1)}addToCart(){const t=this.cart.items,e=t.findIndex((t=>t.id===this.product.id&&t.color.code===this.selectedColorCode&&t.size===this.selectedSize));e>-1?t[e].qty=this.quantity:t.push({id:this.product.id,name:this.product.title,price:this.product.price,color:this.product.colors.find((t=>t.code===this.selectedColorCode)),size:this.selectedSize,qty:this.quantity,image:this.product.main_image,stock:this.product.variants.find((t=>t.color_code===this.selectedColorCode&&t.size===this.selectedSize)).stock}),this.cart.update(),window.alert("已加入購物車")}}(new class{constructor(){this.items=JSON.parse(window.localStorage.getItem("cart")||"[]")}static calculateSubtotal(t){return t.reduce(((t,e)=>t+e.qty*e.price),0)}update(){window.localStorage.setItem("cart",JSON.stringify(this.items))}}),new class extends class{constructor(){this.tagMen=this.getElement(".tag-men"),this.tagWomen=this.getElement(".tag-women"),this.tagAccessories=this.getElement(".tag-accessories"),this.inputSearch=this.getElement("input#search"),this.profile=this.getElement("#profile"),this.count=this.getElement(".count")}createElement(t,e){const i=document.createElement(t);return e.classList&&i.classList.add(...e.classList),e.attributes&&Object.entries(e.attributes).forEach((([t,e])=>{i.setAttribute(t,e)})),e.styles&&Object.entries(e.styles).forEach((([t,e])=>{i.style[t]=e})),e.children&&i.append(...e.children),e.parent&&e.parent.append(i),i}getElement(t){return document.querySelector(t)}handleTag(t){switch(t){case"men":this.tagMen.classList.add("tag--active");break;case"women":this.tagWomen.classList.add("tag--active");break;case"accessories":this.tagAccessories.classList.add("tag--active");break;case"all":break;default:this.inputSearch.value=t}}bindInputSearchPressEnter(t){this.inputSearch.addEventListener("keydown",(e=>{13===e.keyCode&&t(e.currentTarget.value)}))}bindClickProfile(t){this.profile.addEventListener("click",(()=>{t()}))}renderCount(t){this.count.textContent=t}}{constructor(){super(),this.product=this.getElement("#product"),this.productMainImage=this.getElement(".product__main-image"),this.productTitle=this.getElement(".product__title"),this.productId=this.getElement(".product__id"),this.productPrice=this.getElement(".product__price"),this.productNote=this.getElement(".product__note"),this.productTexture=this.getElement(".product__texture"),this.productDescription=this.getElement(".product__description"),this.productWash=this.getElement(".product__wash"),this.productPlace=this.getElement(".product__place"),this.productStory=this.getElement(".product__story"),this.productColors=this.getElement("#colors"),this.productSizes=this.getElement("#sizes"),this.productQuantity=this.getElement("#quantity"),this.increment=this.getElement("#increment"),this.decrement=this.getElement("#decrement"),this.addToCart=this.getElement("#add-to-cart"),this.productColorList=[],this.productSizeList=[]}renderProductDetail(t){this.productMainImage.setAttribute("src",t.main_image),this.productTitle.textContent=t.title,this.productId.textContent=t.id,this.productPrice.textContent=`TWD.${t.price}`,this.productNote.textContent=t.note,this.productTexture.textContent=t.texture,this.productDescription.textContent=t.description,this.productWash.textContent=`清洗：${t.wash}`,this.productPlace.textContent=`產地：${t.place}`,this.productStory.textContent=t.story,t.images.forEach((t=>{this.createElement("img",{classList:["product__image"],attributes:{src:t},parent:this.product})}))}renderProductColors(t,e){this.productColors.innerHTML="",this.colorList=t.colors.map((t=>{const i=["product__color"];return e===t.code&&i.push("product__color--selected"),this.createElement("div",{classList:i,styles:{backgroundColor:`#${t.code}`},parent:this.productColors})}))}renderProductSizes(t,e,i){this.productSizes.innerHTML="",this.sizeList=t.sizes.map((s=>{const r=i===s,o=0===t.variants.find((t=>t.color_code===e&&t.size===s)).stock,n=["product__size"];return r&&n.push("product__size--selected"),o&&n.push("product__size--disabled"),this.createElement("div",{classList:n,children:[s],parent:this.productSizes})}))}renderProductQuantity(t){this.productQuantity.innerHTML="",this.productQuantity.textContent=t}renderProductVariant(t,e,i,s){this.renderProductColors(t,e),this.renderProductSizes(t,e,i),this.renderProductQuantity(s)}bindClickColorCode(t){this.colorList.forEach(((e,i)=>{e.addEventListener("click",(()=>{t(i)}))}))}bindClickSize(t){this.sizeList.forEach(((e,i)=>{e.addEventListener("click",(()=>{t(i)}))}))}bindClickIncrement(t){this.increment.addEventListener("click",(()=>{t()}))}bindClickDecrement(t){this.decrement.addEventListener("click",(()=>{t()}))}bindClickAddToCart(t){this.addToCart.addEventListener("click",(()=>{t()}))}},new class{constructor(){this.jwtToken=void 0}loadSdk(){var t,e,i,s,r;e="script",i="facebook-jssdk",r=(t=document).getElementsByTagName(e)[0],t.getElementById(i)||((s=t.createElement(e)).id=i,s.src="https://connect.facebook.net/zh_TW/sdk.js",r.parentNode.insertBefore(s,r))}async init(){await new Promise((t=>{window.fbAsyncInit=t,this.loadSdk()})),window.FB.init({appId:"700590737403665",cookie:!0,xfbml:!0,version:"v10.0"});const t=await new Promise((t=>{window.FB.getLoginStatus(t)}));return await this.handleLoginStatus(t)}async login(){const t=await new Promise((t=>{window.FB.login(t,{scope:"public_profile,email"})}));return await this.handleLoginStatus(t)}async handleLoginStatus(e){if("connected"===e.status){const{data:i}=await t.signin({provider:"facebook",access_token:e.authResponse.accessToken});return this.jwtToken=i.access_token,i.user}}async logout(){await new Promise((t=>{window.FB.logout(t)}))}},new class{constructor(){this.appId="12348",this.appKey="app_pa1pQcKoY22IlnSXq5m5WP5jFKzoRG58VEXpT7wU62ud7mMbDOGzCYIlzzLF",this.serverType="sandbox"}setupSdk(){window.TPDirect.setupSDK(this.appId,this.appKey,this.serverType)}setupCard(){window.TPDirect.card.setup({fields:{number:{element:"#card-number",placeholder:"**** **** **** ****"},expirationDate:{element:"#card-expiration-date",placeholder:"MM / YY"},ccv:{element:"#card-ccv",placeholder:"後三碼"}},styles:{".valid":{color:"green"},".invalid":{color:"red"}}})}init(){this.setupSdk(),this.setupCard()}getPrime(){return new Promise((t=>{window.TPDirect.card.getPrime((e=>{0===e.status&&t(e.card.prime)}))}))}get canGetPrime(){return window.TPDirect.card.getTappayFieldsStatus().canGetPrime}get cannotGetPrimeReason(){const t=window.TPDirect.card.getTappayFieldsStatus();return 1===t.status.number?"請輸入信用卡號碼":2===t.status.number?"信用卡號碼有誤":1===t.status.expiry?"請輸入有效期限":2===t.status.expiry?"有效期限有誤":1===t.status.ccv?"請輸入安全碼":2===t.status.ccv?"安全碼有誤":void 0}}).init()})();