PageSourceSearch

https://holidaythai.com/assets/AdminAttractions-BPPDus-S.js

js holidaythai.com collected 2026-10-02 13:54:12 UTC 18,107 bytes, 15 lines download raw bytes

1import{r as c,N as re,J as de,a as w,O as F,j as s,_ as O,a1 as Q,S as oe,I as y,B as u,h as S,y as R,ag as ce,g as ue,c as _e,ah as me,T as he,p as pe,q as v,w as f,aj as d,a4 as $,a5 as z,a6 as G,a7 as U,a8 as A,P as V,s as _,Z as g}from"./index-LAef4FAh.js";import{A as ge}from"./AdminLayout-Dro29Kpa.js";import{A as xe}from"./AdminHeader-B42vItrp.js";import{C as je}from"./ContentMeta-BISH5HZL.js";import{T as ye,a as ve,b as J,c as b,d as fe,e as N}from"./table-D5-oyEO6.js";import{D as be,a as Ne,b as Ce,c as we,e as Se}from"./dialog-DMm6owy5.js";import{S as Te}from"./switch-DU3zvDcN.js";import{I as De}from"./ImageUpload-D-84rzUy.js";import{G as qe}from"./GalleryUpload-mKjuZLOk.js";import{L as Ie}from"./LocationPicker-DJsUsX5T.js";import{R as Le}from"./RichTextEditor-BBH5kV6p.js";import{P as ke}from"./PlaceAddressSection-DmXLMVA4.js";import{D as Fe}from"./DestinationSelector-s7aLGAHV.js";import{L as Z}from"./landmark-eclomjXV.js";import{E as Ae}from"./external-link-BRMN0jdb.js";import{S as Ee}from"./square-pen-6Z-Lxopj.js";import"./ticket-Bcy--bUf.js";import"./map-0mwcUW20.js";import"./map-pinned-C0VBE1O0.js";import"./layers-CE-VZH9E.js";import"./building-Cewy1eM-.js";import"./utensils-BqCdN-oa.js";import"./file-text-DUEkAyPG.js";import"./images-CBCSZmwA.js";import"./message-circle-wkoekWF0.js";import"./folder-tree-YycC2xmr.js";import"./hotel-2lv4PSY8.js";import"./clipboard-list-DQ3Suamp.js";import"./index-JglnD_Uo.js";import"./image-B0XNxyw7.js";import"./grip-vertical-MtwG0pDF.js";import"./navigation-Xg5TU3hn.js";import"./index-Dh4i1-J3.js";import"./separator-BCHhsBGf.js";import"./scroll-area-CcAjUzix.js";import"./code-DTogw0bt.js";import"./list-BWf8knBB.js";import"./link-N812JCb4.js";import"./link-2-BK3duh2L.js";import"./palette-CC7WviSX.js";const W=[{value:"temple",label:"วัด/ศาสนสถาน"},{value:"beach",label:"ทะเล/ชายหาด"},{value:"waterfall",label:"น้ำตก"},{value:"mountain",label:"ภูเขา"},{value:"park",label:"สวนสาธารณะ/อุทยาน"},{value:"museum",label:"พิพิธภัณฑ์"},{value:"palace",label:"พระราชวัง/วัง"},{value:"market",label:"ตลาด"},{value:"viewpoint",label:"จุดชมวิว"},{value:"island",label:"เกาะ"},{value:"cave",label:"ถ้ำ"},{value:"historical",label:"โบราณสถาน"},{value:"other",label:"อื่นๆ"}],E={name_th:"",name_en:"",slug:"",attraction_type:"",destination_country_id:null,destination_id:null,destination_area_id:null,summary_th:"",summary_en:"",content_th:"",content_en:"",hero_image_url:"",gallery_images:[],address_th:"",address_en:"",province_code:null,district_code:null,subdistrict_code:null,postal_code:"",latitude:null,longitude:null,google_maps_url:"",entrance_fee:"",contact_phone:"",website_url:"",is_featured:!1,status:"draft",meta_title:"",meta_description:""},Me=o=>({addressTh:o.address_th,provinceCode:o.province_code,districtCode:o.district_code,subdistrictCode:o.subdistrict_code,postalCode:o.postal_code});function Ns(){const[o,X]=c.useState(""),[T,Y]=c.useState("all"),[ee,C]=c.useState(!1),[x,D]=c.useState(null),[j,M]=c.useState(null),[l,i]=c.useState(E),[P,K]=c.useState(""),q=re(),{user:m}=de();w({queryKey:["countries-list"],queryFn:async()=>{const{data:e,error:a}=await _.from("countries").select("id, name_th, code").order("name_th",{ascending:!0});if(a)throw a;return e}});const{data:h}=w({queryKey:["provinces-states-list"],queryFn:async()=>{const{data:e,error:a}=await _.from("provinces_states").select(`
2          id,
3          name_th,
4          country_id,
5          countries (id, name_th, code)
6        `).order("name_th",{ascending:!0});if(a)throw a;return e}});h==null||h.filter(e=>P?e.country_id===P:!0),w({queryKey:["destinations-list"],queryFn:async()=>{const{data:e,error:a}=await _.from("destinations").select("id, title_th").order("title_th",{ascending:!0});if(a)throw a;return e}});const{data:r,isLoading:se}=w({queryKey:["admin-attractions",o],queryFn:async()=>{let e=_.from("attractions").select(`
7          *,
8          provinces_states!province_state_id (
9            name_th,
10            countries (name_th, code)
11          ),
12          destination:destinations!destination_id (
13            country_id
14          )
15        `).order("updated_at",{ascending:!1});o&&(e=e.ilike("name_th",`%${o}%`));const{data:a,error:t}=await e;if(t)throw t;return a}}),I=F({mutationFn:async e=>{const{destination_country_id:a,...t}=e,n={name_th:t.name_th,name_en:t.name_en||null,slug:t.slug,attraction_type:t.attraction_type||null,destination_id:t.destination_id||null,destination_area_
15id:t.destination_area_id||null,summary_th:t.summary_th||null,content_th:t.content_th||null,hero_image_url:t.hero_image_url||null,gallery_images:t.gallery_images,address_th:t.address_th||null,address_en:t.address_en||null,province_code:t.province_code,district_code:t.district_code,subdistrict_code:t.subdistrict_code,postal_code:t.postal_code||null,latitude:t.latitude,longitude:t.longitude,google_maps_url:t.google_maps_url||null,entrance_fee:t.entrance_fee||null,contact_phone:t.contact_phone||null,website_url:t.website_url||null,is_featured:t.is_featured,status:t.status,meta_title:t.meta_title||null,meta_description:t.meta_description||null,created_by:(m==null?void 0:m.id)||null},{error:p}=await _.from("attractions").insert([n]);if(p)throw p},onSuccess:()=>{q.invalidateQueries({queryKey:["admin-attractions"]}),g.success("เพิ่มแหล่งท่องเที่ยวสำเร็จ"),k()},onError:e=>{g.error(`เกิดข้อผิดพลาด: ${e.message}`)}}),L=F({mutationFn:async({id:e,data:a})=>{const{destination_country_id:t,...n}=a,p={name_th:n.name_th,name_en:n.name_en||null,slug:n.slug,attraction_type:n.attraction_type||null,destination_id:n.destination_id||null,destination_area_id:n.destination_area_id||null,summary_th:n.summary_th||null,content_th:n.content_th||null,hero_image_url:n.hero_image_url||null,gallery_images:n.gallery_images,address_th:n.address_th||null,address_en:n.address_en||null,province_code:n.province_code,district_code:n.district_code,subdistrict_code:n.subdistrict_code,postal_code:n.postal_code||null,latitude:n.latitude,longitude:n.longitude,google_maps_url:n.google_maps_url||null,entrance_fee:n.entrance_fee||null,contact_phone:n.contact_phone||null,website_url:n.website_url||null,is_featured:n.is_featured,status:n.status,meta_title:n.meta_title||null,meta_description:n.meta_description||null,updated_by:(m==null?void 0:m.id)||null},{error:H}=await _.from("attractions").update(p).eq("id",e);if(H)throw H},onSuccess:()=>{q.invalidateQueries({queryKey:["admin-attractions"]}),g.success("บันทึกการเปลี่ยนแปลงสำเร็จ"),k()},onError:e=>{g.error(`เกิดข้อผิดพลาด: ${e.message}`)}}),ae=F({mutationFn:async e=>{const{error:a}=await _.from("attractions").delete().eq("id",e);if(a)throw a},onSuccess:()=>{q.invalidateQueries({queryKey:["admin-attractions"]}),g.success("ลบแหล่งท่องเที่ยวสำเร็จ")},onError:e=>{g.error(`เกิดข้อผิดพลาด: ${e.message}`)}}),B=()=>{i(E),D(null),C(!0)},te=e=>{var n;const a=h==null?void 0:h.find(p=>p.id===e.province_state_id);K((a==null?void 0:a.country_id)||"");const t=((n=e.destination)==null?void 0:n.country_id)||null;i({name_th:e.name_th,name_en:e.name_en||"",slug:e.slug,attraction_type:e.attraction_type||"",destination_country_id:t,destination_id:e.destination_id||null,destination_area_id:e.destination_area_id||null,summary_th:e.summary_th||"",summary_en:"",content_th:e.content_th||"",content_en:"",hero_image_url:e.hero_image_url||"",gallery_images:e.gallery_images||[],address_th:e.address_th||"",address_en:e.address_en||"",province_code:e.province_code||null,district_code:e.district_code||null,subdistrict_code:e.subdistrict_code||null,postal_code:e.postal_code||"",latitude:e.latitude,longitude:e.longitude,google_maps_url:e.google_maps_url||"",entrance_fee:e.entrance_fee||"",contact_phone:e.contact_phone||"",website_url:e.website_url||"",is_featured:e.is_featured||!1,status:e.status||"draft",meta_title:e.meta_title||"",meta_description:e.meta_description||""}),M({created_by:e.created_by,created_at:e.created_at,updated_by:e.updated_by,updated_at:e.updated_at}),D(e.id),C(!0)},k=()=>{C(!1),D(null),M(null),K(""),i(E)},le=e=>{e.preventDefault();const a=l.slug||l.name_th.toLowerCase().replace(/\s+/g,"-").replace(/[^\w\-ก-๙]/g,""),t={...l,slug:a};x?L.mutate({id:x,data:t}):I.mutate(t)},ne=e=>{confirm("คุณแน่ใจหรือไม่ที่จะลบแหล่งท่องเที่ยวนี้?")&&ae.mutate(e)},ie=e=>{const a=W.find(t=>t.value===e);return(a==null?void 0:a.label)||e||"-"};return s.jsxs(ge,{children:[s.jsx(xe,{title:"แหล่งท่องเที่ยว",description:"จัดการข้อมูลแหล่งท่องเที่ยว เช่น วัด ทะเล น้ำตก",actionLabel:"เพิ่มแหล่งท่องเที่ยว",onAction:B}),s.jsx(O,{className:"shadow-card mb-6",children:s.jsx(Q,{className:"p-4",children:s.jsxs("div",{className:"relative",children:[s.jsx(oe,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"}),s.jsx(y,{placeholder:"ค้นหาแหล่งท่องเที่ยว...",value:o,onChange:e=>X(e.target.value),className:"pl-10"})]})})}),s.jsx("div",{className:"flex gap-2 mb-4",children:[{value:"all",label:"ทั้งหมด",count:(r==null?void 0:r.length)??0},{value:"published",label:"เผยแพร่",count:(r==null?void 0:r.filter(e=>e.status==="published").length)??0},{value:"draft",label:"ฉบับร่าง",count:(r==null?void 0:r.filter(e=>e.status==="draft").length)??0}].map(e=>s.jsxs(u,{variant:T===e.value?"default":"outline",size:"sm",onClick:()=>Y(e.value),children:[e.label,s.jsx(S,{variant:"secondary",className:"ml-2 text-xs",children:e.count})]},e.value))}),s.jsx(O,{className:"shadow-card",children:s.jsx(Q,{className:"p-0",children:se?s.jsx("div",{className:"flex items-center justify-center py-12",children:s.jsx(R,{className:"h-6 w-6 animate-spin text-primary"})}):(()=>{const e=r==null?void 0:r.filter(a=>T==="all"?!0:a.status===T);return(e==null?void 0:e.length)===0?s.jsxs("div",{className:"text-center py-12",children:[s.jsx(Z,{className:"h-12 w-12 text-muted-foreground mx-auto mb-4"}),s.jsx("h3",{className:"font-medium text-foreground mb-1",children:"ยังไม่มีแหล่งท่องเที่ยว"}),s.jsx("p",{className:"text-sm text-muted-foreground mb-4",children:"เริ่มเพิ่มแหล่งท่องเที่ยวแห่งแรก"}),s.jsxs(u,{onClick:B,children:[s.jsx(ce,{className:"h-4 w-4 mr-2"}),"เพิ่มแหล่งท่องเที่ยว"]})]}):s.jsxs(ye,{children:[s.jsx(ve,{children:s.jsxs(J,{children:[s.jsx(b,{children:"ชื่อแหล่งท่องเที่ยว"}),s.jsx(b,{children:"ประเภท"}
15),s.jsx(b,{children:"จังหวัด/รัฐ"}),s.jsx(b,{children:"สถานะ"}),s.jsx(b,{className:"text-right",children:"การดำเนินการ"})]})}),s.jsx(fe,{children:e==null?void 0:e.map(a=>{var t;return s.jsxs(J,{children:[s.jsx(N,{children:s.jsxs("div",{className:"flex items-center gap-3",children:[a.hero_image_url?s.jsx("img",{src:ue(a.hero_image_url),alt:a.name_th,className:"w-10 h-10 rounded-lg object-cover"}):s.jsx("div",{className:"w-10 h-10 rounded-lg bg-muted flex items-center justify-center",children:s.jsx(Z,{className:"h-4 w-4 text-muted-foreground"})}),s.jsxs("div",{children:[s.jsx("span",{className:"font-medium text-foreground",children:a.name_th}),a.is_featured&&s.jsx(S,{variant:"secondary",className:"text-xs ml-2",children:"แนะนำ"})]})]})}),s.jsx(N,{children:s.jsx(S,{variant:"outline",children:ie(a.attraction_type)})}),s.jsx(N,{children:((t=a.provinces_states)==null?void 0:t.name_th)||"-"}),s.jsx(N,{children:s.jsx(S,{variant:a.status==="published"?"default":"secondary",className:a.status==="published"?"bg-accent":"",children:a.status==="published"?"เผยแพร่":"ฉบับร่าง"})}),s.jsx(N,{className:"text-right",children:s.jsxs("div",{className:"flex items-center justify-end gap-2",children:[s.jsx(u,{variant:"ghost",size:"icon",asChild:!0,children:s.jsx(_e,{to:`/attractions/${a.short_id}`,target:"_blank",children:s.jsx(Ae,{className:"h-4 w-4"})})}),s.jsx(u,{variant:"ghost",size:"icon",onClick:()=>te(a),children:s.jsx(Ee,{className:"h-4 w-4"})}),s.jsx(u,{variant:"ghost",size:"icon",onClick:()=>ne(a.id),className:"text-destructive hover:text-destructive",children:s.jsx(me,{className:"h-4 w-4"})})]})})]},a.id)})})]})})()})}),s.jsx(be,{open:ee,onOpenChange:C,children:s.jsxs(Ne,{className:"max-w-3xl max-h-[90vh] overflow-y-auto",children:[s.jsx(Ce,{children:s.jsx(we,{children:x?"แก้ไขแหล่งท่องเที่ยว":"เพิ่มแหล่งท่องเที่ยวใหม่"})}),x&&j&&s.jsx(je,{createdBy:j.created_by,createdAt:j.created_at,updatedBy:j.updated_by,updatedAt:j.updated_at}),s.jsxs("form",{onSubmit:le,children:[s.jsxs(he,{defaultValue:"basic",className:"w-full",children:[s.jsxs(pe,{className:"grid w-full grid-cols-5 mb-6",children:[s.jsx(v,{value:"basic",children:"ข้อมูลพื้นฐาน"}),s.jsx(v,{value:"media",children:"รูปภาพ"}),s.jsx(v,{value:"location",children:"ตำแหน่ง/ที่ตั้ง"}),s.jsx(v,{value:"seo",children:"SEO"}),s.jsx(v,{value:"settings",children:"ตั้งค่า"})]}),s.jsxs(f,{value:"basic",className:"space-y-4",children:[s.jsxs("div",{className:"space-y-2",children:[s.jsx(d,{children:"ชื่อ (ไทย) *"}),s.jsx(y,{value:l.name_th,onChange:e=>i({...l,name_th:e.target.value}),required:!0})]}),s.jsxs("div",{className:"space-y-2",children:[s.jsx(d,{children:"ประเภทแหล่งท่องเที่ยว"}),s.jsxs($,{value:l.attraction_type,onValueChange:e=>i({...l,attraction_type:e}),children:[s.jsx(z,{children:s.jsx(G,{placeholder:"เลือกประเภท"})}),s.jsx(U,{children:W.map(e=>s.jsx(A,{value:e.value,children:e.label},e.value))})]})]}),s.jsxs("div",{className:"space-y-2",children:[s.jsx(d,{children:"สรุป"}),s.jsx(V,{value:l.summary_th,onChange:e=>i({...l,summary_th:e.target.value}),rows:3,placeholder:"สรุปสั้นๆ เกี่ยวกับแหล่งท่องเที่ยวนี้..."})]}),s.jsx(Le,{label:"รายละเอียด",value:l.content_th,onChange:e=>i({...l,content_th:e}),placeholder:"รายละเอียดเกี่ยวกับแหล่งท่องเที่ยว..."})]}),s.jsxs(f,{value:"media",className:"space-y-4",children:[s.jsxs("div",{className:"space-y-2",children:[s.jsx(d,{children:"รูปภาพหลัก"}),s.jsx(De,{value:l.hero_image_url,onChange:e=>i({...l,hero_image_url:e})})]}),s.jsxs("div",{className:"space-y-2",children:[s.jsx(d,{children:"แกลเลอรี"}),s.jsx(qe,{value:l.gallery_images,onChange:e=>i({...l,gallery_images:e}),onSetAsHero:e=>{const a=l.hero_image_url,t=l.gallery_images.filter(n=>n!==e);a&&t.unshift(a),i({...l,hero_image_url:e,gallery_images:t})}})]})]}),s.jsxs(f,{value:"location",className:"space-y-6",children:[s.jsx(Fe,{countryId:l.destination_country_id,destinationId:l.destination_id,destinationAreaId:l.destination_area_
15id,onChange:e=>i({...l,destination_country_id:e.countryId,destination_id:e.destinationId,destination_area_id:e.destinationAreaId})}),s.jsx(ke,{value:Me(l),onChange:e=>i({...l,address_th:e.addressTh,province_code:e.provinceCode,district_code:e.districtCode,subdistrict_code:e.subdistrictCode,postal_code:e.postalCode})}),s.jsxs("div",{className:"space-y-2",children:[s.jsx(d,{children:"ที่อยู่ (อังกฤษ)"}),s.jsx(y,{value:l.address_en,onChange:e=>i({...l,address_en:e.target.value})})]}),s.jsxs("div",{className:"space-y-2",children:[s.jsx(d,{children:"ตำแหน่งบนแผนที่"}),s.jsx(Ie,{latitude:l.latitude,longitude:l.longitude,onLocationChange:(e,a)=>i({...l,latitude:e,longitude:a})})]}),s.jsxs("div",{className:"space-y-2",children:[s.jsx(d,{children:"Google Maps URL"}),s.jsx(y,{type:"url",value:l.google_maps_url,onChange:e=>i({...l,google_maps_url:e.target.value})})]})]}),s.jsxs(f,{value:"seo",className:"space-y-4",children:[s.jsxs("div",{className:"space-y-2",children:[s.jsx(d,{children:"Meta Title"}),s.jsx(y,{value:l.meta_title,onChange:e=>i({...l,meta_title:e.target.value}),placeholder:"ถ้าว่างจะใช้ชื่อแหล่งท่องเที่ยว"})]}),s.jsxs("div",{className:"space-y-2",children:[s.jsx(d,{children:"Meta Description"}),s.jsx(V,{value:l.meta_description,onChange:e=>i({...l,meta_description:e.target.value}),rows:3,placeholder:"ถ้าว่างจะใช้สรุปย่อ"})]})]}),s.jsxs(f,{value:"settings",className:"space-y-4",children:[s.jsxs("div",{className:"space-y-2",children:[s.jsx(d,{children:"สถานะ"}),s.jsxs($,{value:l.status,onValueChange:e=>i({...l,status:e}),children:[s.jsx(z,{children:s.jsx(G,{})}),s.jsxs(U,{children:[s.jsx(A,{value:"draft",children:"ฉบับร่าง"}),s.jsx(A,{value:"published",children:"เผยแพร่"})]})]})]}),s.jsxs("div",{className:"flex items-center gap-3",children:[s.jsx(Te,{checked:l.is_featured,onCheckedChange:e=>i({...l,is_featured:e})}),s.jsx(d,{children:"แนะนำ (Featured)"})]})]})]}),s.jsxs(Se,{className:"mt-6",children:[s.jsx(u,{type:"button",variant:"outline",onClick:k,children:"ยกเลิก"}),s.jsxs(u,{type:"submit",disabled:I.isPending||L.isPending,children:[(I.isPending||L.isPending)&&s.jsx(R,{className:"h-4 w-4 mr-2 animate-spin"}),x?"บันทึก":"เพิ่ม"]})]})]})]})})]})}export{Ns 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.