Repository: awesome-academy/naitei_ruby_10_02_2025_food_and_drink
Pull request #14: Feature #85842: order management for admin
Author: login: khanhdx-0573
Created: 2025-03-28T04:13:08Z | Merged: 2025-03-28T07:13:13Z

## Related Tickets
- https://edu-redmine.sun-asterisk.vn/issues/85842

## WHAT (optional)
- Change number items `completed/total` in admin page.

## HOW
- I edit js file, inject not_vary_normal items in calculate function.

## WHY (optional)
- Because in previous version - number just depends on `normal` items. But in new version, we have `state` and `confirm_state` depends on both `normal` + `not_normal` items.

## Evidence (Screenshot or Video)
![image](https://github.com/user-attachments/assets/f65017e7-bbec-410e-8042-f028cb38c08d)
### Xem tất cả order
![image](https://github.com/user-attachments/assets/d27a9a7e-499c-4bba-971d-45657307a328)
![image](https://github.com/user-attachments/assets/af1840c2-d315-4f36-97a4-52fb99e538d2)
- Có thể filter theo status, date 
![Uploading image.png…]()

### Cập nhật
![image](https://github.com/user-attachments/assets/ff8b596a-5bbc-49b5-90f4-c47c0079b051)
### Xóa
![image](https://github.com/user-attachments/assets/3a32b60b-34d3-4ce5-bb77-e857cbb9cb2c)





Diff:
diff --git a/app/assets/builds/tailwind.css b/app/assets/builds/tailwind.css
index 492b5d3..21ee887 100644
--- a/app/assets/builds/tailwind.css
+++ b/app/assets/builds/tailwind.css
@@ -1 +1 @@
-*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.17 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-feature-settings:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]:where(:not([hidden=until-found])){display:none}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.-right-1{right:-.25rem}.-top-1{top:-.25rem}.right-0{right:0}.top-0{top:0}.top-24{top:6rem}.z-50{z-index:50}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-4{margin-left:1rem;margin-right:1rem}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.ml-4{margin-left:1rem}.mr-1{margin-right:.25rem}.mr-2{margin-right:.5rem}.mr-4{margin-right:1rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.flow-root{display:flow-root}.grid{display:grid}.hidden{display:none}.aspect-square{aspect-ratio:1/1}.h-1{height:.25rem}.h-10{height:2.5rem}.h-16{height:4rem}.h-24{height:6rem}.h-3{height:.75rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-full{height:100%}.max-h-\[90vh\]{max-height:90vh}.min-h-screen{min-height:100vh}.w-10{width:2.5rem}.w-12{width:3rem}.w-16{width:4rem}.w-24{width:6rem}.w-3{width:.75rem}.w-32{width:8rem}.w-4{width:1rem}.w-48{width:12rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-8{width:2rem}.w-full{width:100%}.max-w-2xl{max-width:42rem}.max-w-md{max-width:28rem}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.origin-top-right{transform-origin:top right}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.gap-8{gap:2rem}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.25rem*var(--tw-space-x-reverse))}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.space-x-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.75rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.75rem*var(--tw-space-x-reverse))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.25rem*var(--tw-space-y-reverse));margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.75rem*var(--tw-space-y-reverse));margin-top:calc(.75rem*(1 - var(--tw-space-y-reverse)))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1rem*var(--tw-space-y-reverse));margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.5rem*var(--tw-space-y-reverse));margin-top:calc(1.5rem*(1 - var(--tw-space-y-reverse)))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2rem*var(--tw-space-y-reverse));margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-bottom-width:calc(1px*var(--tw-divide-y-reverse));border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)))}.divide-gray-200>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(229 231 235/var(--tw-divide-opacity,1))}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.whitespace-nowrap{white-space:nowrap}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-l-md{border-bottom-left-radius:.375rem;border-top-left-radius:.375rem}.rounded-r-md{border-bottom-right-radius:.375rem;border-top-right-radius:.375rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-l-4{border-left-width:4px}.border-t{border-top-width:1px}.border-none{border-style:none}.border-gray-100{--tw-border-opacity:1;border-color:rgb(243 244 246/var(--tw-border-opacity,1))}.border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1))}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1))}.border-red-500{--tw-border-opacity:1;border-color:rgb(239 68 68/var(--tw-border-opacity,1))}.border-transparent{border-color:transparent}.bg-black{--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity,1))}.bg-blue-100{--tw-bg-opacity:1;background-color:rgb(219 234 254/var(--tw-bg-opacity,1))}.bg-blue-50{--tw-bg-opacity:1;background-color:rgb(239 246 255/var(--tw-bg-opacity,1))}.bg-blue-500{--tw-bg-opacity:1;background-color:rgb(59 130 246/var(--tw-bg-opacity,1))}.bg-blue-600{--tw-bg-opacity:1;background-color:rgb(37 99 235/var(--tw-bg-opacity,1))}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.bg-gray-200{--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity,1))}.bg-gray-300{--tw-bg-opacity:1;background-color:rgb(209 213 219/var(--tw-bg-opacity,1))}.bg-gray-50{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.bg-green-100{--tw-bg-opacity:1;background-color:rgb(220 252 231/var(--tw-bg-opacity,1))}.bg-red-100{--tw-bg-opacity:1;background-color:rgb(254 226 226/var(--tw-bg-opacity,1))}.bg-red-500{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity,1))}.bg-red-600{--tw-bg-opacity:1;background-color:rgb(220 38 38/var(--tw-bg-opacity,1))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.bg-yellow-100{--tw-bg-opacity:1;background-color:rgb(254 249 195/var(--tw-bg-opacity,1))}.bg-opacity-50{--tw-bg-opacity:0.5}.object-cover{-o-object-fit:cover;object-fit:cover}.p-2{padding:.5rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0{padding-bottom:0;padding-top:0}.py-0\.5{padding-bottom:.125rem;padding-top:.125rem}.py-1{padding-bottom:.25rem;padding-top:.25rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.py-4{padding-bottom:1rem;padding-top:1rem}.py-6{padding-bottom:1.5rem;padding-top:1.5rem}.py-8{padding-bottom:2rem;padding-top:2rem}.pb-2{padding-bottom:.5rem}.pb-3{padding-bottom:.75rem}.pb-4{padding-bottom:1rem}.pt-0{padding-top:0}.pt-2{padding-top:.5rem}.pt-4{padding-top:1rem}.text-center{text-align:center}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.text-blue-600{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.text-blue-800{--tw-text-opacity:1;color:rgb(30 64 175/var(--tw-text-opacity,1))}.text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity,1))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.text-gray-800{--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity,1))}.text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}.text-green-800{--tw-text-opacity:1;color:rgb(22 101 52/var(--tw-text-opacity,1))}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.text-red-600{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity,1))}.text-red-700{--tw-text-opacity:1;color:rgb(185 28 28/var(--tw-text-opacity,1))}.text-red-800{--tw-text-opacity:1;color:rgb(153 27 27/var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.text-yellow-800{--tw-text-opacity:1;color:rgb(133 77 14/var(--tw-text-opacity,1))}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.shadow-lg,.shadow-md{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-black{--tw-ring-opacity:1;--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity,1))}.ring-opacity-5{--tw-ring-opacity:0.05}.transition-colors{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-transform{transition-duration:.15s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-300{transition-duration:.3s}.nav-item{align-items:center;display:flex;font-size:.875rem;font-weight:500;line-height:1.25rem;--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.nav-item:hover{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}.drop-down-item{display:block;font-size:.875rem;line-height:1.25rem;padding:.5rem 1rem;--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.drop-down-item:hover{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.nav-mobile-item{border-radius:.375rem;display:block;font-size:1rem;font-weight:500;line-height:1.5rem;padding:.5rem .75rem;--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.nav-mobile-item:hover{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}.input-field{border-radius:.375rem;border-width:1px;--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1))}.input-field:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity,1))}.button-common{align-items:center;border-color:transparent;border-radius:.375rem;border-width:1px;display:flex;justify-content:center;margin-top:.5rem;--tw-bg-opacity:1;background-color:rgb(37 99 235/var(--tw-bg-opacity,1));font-size:.875rem;font-weight:500;line-height:1.25rem;padding:.5rem 1rem;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1));--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.button-common:hover{--tw-bg-opacity:1;background-color:rgb(29 78 216/var(--tw-bg-opacity,1))}.button-common:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity,1));--tw-ring-offset-width:2px}.pending{background-color:rgb(219 234 254/var(--tw-bg-opacity,1));color:rgb(30 64 175/var(--tw-text-opacity,1))}.confirmed,.pending{--tw-bg-opacity:1;--tw-text-opacity:1}.confirmed{background-color:rgb(220 252 231/var(--tw-bg-opacity,1));color:rgb(22 101 52/var(--tw-text-opacity,1))}.delivered{background-color:rgb(254 249 195/var(--tw-bg-opacity,1));color:rgb(133 77 14/var(--tw-text-opacity,1))}.cancelled,.delivered{--tw-bg-opacity:1;--tw-text-opacity:1}.cancelled{background-color:rgb(254 226 226/var(--tw-bg-opacity,1));color:rgb(153 27 27/var(--tw-text-opacity,1))}.pagy{display:flex}.pagy>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.25rem*var(--tw-space-x-reverse))}.pagy{font-size:.875rem;font-weight:600;line-height:1.25rem;--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1));a:not(.gap){border-radius:.5rem;display:block;--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity,1));padding-bottom:.25rem;padding-left:.75rem;padding-right:.75rem;padding-top:.25rem}a:not(.gap){&:hover{--tw-bg-opacity:1;background-color:rgb(209 213 219/var(--tw-bg-opacity,1))}&:not([href]){cursor:default;--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity,1))}&.current{--tw-bg-opacity:1;background-color:rgb(156 163 175/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}}label{border-radius:.5rem;display:inline-block;white-space:nowrap;--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity,1));padding-bottom:.125rem;padding-left:.75rem;padding-right:.75rem;padding-top:.125rem}label{input{border-radius:.375rem;border-style:none;--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}}}.hover\:rotate-1:hover{--tw-rotate:1deg}.hover\:rotate-1:hover,.hover\:scale-105:hover{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:scale-105:hover{--tw-scale-x:1.05;--tw-scale-y:1.05}.hover\:scale-110:hover{--tw-scale-x:1.1;--tw-scale-y:1.1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:bg-blue-700:hover{--tw-bg-opacity:1;background-color:rgb(29 78 216/var(--tw-bg-opacity,1))}.hover\:bg-gray-100:hover{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.hover\:bg-gray-200:hover{--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity,1))}.hover\:bg-gray-50:hover{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.hover\:bg-red-50:hover{--tw-bg-opacity:1;background-color:rgb(254 242 242/var(--tw-bg-opacity,1))}.hover\:bg-red-700:hover{--tw-bg-opacity:1;background-color:rgb(185 28 28/var(--tw-bg-opacity,1))}.hover\:text-blue-500:hover{--tw-text-opacity:1;color:rgb(59 130 246/var(--tw-text-opacity,1))}.hover\:text-gray-700:hover{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.hover\:text-gray-900:hover{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}.hover\:text-red-500:hover{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.hover\:underline:hover{text-decoration-line:underline}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\:ring-blue-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity,1))}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px}@media (min-width:640px){.sm\:inline-block{display:inline-block}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}}@media (min-width:768px){.md\:col-span-1{grid-column:span 1/span 1}.md\:col-span-2{grid-column:span 2/span 2}.md\:ml-10{margin-left:2.5rem}.md\:mr-4{margin-right:1rem}.md\:mt-0{margin-top:0}.md\:flex{display:flex}.md\:hidden{display:none}.md\:w-1\/3{width:33.333333%}.md\:w-2\/3{width:66.666667%}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:items-center{align-items:center}.md\:space-x-8>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(2rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(2rem*var(--tw-space-x-reverse))}}@media (min-width:1024px){.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:px-8{padding-left:2rem;padding-right:2rem}}
\ No newline at end of file
+*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.17 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-feature-settings:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]:where(:not([hidden=until-found])){display:none}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.-right-1{right:-.25rem}.-top-1{top:-.25rem}.right-0{right:0}.top-0{top:0}.top-24{top:6rem}.z-50{z-index:50}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-4{margin-left:1rem;margin-right:1rem}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.ml-4{margin-left:1rem}.mr-1{margin-right:.25rem}.mr-2{margin-right:.5rem}.mr-4{margin-right:1rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.flow-root{display:flow-root}.grid{display:grid}.hidden{display:none}.aspect-square{aspect-ratio:1/1}.h-1{height:.25rem}.h-10{height:2.5rem}.h-16{height:4rem}.h-24{height:6rem}.h-3{height:.75rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-full{height:100%}.max-h-\[90vh\]{max-height:90vh}.min-h-screen{min-height:100vh}.w-10{width:2.5rem}.w-12{width:3rem}.w-16{width:4rem}.w-24{width:6rem}.w-3{width:.75rem}.w-32{width:8rem}.w-4{width:1rem}.w-48{width:12rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-8{width:2rem}.w-full{width:100%}.min-w-full{min-width:100%}.max-w-2xl{max-width:42rem}.max-w-md{max-width:28rem}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.origin-top-right{transform-origin:top right}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.gap-8{gap:2rem}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.25rem*var(--tw-space-x-reverse))}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.space-x-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.75rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.75rem*var(--tw-space-x-reverse))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.25rem*var(--tw-space-y-reverse));margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.75rem*var(--tw-space-y-reverse));margin-top:calc(.75rem*(1 - var(--tw-space-y-reverse)))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1rem*var(--tw-space-y-reverse));margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.5rem*var(--tw-space-y-reverse));margin-top:calc(1.5rem*(1 - var(--tw-space-y-reverse)))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2rem*var(--tw-space-y-reverse));margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-bottom-width:calc(1px*var(--tw-divide-y-reverse));border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)))}.divide-gray-200>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(229 231 235/var(--tw-divide-opacity,1))}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.whitespace-nowrap{white-space:nowrap}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-l-md{border-bottom-left-radius:.375rem;border-top-left-radius:.375rem}.rounded-r-md{border-bottom-right-radius:.375rem;border-top-right-radius:.375rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-l-4{border-left-width:4px}.border-t{border-top-width:1px}.border-none{border-style:none}.border-gray-100{--tw-border-opacity:1;border-color:rgb(243 244 246/var(--tw-border-opacity,1))}.border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1))}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1))}.border-red-500{--tw-border-opacity:1;border-color:rgb(239 68 68/var(--tw-border-opacity,1))}.border-transparent{border-color:transparent}.bg-black{--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity,1))}.bg-blue-100{--tw-bg-opacity:1;background-color:rgb(219 234 254/var(--tw-bg-opacity,1))}.bg-blue-50{--tw-bg-opacity:1;background-color:rgb(239 246 255/var(--tw-bg-opacity,1))}.bg-blue-500{--tw-bg-opacity:1;background-color:rgb(59 130 246/var(--tw-bg-opacity,1))}.bg-blue-600{--tw-bg-opacity:1;background-color:rgb(37 99 235/var(--tw-bg-opacity,1))}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.bg-gray-200{--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity,1))}.bg-gray-300{--tw-bg-opacity:1;background-color:rgb(209 213 219/var(--tw-bg-opacity,1))}.bg-gray-50{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.bg-green-100{--tw-bg-opacity:1;background-color:rgb(220 252 231/var(--tw-bg-opacity,1))}.bg-green-600{--tw-bg-opacity:1;background-color:rgb(22 163 74/var(--tw-bg-opacity,1))}.bg-red-100{--tw-bg-opacity:1;background-color:rgb(254 226 226/var(--tw-bg-opacity,1))}.bg-red-500{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity,1))}.bg-red-600{--tw-bg-opacity:1;background-color:rgb(220 38 38/var(--tw-bg-opacity,1))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.bg-yellow-100{--tw-bg-opacity:1;background-color:rgb(254 249 195/var(--tw-bg-opacity,1))}.bg-opacity-50{--tw-bg-opacity:0.5}.object-cover{-o-object-fit:cover;object-fit:cover}.p-2{padding:.5rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0{padding-bottom:0;padding-top:0}.py-0\.5{padding-bottom:.125rem;padding-top:.125rem}.py-1{padding-bottom:.25rem;padding-top:.25rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.py-4{padding-bottom:1rem;padding-top:1rem}.py-6{padding-bottom:1.5rem;padding-top:1.5rem}.py-8{padding-bottom:2rem;padding-top:2rem}.pb-2{padding-bottom:.5rem}.pb-3{padding-bottom:.75rem}.pb-4{padding-bottom:1rem}.pt-0{padding-top:0}.pt-2{padding-top:.5rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.leading-5{line-height:1.25rem}.tracking-wider{letter-spacing:.05em}.text-blue-600{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity,1))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.text-red-600{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity,1))}.text-red-700{--tw-text-opacity:1;color:rgb(185 28 28/var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.shadow-lg,.shadow-md{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-black{--tw-ring-opacity:1;--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity,1))}.ring-opacity-5{--tw-ring-opacity:0.05}.transition-colors{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-transform{transition-duration:.15s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-300{transition-duration:.3s}.nav-item{align-items:center;display:flex;font-size:.875rem;font-weight:500;line-height:1.25rem;--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.nav-item:hover{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}.drop-down-item{display:block;font-size:.875rem;line-height:1.25rem;padding:.5rem 1rem;--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.drop-down-item:hover{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.nav-mobile-item{border-radius:.375rem;display:block;font-size:1rem;font-weight:500;line-height:1.5rem;padding:.5rem .75rem;--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.nav-mobile-item:hover{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}.input-field{border-radius:.375rem;border-width:1px;--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1))}.input-field:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity,1))}.button-common{align-items:center;border-color:transparent;border-radius:.375rem;border-width:1px;display:flex;justify-content:center;margin-top:.5rem;--tw-bg-opacity:1;background-color:rgb(37 99 235/var(--tw-bg-opacity,1));font-size:.875rem;font-weight:500;line-height:1.25rem;padding:.5rem 1rem;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1));--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.button-common:hover{--tw-bg-opacity:1;background-color:rgb(29 78 216/var(--tw-bg-opacity,1))}.button-common:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity,1));--tw-ring-offset-width:2px}.pending{background-color:rgb(219 234 254/var(--tw-bg-opacity,1));color:rgb(30 64 175/var(--tw-text-opacity,1))}.confirmed,.pending{--tw-bg-opacity:1;--tw-text-opacity:1}.confirmed{background-color:rgb(220 252 231/var(--tw-bg-opacity,1));color:rgb(22 101 52/var(--tw-text-opacity,1))}.delivered{background-color:rgb(254 249 195/var(--tw-bg-opacity,1));color:rgb(133 77 14/var(--tw-text-opacity,1))}.canceled,.delivered{--tw-bg-opacity:1;--tw-text-opacity:1}.canceled{background-color:rgb(254 226 226/var(--tw-bg-opacity,1));color:rgb(153 27 27/var(--tw-text-opacity,1))}.pagy{display:flex}.pagy>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.25rem*var(--tw-space-x-reverse))}.pagy{font-size:.875rem;font-weight:600;line-height:1.25rem;--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1));a:not(.gap){border-radius:.5rem;display:block;--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity,1));padding-bottom:.25rem;padding-left:.75rem;padding-right:.75rem;padding-top:.25rem}a:not(.gap){&:hover{--tw-bg-opacity:1;background-color:rgb(209 213 219/var(--tw-bg-opacity,1))}&:not([href]){cursor:default;--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity,1))}&.current{--tw-bg-opacity:1;background-color:rgb(156 163 175/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}}label{border-radius:.5rem;display:inline-block;white-space:nowrap;--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity,1));padding-bottom:.125rem;padding-left:.75rem;padding-right:.75rem;padding-top:.125rem}label{input{border-radius:.375rem;border-style:none;--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}}}.hover\:rotate-1:hover{--tw-rotate:1deg}.hover\:rotate-1:hover,.hover\:scale-105:hover{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:scale-105:hover{--tw-scale-x:1.05;--tw-scale-y:1.05}.hover\:scale-110:hover{--tw-scale-x:1.1;--tw-scale-y:1.1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:bg-blue-700:hover{--tw-bg-opacity:1;background-color:rgb(29 78 216/var(--tw-bg-opacity,1))}.hover\:bg-gray-100:hover{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.hover\:bg-gray-200:hover{--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity,1))}.hover\:bg-gray-400:hover{--tw-bg-opacity:1;background-color:rgb(156 163 175/var(--tw-bg-opacity,1))}.hover\:bg-gray-50:hover{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.hover\:bg-green-700:hover{--tw-bg-opacity:1;background-color:rgb(21 128 61/var(--tw-bg-opacity,1))}.hover\:bg-red-50:hover{--tw-bg-opacity:1;background-color:rgb(254 242 242/var(--tw-bg-opacity,1))}.hover\:bg-red-700:hover{--tw-bg-opacity:1;background-color:rgb(185 28 28/var(--tw-bg-opacity,1))}.hover\:text-blue-500:hover{--tw-text-opacity:1;color:rgb(59 130 246/var(--tw-text-opacity,1))}.hover\:text-gray-700:hover{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.hover\:text-gray-900:hover{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}.hover\:text-red-500:hover{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.hover\:underline:hover{text-decoration-line:underline}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\:ring-blue-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity,1))}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px}@media (min-width:640px){.sm\:inline-block{display:inline-block}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}}@media (min-width:768px){.md\:col-span-1{grid-column:span 1/span 1}.md\:col-span-2{grid-column:span 2/span 2}.md\:ml-10{margin-left:2.5rem}.md\:mr-4{margin-right:1rem}.md\:mt-0{margin-top:0}.md\:flex{display:flex}.md\:hidden{display:none}.md\:w-1\/3{width:33.333333%}.md\:w-2\/3{width:66.666667%}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:items-center{align-items:center}.md\:space-x-8>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(2rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(2rem*var(--tw-space-x-reverse))}}@media (min-width:1024px){.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:px-8{padding-left:2rem;padding-right:2rem}}
\ No newline at end of file
diff --git a/app/assets/stylesheets/application.tailwind.css b/app/assets/stylesheets/application.tailwind.css
index 753ccf6..16498c4 100644
--- a/app/assets/stylesheets/application.tailwind.css
+++ b/app/assets/stylesheets/application.tailwind.css
@@ -26,7 +26,7 @@
 .delivered{
   @apply bg-yellow-100 text-yellow-800;
 }
-.cancelled{
+.canceled{
   @apply bg-red-100 text-red-800;
 }
 .pagy {
diff --git a/app/controllers/admin/orders_controller.rb b/app/controllers/admin/orders_controller.rb
new file mode 100644
index 0000000..e863633
--- /dev/null
+++ b/app/controllers/admin/orders_controller.rb
@@ -0,0 +1,68 @@
+class Admin::OrdersController < ApplicationController
+  before_action :logged_in_user?
+  before_action :authorize_admin
+  before_action :find_order, only: %i(update destroy)
+
+  def index
+    @pagy, @orders = pagy Order
+                     .includes(:order_items)
+                     .includes(:products)
+                     .includes(:user)
+                     .not_draft,
+                          limit: Settings.pagy_items
+    @orders = @orders.by_date(params[:date]).by_status(params[:status])
+  end
+
+  def update
+    if check_valid_status_update == false
+      flash[:danger] = t "order.update_fail"
+      redirect_to admin_orders_path
+      return
+    end
+    if @order.update edit_order_params
+      flash[:success] = t "order.update_success"
+    else
+      flash[:danger] = t "order.update_fail"
+    end
+    redirect_to admin_orders_path
+  end
+
+  def destroy
+    if @order.destroy
+      flash[:success] = t "order.delete_success"
+    else
+      flash[:danger] = t "order.delete_fail"
+    end
+    redirect_to admin_orders_path
+  end
+
+  private
+  def find_order
+    @order = Order.find_by id: params[:id]
+    return if @order
+
+    flash[:danger] = t "order.not_found"
+    redirect_to admin_orders_path
+  end
+
+  def edit_order_params
+    params.require(:order).permit Order::ORDER_UPDATE_PARAMS
+  end
+
+  def authorize_admin
+    return if current_user.admin?
+
+    flash[:danger] = t "user.permission_denied"
+    redirect_to root_path
+  end
+
+  def check_valid_status_update
+    status_param = edit_order_params[:status]
+    if Order::BLOCKED_STATUS[status_param.to_sym] == @order.status.to_sym
+      return false
+    end
+    return false if Order.statuses[@order.status] > Order.statuses[status_param]
+
+    true
+  end
+end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 41cb847..f0ae474 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -9,4 +9,11 @@ def set_locale
   def default_url_options
     {locale: I18n.locale}
   end
+
+  def logged_in_user?
+    return if logged_in?
+
+    flash[:danger] = t "user.please_login"
+    redirect_to login_path
+  end
 end
diff --git a/app/controllers/orders_controller.rb b/app/controllers/orders_controller.rb
index 293cc50..ba3e3b0 100644
--- a/app/controllers/orders_controller.rb
+++ b/app/controllers/orders_controller.rb
@@ -69,12 +69,6 @@ def view_history
     @orders = @orders.by_status(params[:status]) if params[:status].present?
   end
   private
-  def logged_in_user?
-    return if logged_in?
-
-    flash[:danger] = t "user.please_login"
-    redirect_to login_path
-  end
 
   def correct_user
     return if current_user.id == params[:user_id].to_i
diff --git a/app/javascript/application.js b/app/javascript/application.js
index c8d8295..75c40d0 100644
--- a/app/javascript/application.js
+++ b/app/javascript/application.js
@@ -3,4 +3,5 @@ import 'controllers'
 import 'custom/main'
 import 'custom/add_to_cart'
 import 'custom/order_modal'
+import 'custom/manage_admin_order'
 import '@fontawesome/fontawesome-free'
diff --git a/app/javascript/custom/manage_admin_order.js b/app/javascript/custom/manage_admin_order.js
new file mode 100644
index 0000000..a0c70df
--- /dev/null
+++ b/app/javascript/custom/manage_admin_order.js
@@ -0,0 +1,39 @@
+window.openEditOrderModal = function(orderId) {
+  const modal = document.getElementById(`editOrderModal${orderId}`);
+  if (modal) {
+    modal.classList.remove('hidden');
+    modal.classList.add('flex');
+  }
+};
+
+window.closeEditOrderModal = function(orderId) {
+  const modal = document.getElementById(`editOrderModal${orderId}`);
+  if (modal) {
+    modal.classList.add('hidden');
+    modal.classList.remove('flex');
+  }
+};
+
+window.openDeleteOrderModal = function(orderId) {
+  const modal = document.getElementById(`deleteOrderModal${orderId}`);
+  if (modal) {
+    modal.classList.remove('hidden');
+    modal.classList.add('flex');
+  }
+};
+
+window.closeDeleteOrderModal = function(orderId) {
+  const modal = document.getElementById(`deleteOrderModal${orderId}`);
+  if (modal) {
+    modal.classList.add('hidden');
+    modal.classList.remove('flex');
+  }
+};
+
+document.addEventListener('turbo:submit-end', function(event) {
+  const form = event.target;
+  if (form.dataset.remote === 'true' && event.detail.success) {
+    const orderId = form.dataset.orderId;
+    window.closeEditOrderModal(orderId);
+  }
+});
diff --git a/app/models/order.rb b/app/models/order.rb
index ec6b213..07a046a 100644
--- a/app/models/order.rb
+++ b/app/models/order.rb
@@ -1,11 +1,15 @@
 class Order < ApplicationRecord
   ORDER_PARAMS = %i(shipping_address phone_number).freeze
+  ORDER_UPDATE_PARAMS = %i(status).freeze
+  BLOCKED_STATUS = {
+    canceled: :delivered
+  }.freeze
   enum status: {
     draft: -1,
     pending: 0,
     confirmed: 1,
     delivered: 2,
-    cancelled: 3
+    canceled: 3
   }, _prefix: true
 
   validates :status, presence: true,
@@ -24,7 +28,12 @@ class Order < ApplicationRecord
   scope :by_user_id, ->(user_id){where user_id:}
   scope :not_draft, ->{where.not(status: :draft)}
   scope :order_by_created_at, ->{order created_at: :desc}
-  scope :by_status, ->(status){where status:}
+  scope :by_status, lambda {|status|
+    where(status:) if status.present?
+  }
+  scope :by_date, lambda {|date|
+    where created_at: date.to_date.all_day if date.present?
+  }
 
   def calculate_total_price
     order_items.sum do |order_item|
diff --git a/app/views/admin/orders/_delete_order_modal.html.erb b/app/views/admin/orders/_delete_order_modal.html.erb
new file mode 100644
index 0000000..370692e
--- /dev/null
+++ b/app/views/admin/orders/_delete_order_modal.html.erb
@@ -0,0 +1,26 @@
+<div id="deleteOrderModal<%= order.id %>" class="fixed inset-0 z-50 hidden items-center justify-center bg-black bg-opacity-50">
+  <div class="bg-white rounded-lg w-full max-w-md mx-4 p-6">
+    <div class="flex justify-between items-center border-b pb-4 mb-4">
+      <h2 class="text-xl font-bold text-red-600"><%= t "delete_confirm_title" %></h2>
+      <button onclick="closeDeleteOrderModal('<%= order.id %>')" class="text-gray-500 hover:text-gray-700">
+        <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
+          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
+        </svg>
+      </button>
+    </div>
+
+    <p class="text-gray-700 mb-4"><%= t "delete_confirm_message" %></p>
+
+    <div class="flex justify-end space-x-2">
+      <button onclick="closeDeleteOrderModal('<%= order.id %>')" class="px-4 py-2 bg-gray-300 text-gray-700 rounded-md hover:bg-gray-400">
+        <%= t "cancel" %>
+      </button>
+
+      <%= link_to admin_order_path(order),
+            data: { turbo_method: :delete },
+            class: "px-4 py-2 bg-red-600 text-white rounded-md hover:bg-red-700" do %>
+        <%= t "confirm" %>
+      <% end %>
+    </div>
+  </div>
+</div>
diff --git a/app/views/admin/orders/_edit_order_modal.html.erb b/app/views/admin/orders/_edit_order_modal.html.erb
new file mode 100644
index 0000000..745cfac
--- /dev/null
+++ b/app/views/admin/orders/_edit_order_modal.html.erb
@@ -0,0 +1,24 @@
+<div id="editOrderModal<%= order.id %>" class="fixed inset-0 z-50 hidden items-center justify-center bg-black bg-opacity-50">
+  <div class="bg-white rounded-lg w-full max-w-md mx-4 p-6">
+    <div class="flex justify-between items-center border-b pb-4 mb-4">
+      <h2 class="text-xl font-bold"><%= t "order.update_status" %></h2>
+      <button type="button" onclick="this.closest('.fixed').classList.add('hidden'); this.closest('.fixed').classList.remove('flex');"
+        class="text-gray-500 hover:text-gray-700">
+        <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
+          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
+        </svg>
+      </button>
+    </div>
+
+    <%= form_with model: order, url: admin_order_path(order), method: :patch, data: { turbo: false } do |f| %>
+      <div class="mb-4">
+        <label for="status" class="block text-sm font-medium text-gray-700"><%= t "order.status.name" %></label>
+        <%= f.select :status, Order.statuses.keys.reject { |k| k == 'draft' }.map { |k| [t("order.status.#{k}"), k] }, { selected: order.status }, class: "w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" %>
+      </div>
+
+      <div class="flex justify-end mt-4">
+        <%= f.submit t("update"), class: "px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700" %>
+      </div>
+    <% end %>
+  </div>
+</div>
diff --git a/app/views/admin/orders/_order_item.html.erb b/app/views/admin/orders/_order_item.html.erb
new file mode 100644
index 0000000..5c67881
--- /dev/null
+++ b/app/views/admin/orders/_order_item.html.erb
@@ -0,0 +1,48 @@
+<tr>
+  <td class="px-6 py-4 whitespace-nowrap">
+    <div class="text-sm font-medium text-gray-900">ORDER#<%= order.id %></div>
+  </td>
+  <td class="px-6 py-4 whitespace-nowrap">
+    <div class="flex items-center">
+      <div class="ml-4">
+        <div class="text-sm font-medium text-gray-900"><%= order.user.name %></div>
+        <div class="text-sm text-gray-500"><%= order.user.email %></div>
+      </div>
+    </div>
+  </td>
+  <td class="px-6 py-4 whitespace-nowrap">
+    <div class="text-sm text-gray-900"><%= l order.created_at, format: :long %></div>
+  </td>
+  <td class="px-6 py-4 whitespace-nowrap">
+    <div class="text-sm text-gray-900"><%= number_to_currency price_in(order.total_price) %></div>
+  </td>
+  <td class="px-6 py-4 whitespace-nowrap">
+    <span class="<%= order.status %> px-2 inline-flex text-xs leading-5 font-semibold rounded-full">
+      <%= t "order.status.#{order.status}" %>
+    </span>
+  <td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
+    <div class="flex justify-end space-x-2">
+      <button onclick="openOrderModal('<%= order.id %>')"
+              class="px-3 py-1 bg-blue-600 text-white rounded-md hover:bg-blue-700"
+              title="<%= t "view" %>">
+        <i class="fa-solid fa-eye"></i>
+      </button>
+
+      <button onclick="openEditOrderModal('<%= order.id %>')"
+              class="px-3 py-1 bg-green-600 text-white rounded-md hover:bg-green-700"
+              title="<%= t "update" %>">
+        <i class="fa-solid fa-pen"></i>
+      </button>
+
+      <button onclick="openDeleteOrderModal('<%= order.id %>')"
+              class="px-3 py-1 bg-red-600 text-white rounded-md hover:bg-red-700"
+              title="<%= t "delete" %>">
+        <i class="fa-solid fa-trash"></i>
+      </button>
+    </div>
+  </td>
+</tr>
+<% @order_items = order.order_items %>
+<%= render "orders/order_detail", order: order %>
+<%= render "delete_order_modal", order: order %>
+<%= render "edit_order_modal", order: order %>
diff --git a/app/views/admin/orders/index.html.erb b/app/views/admin/orders/index.html.erb
new file mode 100644
index 0000000..64f0df0
--- /dev/null
+++ b/app/views/admin/orders/index.html.erb
@@ -0,0 +1,80 @@
+<div class="container mx-auto px-4 py-8">
+  <div class="flex justify-between items-center mb-6">
+    <h1 class="text-2xl font-bold"><%= t "order.manage_orders" %></h1>
+
+    <div class="flex space-x-2">
+      <%= link_to new_admin_order_path, class: "px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 flex items-center" do %>
+        <i class="fa-solid fa-plus mr-2"></i>
+        <%= t "order.new_order" %>
+      <% end %>
+    </div>
+  </div>
+
+  <%= form_with url: admin_orders_path, method: :get, local: true do %>
+    <div class="bg-white rounded-lg shadow-md p-6 mb-6">
+      <div class="grid grid-cols-1 md:grid-cols-4 gap-4">
+        <div>
+          <label for="status-filter" class="block text-sm font-medium text-gray-700 mb-1">
+            <%= t "order.status.name" %>
+          </label>
+          <%= select_tag :status,
+                options_for_select(Order.statuses.reject { |k, _| k == "draft" }
+                  .map { |k, v| [t("order.status.#{k}"), k] }, params[:status]),
+                prompt: t("order.status.name"),
+                class: "w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" %>
+        </div>
+
+        <div>
+          <label for="date-filter" class="block text-sm font-medium text-gray-700 mb-1">
+            <%= t "order.order_date" %>
+          </label>
+          <%= date_field_tag :date, params[:date],
+                class: "w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" %>
+        </div>
+      </div>
+
+      <div class="flex justify-end mt-4">
+        <%= submit_tag t("order.apply_filters"),
+              class: "px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700" %>
+      </div>
+    </div>
+  <% end %>
+
+  <div class="bg-white rounded-lg shadow-md overflow-hidden">
+    <div class="overflow-x-auto">
+      <table class="min-w-full divide-y divide-gray-200">
+        <thead class="bg-gray-50">
+          <tr>
+            <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
+              <%= t "activerecord.attributes.order.id" %>
+            </th>
+            <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
+              <%= t "activerecord.attributes.order.user" %>
+            </th>
+            <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
+              <%= t "activerecord.attributes.order.created_at" %>
+            </th>
+            <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
+              <%= t "activerecord.attributes.order.total_price" %>
+            </th>
+            <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
+              <%= t "activerecord.attributes.order.status" %>
+            </th>
+            <th scope="col" class="px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">
+              <%= t "actions" %>
+            </th>
+          </tr>
+        </thead>
+        <tbody class="bg-white divide-y divide-gray-200">
+          <%= render partial: "order_item", collection: @orders, as: :order %>
+        </tbody>
+      </table>
+    </div>
+
+    <div class="bg-white px-4 py-3 border-t border-gray-200 sm:px-6">
+      <div class="flex justify-center items-center">
+        <%== pagy_nav @pagy %>
+      </div>
+    </div>
+  </div>
+</div>
diff --git a/app/views/orders/_order_detail.html.erb b/app/views/orders/_order_detail.html.erb
new file mode 100644
index 0000000..047d712
--- /dev/null
+++ b/app/views/orders/_order_detail.html.erb
@@ -0,0 +1,55 @@
+<div id="orderModal<%= order.id %>" class="fixed inset-0 z-50 hidden items-center justify-center bg-black bg-opacity-50">
+  <div class="bg-white rounded-lg w-full max-w-2xl mx-4 max-h-[90vh] overflow-y-auto">
+    <div class="p-6">
+      <div class="flex justify-between items-center border-b pb-4 mb-4">
+        <h2 class="text-xl font-bold"><%= t "order.details" %></h2>
+        <%= link_to "#",
+              onclick: "closeOrderModal('#{order.id}'); return false;",
+              class: "text-gray-500 hover:text-gray-700" do %>
+          <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
+            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
+          </svg>
+        <% end %>
+      </div>
+
+      <div class="mb-4">
+        <div class="space-y-3">
+          <div class="flex items-center">
+            <span class="w-32 text-gray-500 font-medium"><%= t "order.number" %>:</span>
+            <span class="text-gray-700">ORDER#<%= order.id %></span>
+          </div>
+          <div class="flex items-center">
+            <span class="w-32 text-gray-500 font-medium"><%= t "order.order_date" %>:</span>
+            <span class="text-gray-700"><%= l order.created_at, format: :long %></span>
+          </div>
+          <div class="flex items-center">
+            <span class="w-32 text-gray-500 font-medium"><%= t "order.detail_info.address" %>:</span>
+            <span class="text-gray-700"><%= order.shipping_address %></span>
+          </div>
+          <div class="flex items-center">
+            <span class="w-32 text-gray-500 font-medium"><%= t "order.detail_info.phone" %>:</span>
+            <span class="text-gray-700"><%= order.phone_number %></span>
+          </div>
+          <div class="flex items-center">
+            <span class="w-32 text-gray-500 font-medium"><%= t "order.status.name" %>:</span>
+            <span class="<%= order.status %> px-2.5 py-1 rounded-full text-xs font-medium">
+              <%= t "order.status.#{order.status}" %>
+            </span>
+          </div>
+        </div>
+      </div>
+
+      <div class="space-y-2 mb-4">
+        <h3 class="font-semibold border-b pb-2"><%= t "product.name" %></h3>
+        <ul class="divide-y divide-gray-200">
+          <%= render partial: "orders/checkout_product_item", collection: order.products, as: :product %>
+        </ul>
+      </div>
+
+      <div class="border-t pt-4 flex justify-between">
+        <p class="font-medium"><%= t "order.total" %>:</p>
+        <p class="text-xl font-bold"><%= number_to_currency price_in(order.total_price) %></p>
+      </div>
+    </div>
+  </div>
+</div>
diff --git a/app/views/orders/_product_history_item.html.erb b/app/views/orders/_product_history_item.html.erb
index 3fe963e..d06591c 100644
--- a/app/views/orders/_product_history_item.html.erb
+++ b/app/views/orders/_product_history_item.html.erb
@@ -45,59 +45,4 @@
     </div>
   </div>
 </div>
-
-<div id="orderModal<%= order.id %>" class="fixed inset-0 z-50 hidden items-center justify-center bg-black bg-opacity-50">
-  <div class="bg-white rounded-lg w-full max-w-2xl mx-4 max-h-[90vh] overflow-y-auto">
-    <div class="p-6">
-      <div class="flex justify-between items-center border-b pb-4 mb-4">
-        <h2 class="text-xl font-bold"><%= t "order.details" %></h2>
-        <%= link_to "#",
-              onclick: "closeOrderModal('#{order.id}'); return false;",
-              class: "text-gray-500 hover:text-gray-700" do %>
-          <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
-            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
-          </svg>
-        <% end %>
-      </div>
-
-      <div class="mb-4">
-        <div class="space-y-3">
-          <div class="flex items-center">
-            <span class="w-32 text-gray-500 font-medium"><%= t "order.number" %>:</span>
-            <span class="text-gray-700">ORDER#<%= order.id %></span>
-          </div>
-          <div class="flex items-center">
-            <span class="w-32 text-gray-500 font-medium"><%= t "order.order_date" %>:</span>
-            <span class="text-gray-700"><%= l order.created_at, format: :long %></span>
-          </div>
-          <div class="flex items-center">
-            <span class="w-32 text-gray-500 font-medium"><%= t "order.detail_info.address" %>:</span>
-            <span class="text-gray-700"><%= order.shipping_address %></span>
-          </div>
-          <div class="flex items-center">
-            <span class="w-32 text-gray-500 font-medium"><%= t "order.detail_info.phone" %>:</span>
-            <span class="text-gray-700"><%= order.phone_number %></span>
-          </div>
-          <div class="flex items-center">
-            <span class="w-32 text-gray-500 font-medium"><%= t "order.status.name" %>:</span>
-            <span class="<%= order.status %> px-2.5 py-1 rounded-full text-xs font-medium">
-              <%= t "order.status.#{order.status}" %>
-            </span>
-          </div>
-        </div>
-      </div>
-
-      <div class="space-y-2 mb-4">
-        <h3 class="font-semibold border-b pb-2"><%= t "product.name" %></h3>
-        <ul class="divide-y divide-gray-200">
-          <%= render partial: "checkout_product_item", collection: order.products, as: :product %>
-        </ul>
-      </div>
-
-      <div class="border-t pt-4 flex justify-between">
-        <p class="font-medium"><%= t "order.total" %>:</p>
-        <p class="text-xl font-bold"><%= number_to_currency price_in(order.total_price) %></p>
-      </div>
-    </div>
-  </div>
-</div>
+<%= render "order_detail", order: order %>
diff --git a/app/views/orders/edit.html.erb b/app/views/orders/edit.html.erb
index f39b531..adfa8b8 100644
--- a/app/views/orders/edit.html.erb
+++ b/app/views/orders/edit.html.erb
@@ -32,7 +32,7 @@
     </div>
   </div>
 
-  <%= form_with model: @order, url: checkout_update_path, method: :patch, scope: :order, local: true, class: "space-y-8" do |form| %>
+  <%= form_with model: @order, url: checkout_update_path(user_id: @order.user.id), method: :patch, scope: :order, local: true, class: "space-y-8" do |form| %>
     <div class="grid grid-cols-1 md:grid-cols-3 gap-8">
       <div class="md:col-span-2 space-y-6">
         <div class="bg-white rounded-lg shadow-md overflow-hidden p-6">
diff --git a/app/views/orders/show_cart.html.erb b/app/views/orders/show_cart.html.erb
index a6e6131..5d446e8 100644
--- a/app/views/orders/show_cart.html.erb
+++ b/app/views/orders/show_cart.html.erb
@@ -22,7 +22,7 @@
 
         <div class="mt-6">
           <% if logged_in? %>
-            <%= link_to checkout_path(@order), class: "w-full flex justify-center items-center px-6 py-3 border border-transparent rounded-md shadow-sm text-base font-medium text-white bg-blue-600 hover:bg-blue-700" do %>
+            <%= link_to checkout_path(@order, user_id: @order.user.id), class: "w-full flex justify-center items-center px-6 py-3 border border-transparent rounded-md shadow-sm text-base font-medium text-white bg-blue-600 hover:bg-blue-700" do %>
               <%= t "order.checkout" %>
             <% end %>
           <% else %>
diff --git a/config/importmap.rb b/config/importmap.rb
index b543833..1556b70 100644
--- a/config/importmap.rb
+++ b/config/importmap.rb
@@ -8,4 +8,5 @@
 pin "custom/main", preload: true
 pin "custom/add_to_cart", preload: true
 pin "custom/order_modal", preload: true
+pin "custom/manage_admin_order", preload: true
 pin "@fontawesome/fontawesome-free", to: "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/js/all.min.js"
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 69617c3..69bb92e 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -17,6 +17,11 @@ en:
       order:
         shipping_address: "Shipping Address"
         phone_number: "Phone Number"
+        id: "Order ID"
+        user: "User"
+        created_at: "Order Date"
+        status: "Status"
+        total_price: "Total Price"
     errors:
       models:
         order:
@@ -88,6 +93,13 @@ en:
     details: "Order details"
     reorder: "Reorder"
     number: "Order number"
+    manage_orders: "Manage orders"
+    apply_filters: "Apply filters"
+    update_status: "Update status"
+    update_success: "Update order status successfully"
+    update_fail: "Cannot update order status to a lower status than current status"
+    delete_success: "Delete order successfully"
+    delete_fail: "Delete order failed"
   order_item:
     remove_fail: "Failed to remove product from cart, please try again"
     update_fail: "Invalid product quantity, please try again"
@@ -99,3 +111,11 @@ en:
     permission_denied: "Permission denied, you are not allowed to access this page"
   all: "All"
   continue_order: "Continue shopping"
+  view: "View"
+  update: "Update"
+  delete: "Delete"
+  actions: "Actions"
+  delete_confirm_title: "Delete confirmation"
+  delete_confirm_message: "Are you sure you want to delete this item?"
+  cancel: "Cancel"
+  confirm: "Confirm"
diff --git a/config/locales/vi.yml b/config/locales/vi.yml
index 9f341de..1b94476 100644
--- a/config/locales/vi.yml
+++ b/config/locales/vi.yml
@@ -17,6 +17,11 @@ vi:
       order:
         shipping_address: "Địa chỉ"
         phone_number: "Số điện thoại"
+        id: "Mã đơn hàng"
+        user: "Người đặt"
+        created_at: "Ngày đặt hàng"
+        status: "Trạng thái"
+        total_price: "Tổng cộng"
     errors:
       models:
         order:
@@ -90,6 +95,14 @@ vi:
     reorder: "Đặt lại"
     number: "Mã đơn hàng"
     cancel: "Hủy đơn hàng"
+    manage_orders: "Quản lý đơn hàng"
+    new_order: "Đơn hàng mới"
+    apply_filters: "Áp dụng bộ lọc"
+    update_status: "Cập nhật trạng thái"
+    update_success: "Cập nhật trạng thái đơn hàng thành công"
+    update_fail: "Cập nhật trạng thái đơn hàng thất bại vì trạng thái cập nhật không được thấp hơn trạng thái hiện tại"
+    delete_success: "Xóa đơn hàng thành công"
+    delete_fail: "Xóa đơn hàng thất bại"
   order_item:
     remove_fail: "Xóa sản phẩm khỏi giỏ hàng thất bại, hãy thử lại"
     update_fail: "Số lượng sản phẩm không hợp lệ, hãy thử lại"
@@ -102,3 +115,11 @@ vi:
   all: "Tất cả"
   or: "hoặc"
   continue_order: "Tiếp tục mua hàng"
+  view: "Xem"
+  update: "Cập nhật"
+  delete: "Xóa"
+  actions: "Hành động"
+  delete_confirm_title: "Xác nhận xóa"
+  delete_confirm_message: "Bạn có chắc chắn muốn xóa?"
+  cancel: "Hủy"
+  confirm: "Xác nhận"
diff --git a/config/routes.rb b/config/routes.rb
index 29ab325..442221a 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -17,5 +17,9 @@
     resources :order_items, only: %i(update destroy)
     patch "/guest_cart_items/:product_id", to: "order_items#update_guest_cart_item", as: "update_guest_cart_item"
     delete "/guest_cart_items/:product_id", to: "order_items#remove_guest_cart_item", as: "remove_guest_cart_item"
+
+    namespace :admin do
+      resources :orders
+    end
   end
 end


Reviews:
body: cmt
state: COMMENTED
author_association: NONE
submitted_at: 2025-03-28T06:07:36Z
body: merged
state: COMMENTED
author_association: NONE
submitted_at: 2025-03-28T07:13:08Z

Review comments:
diff_hunk: @@ -0,0 +1,69 @@
+class Admin::OrdersController < ApplicationController
+  before_action :logged_in_user?
+  before_action :authorize_admin
+  before_action :find_order, only: %i(update destroy)
+
+  def index
+    @pagy, @orders = pagy Order.all
path: app/controllers/admin/orders_controller.rb
body: bỏ all đi em 
created_at: 2025-03-28T06:06:07Z
author_association: NONE
diff_hunk: @@ -0,0 +1,69 @@
+class Admin::OrdersController < ApplicationController
+  before_action :logged_in_user?
+  before_action :authorize_admin
+  before_action :find_order, only: %i(update destroy)
+
+  def index
+    @pagy, @orders = pagy Order.all
+                               .includes(:order_items)
+                               .includes(:products)
+                               .includes(:user)
+                               .not_draft,
+                          limit: Settings.pagy_items
+    @orders = @orders.by_status params[:status] if params[:status].present?
+    @orders = @orders.by_date params[:date] if params[:date].present?
path: app/controllers/admin/orders_controller.rb
body: ```suggestion
    @orders = @orders.by_date(params[:date]).by_status params[:status]
```
created_at: 2025-03-28T06:06:51Z
author_association: NONE

PR comments:
user: login: khanhdx-0573
created_at: 2025-03-28T04:18:06Z
body: ready
author_association: CONTRIBUTOR
user: login: khanhdx-0573
created_at: 2025-03-28T06:25:28Z
body: ready
author_association: CONTRIBUTOR