Compare commits
11 Commits
57a5c0cce3
...
dev02
| Author | SHA1 | Date | |
|---|---|---|---|
| 77bb3e7c80 | |||
| f203b74e88 | |||
| 8cf51275b8 | |||
| b6c4298529 | |||
| b6dd223fb3 | |||
| c61bf4b15a | |||
| 3e69ec7d12 | |||
| 9ecde8d366 | |||
| a4e84a4c0f | |||
| 27a52ec1ee | |||
| 90e18c5a81 |
@@ -45,3 +45,6 @@ Instead, ALWAYS use the `activeTheme` variable to dynamically load the active th
|
||||
|
||||
### Admin Panel UI Pattern: Lists
|
||||
When building admin panels to manage lists of items, DO NOT use inline `<input>` fields for all rows by default. Instead, use a **read-only view** for the list items, providing explicit **"Edit"** and **"Delete"** buttons for each row. Clicking "Edit" should open a modal or expand the row to allow editing the fields.
|
||||
|
||||
### Data Seeding & Content Cloning
|
||||
When seeding, populating, or importing new posts, pages, categories, tags, or other domain entities from external files (e.g., HTML, JSON, CSV), ALWAYS use a Python script (`seed_*.py`) to parse the source files and generate/execute the necessary seeder components or database operations.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
:root{--swiper-navigation-size:44px}.swiper-button-next,.swiper-button-prev{position:absolute;top:var(--swiper-navigation-top-offset,50%);width:calc(var(--swiper-navigation-size) / 44 * 27);height:var(--swiper-navigation-size);margin-top:calc(0px - (var(--swiper-navigation-size) / 2));z-index:10;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--swiper-navigation-color,var(--swiper-theme-color))}.swiper-button-next.swiper-button-disabled,.swiper-button-prev.swiper-button-disabled{opacity:.35;cursor:auto;pointer-events:none}.swiper-button-next.swiper-button-hidden,.swiper-button-prev.swiper-button-hidden{opacity:0;cursor:auto;pointer-events:none}.swiper-navigation-disabled .swiper-button-next,.swiper-navigation-disabled .swiper-button-prev{display:none!important}.swiper-button-next svg,.swiper-button-prev svg{width:100%;height:100%;object-fit:contain;transform-origin:center}.swiper-rtl .swiper-button-next svg,.swiper-rtl .swiper-button-prev svg{transform:rotate(180deg)}.swiper-button-prev,.swiper-rtl .swiper-button-next{left:var(--swiper-navigation-sides-offset,10px);right:auto}.swiper-button-lock{display:none}.swiper-button-next:after,.swiper-button-prev:after{font-family:swiper-icons;font-size:var(--swiper-navigation-size);text-transform:none!important;letter-spacing:0;font-variant:normal;line-height:1}.swiper-button-prev:after,.swiper-rtl .swiper-button-next:after{content:"prev"}.swiper-button-next,.swiper-rtl .swiper-button-prev{right:var(--swiper-navigation-sides-offset,10px);left:auto}.swiper-button-next:after,.swiper-rtl .swiper-button-prev:after{content:"next"}
|
||||
@@ -0,0 +1 @@
|
||||
"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[7953],{46101:(e,t,r)=>{r.d(t,{v:()=>o});var n=r(66724),a=r(59913);let l=e=>e,i=e=>{let t=(0,a.y)(e),r=e=>(function(e,t=l){let r=n.useSyncExternalStore(e.subscribe,n.useCallback(()=>t(e.getState()),[e,t]),n.useCallback(()=>t(e.getInitialState()),[e,t]));return n.useDebugValue(r),r})(t,e);return Object.assign(r,t),r},o=e=>e?i(e):i},47526:(e,t,r)=>{r.d(t,{Zr:()=>a});let n=e=>t=>{try{let r=e(t);if(r instanceof Promise)return r;return{then:e=>n(e)(r),catch(e){return this}}}catch(e){return{then(e){return this},catch:t=>n(t)(e)}}},a=(e,t)=>(r,a,l)=>{let i,o={storage:function(e,t){let r;try{r=e()}catch(e){return}return{getItem:e=>{var t;let n=e=>null===e?null:JSON.parse(e,void 0),a=null!=(t=r.getItem(e))?t:null;return a instanceof Promise?a.then(n):n(a)},setItem:(e,t)=>r.setItem(e,JSON.stringify(t,void 0)),removeItem:e=>r.removeItem(e)}}(()=>localStorage),partialize:e=>e,version:0,merge:(e,t)=>({...t,...e}),...t},s=!1,u=new Set,c=new Set,d=o.storage;if(!d)return e((...e)=>{console.warn(`[zustand persist middleware] Unable to update item '${o.name}', the given storage is currently unavailable.`),r(...e)},a,l);let m=()=>{let e=o.partialize({...a()});return d.setItem(o.name,{state:e,version:o.version})},h=l.setState;l.setState=(e,t)=>(h(e,t),m());let g=e((...e)=>(r(...e),m()),a,l);l.getInitialState=()=>g;let f=()=>{var e,t;if(!d)return;s=!1,u.forEach(e=>{var t;return e(null!=(t=a())?t:g)});let l=(null==(t=o.onRehydrateStorage)?void 0:t.call(o,null!=(e=a())?e:g))||void 0;return n(d.getItem.bind(d))(o.name).then(e=>{if(e)if("number"!=typeof e.version||e.version===o.version)return[!1,e.state];else{if(o.migrate){let t=o.migrate(e.state,e.version);return t instanceof Promise?t.then(e=>[!0,e]):[!0,t]}console.error("State loaded from storage couldn't be migrated since no migrate function was provided")}return[!1,void 0]}).then(e=>{var t;let[n,l]=e;if(r(i=o.merge(l,null!=(t=a())?t:g),!0),n)return m()}).then(()=>{null==l||l(i,void 0),i=a(),s=!0,c.forEach(e=>e(i))}).catch(e=>{null==l||l(void 0,e)})};return l.persist={setOptions:e=>{o={...o,...e},e.storage&&(d=e.storage)},clearStorage:()=>{null==d||d.removeItem(o.name)},getOptions:()=>o,rehydrate:()=>f(),hasHydrated:()=>s,onHydrate:e=>(u.add(e),()=>{u.delete(e)}),onFinishHydration:e=>(c.add(e),()=>{c.delete(e)})},o.skipHydration||f(),i||g}},54173:(e,t,r)=>{r.d(t,{c3:()=>l});var n=r(7283);function a(e,t){return(...e)=>{try{return t(...e)}catch{throw Error(void 0)}}}let l=a(0,n.c3);a(0,n.kc)},59913:(e,t,r)=>{r.d(t,{y:()=>a});let n=e=>{let t,r=new Set,n=(e,n)=>{let a="function"==typeof e?e(t):e;if(!Object.is(a,t)){let e=t;t=(null!=n?n:"object"!=typeof a||null===a)?a:Object.assign({},t,a),r.forEach(r=>r(t,e))}},a=()=>t,l={setState:n,getState:a,getInitialState:()=>i,subscribe:e=>(r.add(e),()=>r.delete(e))},i=t=e(n,a,l);return l},a=e=>e?n(e):n},68148:(e,t,r)=>{r.d(t,{A:()=>c});var n=r(66724);let a=e=>e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),l=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(e,t,r)=>r?r.toUpperCase():t.toLowerCase()),i=e=>{let t=l(e);return t.charAt(0).toUpperCase()+t.slice(1)},o=function(){for(var e=arguments.length,t=Array(e),r=0;r<e;r++)t[r]=arguments[r];return t.filter((e,t,r)=>!!e&&""!==e.trim()&&r.indexOf(e)===t).join(" ").trim()};var s={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};let u=(0,n.forwardRef)((e,t)=>{let{color:r="currentColor",size:a=24,strokeWidth:l=2,absoluteStrokeWidth:i,className:u="",children:c,iconNode:d,...m}=e;return(0,n.createElement)("svg",{ref:t,...s,width:a,height:a,stroke:r,strokeWidth:i?24*Number(l)/Number(a):l,className:o("lucide",u),...m},[...d.map(e=>{let[t,r]=e;return(0,n.createElement)(t,r)}),...Array.isArray(c)?c:[c]])}),c=(e,t)=>{let r=(0,n.forwardRef)((r,l)=>{let{className:s,...c}=r;return(0,n.createElement)(u,{ref:l,iconNode:t,className:o("lucide-".concat(a(i(e))),"lucide-".concat(e),s),...c})});return r.displayName=i(e),r}}}]);
|
||||
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 62 KiB |
@@ -0,0 +1 @@
|
||||
/* PLEASE DO NOT COPY AND PASTE THIS CODE. */(function(){var w=window,C='___grecaptcha_cfg',cfg=w[C]=w[C]||{},N='grecaptcha';var gr=w[N]=w[N]||{};gr.ready=gr.ready||function(f){(cfg['fns']=cfg['fns']||[]).push(f);};w['__recaptcha_api']='https://www.google.com/recaptcha/api2/';(cfg['render']=cfg['render']||[]).push('onload');(cfg['anchor-ms']=cfg['anchor-ms']||[]).push(20000);(cfg['execute-ms']=cfg['execute-ms']||[]).push(30000);w['__google_recaptcha_client']=true;var d=document,po=d.createElement('script');po.type='text/javascript';po.async=true; po.charset='utf-8';var v=w.navigator,m=d.createElement('meta');m.httpEquiv='origin-trial';m.content='A7vZI3v+Gz7JfuRolKNM4Aff6zaGuT7X0mf3wtoZTnKv6497cVMnhy03KDqX7kBz/q/iidW7srW31oQbBt4VhgoAAACUeyJvcmlnaW4iOiJodHRwczovL3d3dy5nb29nbGUuY29tOjQ0MyIsImZlYXR1cmUiOiJEaXNhYmxlVGhpcmRQYXJ0eVN0b3JhZ2VQYXJ0aXRpb25pbmczIiwiZXhwaXJ5IjoxNzU3OTgwODAwLCJpc1N1YmRvbWFpbiI6dHJ1ZSwiaXNUaGlyZFBhcnR5Ijp0cnVlfQ==';if(v&&v.cookieDeprecationLabel){v.cookieDeprecationLabel.getValue().then(function(l){if(l!=='treatment_1.1'&&l!=='treatment_1.2'&&l!=='control_1.1'){d.head.prepend(m);}});}else{d.head.prepend(m);}po.src='https://www.gstatic.com/recaptcha/releases/XOqlk8PL_yVx6IdpLbpXdiLy/recaptcha__en.js';po.crossOrigin='anonymous';po.integrity='sha384-5gTdLl6IS0Y6zKiLKimmhaY3IOLosQFpvj9Tvt9s2RAiKLtLUEWOP5N8mtHLNUzF';var e=d.querySelector('script[nonce]'),n=e&&(e['nonce']||e.getAttribute('nonce'));if(n){po.setAttribute('nonce',n);}var s=d.getElementsByTagName('script')[0];s.parentNode.insertBefore(po, s);})();
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 244 KiB |
@@ -0,0 +1 @@
|
||||
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[8530],{28377:(e,r,t)=>{Promise.resolve().then(t.bind(t,38982))},38982:(e,r,t)=>{"use strict";t.r(r),t.d(r,{default:()=>i});var n=t(45704),a=t(66724),s=t(99018);function i(e){let{error:r,reset:t}=e,i=(0,s.useParams)().locale||"vi";return(0,a.useEffect)(()=>{},[r]),(0,n.jsxs)("main",{className:"flex min-h-screen flex-col items-center justify-center gap-4 p-4 text-center",children:[(0,n.jsx)("h1",{className:"text-3xl font-bold text-gray-800 md:text-4xl",children:{vi:"Đ\xe3 xảy ra lỗi",en:"Something went wrong"}[i]}),(0,n.jsx)("p",{className:"mx-auto max-w-md text-gray-600",children:{vi:"Đ\xe3 c\xf3 lỗi xảy ra. Vui l\xf2ng thử lại sau.",en:"An error has occurred. Please try again later."}[i]}),(0,n.jsx)("button",{onClick:t,className:"mt-6 inline-flex items-center justify-center rounded-md bg-red px-6 py-3 text-white transition-colors hover:bg-black",children:{vi:"Thử lại",en:"Try again"}[i]})]})}},99018:(e,r,t)=>{"use strict";var n=t(91166);t.o(n,"permanentRedirect")&&t.d(r,{permanentRedirect:function(){return n.permanentRedirect}}),t.o(n,"redirect")&&t.d(r,{redirect:function(){return n.redirect}}),t.o(n,"useParams")&&t.d(r,{useParams:function(){return n.useParams}}),t.o(n,"usePathname")&&t.d(r,{usePathname:function(){return n.usePathname}}),t.o(n,"useRouter")&&t.d(r,{useRouter:function(){return n.useRouter}}),t.o(n,"useSearchParams")&&t.d(r,{useSearchParams:function(){return n.useSearchParams}})}},e=>{var r=r=>e(e.s=r);e.O(0,[1032,4619,7358],()=>r(28377)),_N_E=e.O()}]);
|
||||
|
After Width: | Height: | Size: 581 B |
|
After Width: | Height: | Size: 147 KiB |
@@ -0,0 +1 @@
|
||||
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[4219],{70094:(e,s,n)=>{Promise.resolve().then(n.bind(n,87959))},87959:(e,s,n)=>{"use strict";n.r(s),n.d(s,{default:()=>u});var l=n(45704),r=n(24293),t=n(39774),a=n.n(t);function u(e){return(0,l.jsx)("html",{lang:r.DT.defaultLocale,children:(0,l.jsx)("body",{children:(0,l.jsx)(a(),{statusCode:0})})})}}},e=>{var s=s=>e(e.s=s);e.O(0,[2263,6696,6069,4293,1032,4619,7358],()=>s(70094)),_N_E=e.O()}]);
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
After Width: | Height: | Size: 192 KiB |
@@ -0,0 +1 @@
|
||||
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[7358],{24473:(e,s,n)=>{Promise.resolve().then(n.t.bind(n,14933,23)),Promise.resolve().then(n.t.bind(n,86695,23)),Promise.resolve().then(n.t.bind(n,54775,23)),Promise.resolve().then(n.t.bind(n,22908,23)),Promise.resolve().then(n.t.bind(n,23624,23)),Promise.resolve().then(n.t.bind(n,59440,23)),Promise.resolve().then(n.t.bind(n,62920,23)),Promise.resolve().then(n.t.bind(n,19710,23))}},e=>{var s=s=>e(e.s=s);e.O(0,[1032,4619],()=>(s(36596),s(24473))),_N_E=e.O()}]);
|
||||
@@ -0,0 +1 @@
|
||||
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[3224],{14939:(e,t,n)=>{Promise.resolve().then(n.bind(n,65200))},15589:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"useMergedRef",{enumerable:!0,get:function(){return l}});let r=n(66724);function l(e,t){let n=(0,r.useRef)(null),l=(0,r.useRef)(null);return(0,r.useCallback)(r=>{if(null===r){let e=n.current;e&&(n.current=null,e());let t=l.current;t&&(l.current=null,t())}else e&&(n.current=u(e,r)),t&&(l.current=u(t,r))},[e,t])}function u(e,t){if("function"!=typeof e)return e.current=t,()=>{e.current=null};{let n=e(t);return"function"==typeof n?n:()=>e(null)}}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},65200:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(45704),l=n(51193),u=n.n(l),c=n(99018);function a(){let e=(0,c.useParams)().locale||"vi";return(0,r.jsxs)("main",{className:"flex min-h-screen flex-col items-center justify-center gap-4 p-4 text-center",children:[(0,r.jsx)("h1",{className:"text-9xl font-bold text-gray-800",children:"404"}),(0,r.jsx)("h2",{className:"text-2xl font-semibold md:text-3xl",children:{vi:"Trang kh\xf4ng tồn tại",en:"Page Not Found"}[e]}),(0,r.jsx)("p",{className:"mx-auto max-w-md text-gray-600",children:{vi:"Xin lỗi, trang bạn đang t\xecm kiếm kh\xf4ng tồn tại hoặc đ\xe3 được di chuyển.",en:"Sorry, the page you are looking for doesn't exist or has been moved."}[e]}),(0,r.jsx)(u(),{href:"/".concat(e),className:"mt-6 inline-flex items-center justify-center rounded-md bg-red px-6 py-3 text-white transition-colors hover:bg-black",children:{vi:"Quay về trang chủ",en:"Back to home"}[e]})]})}}},e=>{var t=t=>e(e.s=t);e.O(0,[6696,1032,4619,7358],()=>t(14939)),_N_E=e.O()}]);
|
||||
@@ -0,0 +1 @@
|
||||
!function(r,i){"use strict";var e,o=r.location,s=r.document,t=s.querySelector('[src*="'+i+'"]'),l=t&&t.getAttribute("data-domain"),p=r.localStorage.plausible_ignore;function c(e){console.warn("Ignoring Event: "+e)}function a(e,t){if(/^localhost$|^127(?:\.[0-9]+){0,2}\.[0-9]+$|^(?:0*\:)*?:?0*1$/.test(o.hostname)||"file:"===o.protocol)return c("localhost");if(!(r.phantom||r._phantom||r.__nightmare||r.navigator.webdriver||r.Cypress)){if("true"==p)return c("localStorage flag");var a={};a.n=e,a.u=o.href,a.d=l,a.r=s.referrer||null,a.w=r.innerWidth,t&&t.meta&&(a.m=JSON.stringify(t.meta)),t&&t.props&&(a.p=JSON.stringify(t.props));var n=new XMLHttpRequest;n.open("POST",i+"/api/event",!0),n.setRequestHeader("Content-Type","text/plain"),n.send(JSON.stringify(a)),n.onreadystatechange=function(){4==n.readyState&&t&&t.callback&&t.callback()}}}function n(){e!==o.pathname&&(e=o.pathname,a("pageview"))}try{var u,h=r.history;h.pushState&&(u=h.pushState,h.pushState=function(){u.apply(this,arguments),n()},r.addEventListener("popstate",n));var g=r.plausible&&r.plausible.q||[];r.plausible=a;for(var f=0;f<g.length;f++)a.apply(this,g[f]);"prerender"===s.visibilityState?s.addEventListener("visibilitychange",function(){e||"visible"!==s.visibilityState||n()}):n()}catch(e){console.error(e),(new Image).src=i+"/api/error?message="+encodeURIComponent(e.message)}}(window,"https://analytics.jamstackvietnam.com");
|
||||
|
After Width: | Height: | Size: 1.3 KiB |