This commit is contained in:
Viet An
2026-04-13 21:58:04 +07:00
parent 631527225e
commit 0011c3ced9
25 changed files with 1956 additions and 686 deletions

View File

@@ -126,12 +126,6 @@ $size: (
// 4. CUSTOM CLASSES
// ==========================================
.header-logo {
background: url('/logo_dev.png') no-repeat center center;
background-size: 40px;
width: 50px;
}
// Block Layout
.blockdiv {
max-width: 1900px !important;

View File

@@ -3,4 +3,14 @@
.card {
--bulma-card-shadow: none;
border: 1px solid $grey-lighter;
}
}
:root {
// somehow this value keeps picking dark mode values despite [data-theme]="light"
--bulma-hr-background-color: var(--bulma-grey-90);
}
// might break lots of stuff
// .skeleton-block:not(:last-child), .media:not(:last-child), .level:not(:last-child), .fixed-grid:not(:last-child), .grid:not(:last-child), .tabs:not(:last-child), .pagination:not(:last-child), .message:not(:last-child), .card:not(:last-child), .breadcrumb:not(:last-child), .field:not(:last-child), .file:not(:last-child), .title:not(:last-child), .subtitle:not(:last-child), .tags:not(:last-child), .table:not(:last-child), .table-container:not(:last-child), .progress:not(:last-child), .notification:not(:last-child), .content:not(:last-child), .buttons:not(:last-child), .box:not(:last-child), .block:not(:last-child) {
// margin-bottom: inherit;
// }

View File

@@ -59,49 +59,20 @@
border-radius: calc(infinity * 1px);
}
$base: 0.25rem;
@function spacing($step) {
@return $step * $base;
.static {
position: static;
}
$spacing-types: (
"p": "padding",
"m": "margin",
);
$spacing-variants: (
"": (""),
"x": ("-left", "-right"),
"y": ("-top", "-bottom"),
"t": ("-top"),
"b": ("-bottom"),
"l": ("-left"),
"r": ("-right"),
);
@each $type-prefix, $type in $spacing-types {
@each $dir-suffix, $sides in $spacing-variants {
@for $i from 0 through 48 {
// Whole step: p-0, p-1, p-2 ...
.#{$type-prefix}#{$dir-suffix}-#{$i} {
@each $side in $sides {
#{$type}#{$side}: spacing($i);
}
}
// Half step: p-0\.5, p-1\.5, p-2\.5 ...
// Stop at 47.5 — 48.5 would exceed the scale
@if $i < 48 {
.#{$type-prefix}#{$dir-suffix}-#{$i}\.5 {
@each $side in $sides {
#{$type}#{$side}: spacing($i + 0.5);
}
}
}
}
}
.fixed {
position: fixed;
}
.absolute {
position: absolute;
}
.relative {
position: relative;
}
.sticky {
position: sticky;
}
// ─── CSS custom properties ─────────────────────────────────────────────────
@@ -199,7 +170,7 @@ $containers: (
// These are identical in value across w-, h-, and size-
$shared-keywords: (
"auto": auto,
"px": 1px,
"px": 1px,
"full": 100%,
"min": min-content,
"max": max-content,
@@ -233,5 +204,5 @@ $viewport-keywords: (
}
}
.w-screen { width: 100vw; }
.w-screen { width: 100vw; }
.h-screen { height: 100vh; }

View File

@@ -35,7 +35,7 @@
<template v-for="(v, i) in leftmenu" :key="i" :id="v.code">
<a class="navbar-item rounded-lg is-clipped p-0" v-if="!v.submenu" @click="changeTab(v)">
<span :class="[
'px-3 py-1.5 fs-14 font-medium',
'px-3 py-2 fs-14 font-medium',
currentTab.code === v.code ? 'has-text-primary-50 has-background-primary-95' : 'has-text-grey-30'
]">
{{ v[lang] }}

View File

@@ -12,7 +12,11 @@
</div>
</div>
<span class="icon is-left">
<SvgIcon v-bind="{name: 'calendar.svg', type: 'gray', size: 21}"></SvgIcon>
<Icon
name="material-symbols:calendar-today-outline-rounded"
:size="21"
class="has-text-grey"
/>
</span>
</div>
</template>

View File

@@ -1,6 +1,6 @@
<template>
<div class="p-2" style="width: 300px">
<div class="field is-grouped mb-4 border-bottom">
<div class="field is-grouped">
<div class="control pl-2">
<a class="mr-1" @click="previousYear()">
<SvgIcon v-bind="{name: 'doubleleft.svg', type: 'gray', size: 18}"></SvgIcon>
@@ -10,8 +10,8 @@
</a>
</div>
<div class="control is-expanded has-text-centered">
<a class="fsb-16 mr-2" @click="type='months'" v-if="type==='days'">{{`T${month}`}}</a>
<a class="fsb-16" @click="type='years'">{{ caption || year }}</a>
<a class="font-bold mr-2" @click="type='months'" v-if="type==='days'">{{`T${month}`}}</a>
<a class="font-bold" @click="type='years'">{{ caption || year }}</a>
</div>
<div class="control pr-2">
<a class="mr-1" @click="nextMonth()" v-if="type==='days'">
@@ -22,36 +22,41 @@
</a>
</div>
</div>
<hr class="mt-0 mb-5" />
<div v-if="type==='days'">
<div class="columns is-mobile mx-0 mb-3">
<div class="column p-0 has-text-grey-light-dark is-flex is-justify-content-center is-align-items-center" style="height: 32px;" v-for="(m,h) in dateOfWeek" :key="h">
<div
v-for="(m, h) in dateOfWeek"
:key="h"
class="fs-14 column p-0 has-text-grey is-flex is-justify-content-center is-align-items-center"
>
{{ m.text }}
</div>
</div>
<div :class="`columns is-mobile mx-0 mb-1 ${i===weeks.length-1? 'mb-1' : ''}`" v-for="(v,i) in weeks" :key="i">
<div class="column p-0 is-flex is-justify-content-center is-align-items-center" style="width: 40px; height: 32px" v-for="(m,h) in v.dates" :key="h">
<span class="fs-14 has-text-grey-light" v-if="m.disable">
<span class="fs-13 has-text-grey-80" v-if="m.disable">
{{m.dayPrint}}
</span>
<a class="fs-14" @click="choose(m)" v-else>
<span class="fs-13 is-clickable" @click="choose(m)" v-else>
<span
style="width: 25px; height: 25px; border-radius: 4px"
style="width: 25px; height: 25px"
:class="[
'p-1 is-flex is-justify-content-center is-align-items-center',
'p-1 rounded-md is-flex is-justify-content-center is-align-items-center',
{
'has-background-primary has-text-white': m.date === curdate,
'has-background-light has-text-white': m.date === today,
'has-text-grey-light': m.currentMonth !== m.monthCondition
'has-background-primary-50 has-text-white': m.date === curdate,
'has-background-success-50 has-text-white': m.date === today,
'has-text-grey-70': m.currentMonth !== m.monthCondition
}
]"
>
{{ m.dayPrint }}
</span>
</a>
</span>
</div>
</div>
<div class="border-bottom"></div>
<div class="mt-2">
<hr class="my-1" />
<div class="mt-2 fs-14">
<span class="ml-2">Hôm nay: </span>
<a class="has-text-primary" @click="chooseToday()">{{ $dayjs(today).format('DD/MM/YYYY') }}</a>
</div>
@@ -112,6 +117,7 @@
weeks.value.map(v=>{
v.dates = dates.filter(x=>x.week===v.week)
})
console.log('weeks.value', weeks.value)
}
function nextMonth() {
month = month + 1
@@ -177,5 +183,9 @@
watch(() => props.date, (newVal, oldVal) => {
showDate()
})
</script>
</script>
<style scoped>
a {
color: var(--bulma-link-60);
}
</style>

View File

@@ -1,6 +1,6 @@
<template>
<div class="columns is-mobile is-multiline mx-0">
<span class="column has-text-centered is-4 hyperlink fs-14" v-for="v in months" @click="$emit('month', v)">Tháng {{ v }}</span>
<span class="column has-text-centered is-4 is-clickable fs-14" v-for="v in months" @click="$emit('month', v)">Tháng {{ v }}</span>
</div>
</template>
<script>

View File

@@ -2,7 +2,7 @@
<div class="columns is-mobile is-multiline mx-0">
<span
v-for="(v,i) in years"
class="column is-4 has-text-centered hyperlink fs-14"
class="column is-4 has-text-centered is-clickable fs-14"
:class="i===0 || i===11 ? 'has-text-grey-light' : ''"
@click="$emit('year', v)">{{ v }}</span>
</div>

View File

@@ -1,75 +1,61 @@
<script setup>
const props = defineProps({
id: Number,
code: String,
employee: Number,
employee__name: String,
customer: Number,
customer__name: String,
customer__phone: String,
total: String,
status: Number,
status__name: String,
status__color: String,
payment_status: Number,
payment_status__name: String,
payment_status__color: String,
delivery_status: Number,
delivery_status__name: String,
delivery_status__color: String,
order__products: Array,
create_time: String
order: Object,
selected: Boolean
});
const { $dayjs, $shortenCurrency } = useNuxtApp();
const emit = defineEmits(['selectOrder', 'unselect'])
</script>
<template>
<tr>
<tr
:class="['is-clickable', selected && 'is-selected']"
@click="selected ? emit('unselect') : emit('selectOrder', order.id) "
>
<td>
<div>
<p class="fs-15 font-semibold">{{ code }}</p>
<p class="fs-13 has-text-grey">{{ employee__name }}</p>
<p class="fs-15 font-semibold">{{ order.code }}</p>
<p class="has-text-grey">{{ order.employee__name }}</p>
</div>
</td>
<td>
<div>
<p>{{ customer__name }}</p>
<div class="is-flex is-gap-0.5 is-align-items-center mt-1 fs-13 has-text-grey">
<p>{{ order.customer__name }}</p>
<div class="is-flex is-gap-0.5 is-align-items-center mt-1 has-text-grey">
<Icon name="material-symbols:call-outline-rounded"
:size="15"
/>
<span class="fs-12">{{ customer__phone }}</span>
<span class="fs-12">{{ order.customer__phone }}</span>
</div>
</div>
</td>
<td class="has-text-right">
<div>
<p class="font-semibold">{{ $shortenCurrency(total) }}</p>
<p class="fs-13 has-text-grey">{{ order__products.length }} SP</p>
<p class="fs-14 font-semibold">{{ $shortenCurrency(order.total) }}</p>
<p class="has-text-grey">{{ order.order__products.length }} SP</p>
</div>
</td>
<td class="has-text-centered">
<span :class="[
'tag rounded-full',
`has-background-${status__color}-80 has-text-${status__color}-25`
`has-background-${order.status__color}-80 has-text-${order.status__color}-25`
]">
{{ status__name }}
{{ order.status__name }}
</span>
</td>
<td>
<p :class="`has-text-${payment_status__color}-40`">{{ payment_status__name }}</p>
<p :class="`has-text-${order.payment_status__color}-40`">{{ order.payment_status__name }}</p>
</td>
<td>
<p :class="`has-text-${delivery_status__color}-40`">{{ delivery_status__name }}</p>
<p :class="`has-text-${order.delivery_status__color}-40`">{{ order.delivery_status__name }}</p>
</td>
<td>
<div>
<div class="is-flex is-gap-0.5">
<Icon :size="18" name="material-symbols:calendar-month-outline-rounded" />
<span class="fs-13">{{ $dayjs(create_time).format('L') }}</span>
<span>{{ $dayjs(order.create_time).format('L') }}</span>
</div>
<p class="has-text-grey fs-12">{{ $dayjs(create_time).format('HH:mm') }}</p>
<p class="has-text-grey fs-12">{{ $dayjs(order.create_time).format('HH:mm') }}</p>
</div>
</td>
<td>
@@ -78,6 +64,10 @@ const { $dayjs, $shortenCurrency } = useNuxtApp();
</tr>
</template>
<style scoped>
tr.is-selected {
--bulma-table-row-active-background-color: var(--bulma-primary-95);
color: unset;
}
td {
vertical-align: middle;
--bulma-table-cell-padding: 0.75em;

View File

@@ -1,5 +1,9 @@
<script setup>
import OrderRow from '@/components/orders/OrderRow.vue';
import SelectedOrder from '@/components/orders/SelectedOrder.vue';
import { pull } from 'es-toolkit';
const { $dayjs } = useNuxtApp();
const orders = [
{
@@ -62,7 +66,7 @@ const orders = [
status__color: 'blue',
payment_status: 2,
payment_status__name: 'Một phần',
payment_status__color: 'orange',
payment_status__color: 'yellow',
delivery_status: 2,
delivery_status__name: 'Sẵn sàng',
delivery_status__color: 'blue',
@@ -186,46 +190,408 @@ const orders = [
],
create_time: '2026-04-04T23:21:11.587660+07:00'
},
{
id: 5,
code: 'SO005',
employee: 5,
employee__name: 'Hoàng Văn E',
customer: 7,
customer__name: 'Đỗ Văn G',
customer__phone: '0945781113',
total: '9400000.00',
status: 2,
status__name: 'Đã xác nhận',
status__color: 'blue',
payment_status: 1,
payment_status__name: 'Chưa thanh toán',
payment_status__color: 'red',
delivery_status: 1,
delivery_status__name: 'Chờ xử lý',
delivery_status__color: 'grey',
order__products: [
{
id: 12,
name: 'Kem mắt chống lão hóa',
unit_price: '550000.00',
quantity: 10,
discount: null,
total: '5500000.00'
},
{
id: 13,
name: 'Serum Vitamin C 30ml',
unit_price: '450000.00',
quantity: 8,
discount: 0.05,
total: '3420000.00'
},
{
id: 14,
name: 'Gel rửa mặt làm sạch sâu',
unit_price: '140000.00',
quantity: 5,
discount: 0.15,
total: '595000.00'
},
],
create_time: '2026-04-07T11:21:46.587660+07:00'
},
{
id: 6,
code: 'SO006',
employee: 1,
employee__name: 'Trần Thị B',
customer: 8,
customer__name: 'Bùi Thị H',
customer__phone: '0933184392',
total: '4200000.00',
status: 1,
status__name: 'Nháp',
status__color: 'yellow',
payment_status: 1,
payment_status__name: 'Chưa thanh toán',
payment_status__color: 'red',
delivery_status: 1,
delivery_status__name: 'Chờ xử lý',
delivery_status__color: 'grey',
order__products: [
{
id: 15,
name: 'Toner cân bằng da 200ml',
unit_price: '180000.00',
quantity: 15,
discount: null,
total: '2700000.00'
},
{
id: 16,
name: 'Mặt nạ collagen 10 miếng',
unit_price: '320000.00',
quantity: 5,
discount: 0.05,
total: '1520000.00'
},
],
create_time: '2026-04-07T13:17:36.587660+07:00'
},
{
id: 7,
code: 'SO007',
employee: 5,
employee__name: 'Hoàng Văn E',
customer: 9,
customer__name: 'Ngô Văn I',
customer__phone: '0978335172',
total: '15600000.00',
status: 3,
status__name: 'Đang giao',
status__color: 'orange',
payment_status: 3,
payment_status__name: 'Đã thanh toán',
payment_status__color: 'green',
delivery_status: 2,
delivery_status__name: 'Hoàn thành',
delivery_status__color: 'green',
order__products: [
{
id: 17,
name: 'Kem chống nắng SPF 50+',
unit_price: '280000.00',
quantity: 30,
discount: 0.1,
total: '7560000.00'
},
{
id: 18,
name: 'Phấn nền BB cream',
unit_price: '220000.00',
quantity: 25,
discount: 0.05,
total: '5225000.00'
},
{
id: 19,
name: 'Kem dưỡng ẩm ban đêm',
unit_price: '380000.00',
quantity: 8,
discount: 0.05,
total: '2880000.00'
},
],
create_time: '2026-06-04T09:30:12.587660+07:00'
},
{
id: 8,
code: 'SO008',
employee: 1,
employee__name: 'Trần Thị B',
customer: 11,
customer__name: 'Đinh Thị K',
customer__phone: '0922104853',
total: '7900000.00',
status: 2,
status__name: 'Đã xác nhận',
status__color: 'blue',
payment_status: 2,
payment_status__name: 'Một phần',
payment_status__color: 'yellow',
delivery_status: 2,
delivery_status__name: 'Sẵn sàng',
delivery_status__color: 'blue',
order__products: [
{
id: 20,
name: 'Nước tẩy trang 3 trong 1',
unit_price: '195000.00',
quantity: 20,
discount: 0.05,
total: '3705000.00'
},
{
id: 21,
name: 'Sữa rửa mặt trà xanh 150ml',
unit_price: '150000.00',
quantity: 18,
discount: null,
total: '2700000.00'
},
{
id: 22,
name: 'Dầu gội thảo mộc 500ml',
unit_price: '120000.00',
quantity: 13,
discount: 0.05,
total: '1482000.00'
},
],
create_time: '2026-04-06T16:01:22.587660+07:00'
},
];
const statuses = [
{
id: 1,
name: 'Nháp',
color: 'yellow',
},
{
id: 2,
name: 'Đã xác nhận',
color: 'blue',
},
{
id: 3,
name: 'Đang giao',
color: 'orange',
},
{
id: 4,
name: 'Hoàn thành',
color: 'green',
},
];
const paymentStatuses = [
{
id: 1,
name: 'Chưa thanh toán',
color: 'red',
},
{
id: 2,
name: 'Một phần',
color: 'yellow',
},
{
id: 3,
name: 'Đã thanh toán',
color: 'green',
}
];
const employees = [
{
id: 1,
name: 'Trần Thị B',
},
{
id: 5,
name: 'Hoàng Văn E',
},
]
const input = ref();
const dateRange = ref({
from: null,
to: null,
});
const selectedStatuses = ref([]);
const selectedPaymentStatus = ref();
const selectedEmployee = ref();
const filteredOrders = computed(() => {
const filteredByInput = orders.filter(order => {
if (!input.value) return true;
const values = Object.values(order);
const strValues = values.filter(v => typeof v === 'string');
return strValues.some(str => str.toLowerCase().includes(input.value.toLowerCase()));
});
const filteredByStatuses = filteredByInput.filter(order => {
if (selectedStatuses.value.length === 0) return true;
return selectedStatuses.value.includes(order.status);
});
const filteredByPaymentStatuses = filteredByStatuses.filter(order => {
if (!selectedPaymentStatus.value) return true;
return order.payment_status === selectedPaymentStatus.value;
});
const filteredByEmployees = filteredByPaymentStatuses.filter(order => {
if (!selectedEmployee.value) return true;
return order.employee === selectedEmployee.value;
});
const filteredByDates = filteredByEmployees.filter(order => {
if (!dateRange.value) return true;
const from = $dayjs(dateRange.value.from || 0);
const to = $dayjs(dateRange.value.to || undefined);
const createTime = $dayjs(order.create_time);
return createTime.isSameOrAfter(from) && createTime.isSameOrBefore(to);
})
return filteredByDates;
});
const selectedOrder = ref(null);
watch(filteredOrders, () => {
selectedOrder.value = null;
});
function toggleStatus(id) {
if (selectedStatuses.value.includes(id)) {
selectedStatuses.value = pull(selectedStatuses.value, [id])
} else {
selectedStatuses.value.push(id);
}
}
</script>
<template>
<div>
<div class="card">
<div class="card-content"></div>
</div>
<div class="card">
<div class="card-content p-0">
<p class="p-5 fs-17 font-semibold is-flex is-align-items-center is-gap-1">
<Icon name="material-symbols:list-alt-outline-rounded" :size="22" />
<span>Danh sách đơn hàng ({{ orders.length }})</span>
</p>
<table class="table is-fullwidth is-hoverable fs-14">
<thead>
<tr>
<th>Đơn hàng</th>
<th>Khách hàng</th>
<th class="has-text-right">Tổng tiền</th>
<th class="has-text-centered">Trạng thái</th>
<th>Thanh toán</th>
<th>Giao hàng</th>
<th>Ngày tạo</th>
<th>Thao tác</th>
</tr>
</thead>
<tbody>
<OrderRow
v-for="order in orders"
:key="order.id"
v-bind="order"
<div class="card-content">
<div class="is-flex is-gap-2 is-align-items-center">
<div class="field m-0">
<p class="control has-icons-left">
<input v-model="input" class="input" type="text" placeholder="Tìm kiếm mã đơn, khách hàng..." />
<span class="icon is-small is-left">
<Icon name="material-symbols:search-rounded" :size="24" />
</span>
</p>
</div>
<div class="is-flex is-gap-1 is-align-items-center">
<!-- Date pickers -->
<Datepicker v-bind="{
record: dateRange,
attr: 'from',
maxdate: new Date(),
onDate: (e) => dateRange.from = e
}" />
<span></span>
<Datepicker v-bind="{
record: dateRange,
attr: 'to',
maxdate: new Date(),
onDate: (e) => dateRange.to = e
}" />
</div>
<div class="select">
<select v-model="selectedPaymentStatus">
<option :value="undefined">Phương thức thanh toán</option>
<option
v-for="paymentStatus in paymentStatuses"
:key="paymentStatus.id"
:value="paymentStatus.id"
>
{{ paymentStatus.name }}
</option>
</select>
</div>
<div class="select">
<select v-model="selectedEmployee">
<option :value="undefined">Nhân viên</option>
<option
v-for="employee in employees"
:key="employee.id"
:value="employee.id"
>
{{ employee.name }}
</option>
</select>
</div>
</div>
<div class="is-flex is-gap-1 mt-3">
<button
v-for="status in statuses"
:key="status.id"
:class="[
'tag fs-13 is-rounded',
selectedStatuses.includes(status.id) && `has-background-${status.color}-80`
]"
@click="toggleStatus(status.id)"
>
{{ status.name }}
<Icon
v-if="selectedStatuses.includes(status.id)"
name="material-symbols:check-rounded"
:size="18"
class="ml-1"
/>
</tbody>
</table>
</button>
</div>
</div>
</div>
<div class="fixed-grid has-3-cols">
<div class="grid">
<div :class="['cell', selectedOrder ? 'is-col-span-2' : 'is-col-span-3']">
<div class="card">
<div class="card-content p-0">
<p class="p-5 fs-17 font-semibold is-flex is-align-items-center is-gap-1">
<Icon name="material-symbols:list-alt-outline-rounded" :size="22" />
<span>Danh sách đơn hàng ({{ filteredOrders.length }})</span>
</p>
<table class="table is-fullwidth is-hoverable fs-13">
<thead>
<tr>
<th class="font-semibold">Đơn hàng</th>
<th class="font-semibold">Khách hàng</th>
<th class="font-semibold has-text-right">Tổng tiền</th>
<th class="font-semibold has-text-centered">Trạng thái</th>
<th class="font-semibold">Thanh toán</th>
<th class="font-semibold">Giao hàng</th>
<th class="font-semibold">Ngày tạo</th>
<th class="font-semibold">Thao tác</th>
</tr>
</thead>
<tbody>
<OrderRow
v-for="order in filteredOrders"
:key="order.id"
v-bind="{ order, selected: order.id === selectedOrder?.id }"
@selectOrder="(id) => {
selectedOrder = filteredOrders.find(order => order.id === id);
}"
@unselect="selectedOrder = null"
/>
</tbody>
</table>
</div>
</div>
</div>
<SelectedOrder :order="selectedOrder" @unselect="selectedOrder = null" />
</div>
</div>
</div>
</template>
<style scoped>
th {
font-weight: 600;
}
</style>

View File

@@ -0,0 +1,105 @@
<script setup>
const props = defineProps({
order: Object
});
const { $dayjs, $numtoString } = useNuxtApp();
const emit = defineEmits(['unselect']);
</script>
<template>
<div v-if="order" class="cell relative fs-14">
<div class="card">
<button
@click="emit('unselect')"
class="button is-white rounded-full has-text-grey absolute size-8 is-flex is-justify-content-center is-align-items-center"
style="right: 0.5rem; top: 0.5rem;"
>
<span class="icon">
<Icon name="material-symbols:close-rounded" :size="22" />
</span>
</button>
<div class="card-content">
<div>
<div class="is-flex is-gap-2 is-align-items-center">
<span class="fs-17 font-bold">{{ order.code }}</span>
<span :class="[
'tag rounded-full',
`has-background-${order.status__color}-80 has-text-${order.status__color}-25`
]">
{{ order.status__name }}
</span>
</div>
<div class="is-flex is-gap-0.5 is-flex-direction-column mt-2">
<div class="is-flex is-gap-1 is-align-items-center">
<Icon name="material-symbols:person-outline-rounded" :size="18" />
<p>{{ order.customer__name }}</p>
</div>
<div class="is-flex is-gap-1 is-align-items-center">
<Icon name="material-symbols:call-outline-rounded" :size="18" />
<p>{{ order.customer__phone }}</p>
</div>
<div class="is-flex is-gap-1 is-align-items-center">
<Icon name="material-symbols:calendar-today-outline-rounded" :size="18" />
<p>{{ $dayjs(order.create_time).format('LL') }}</p>
</div>
</div>
<div class="p-4 has-background-primary-95 rounded-lg mt-6">
<p>Tổng giá trị đơn hàng</p>
<p class="font-bold fs-28">{{ $numtoString(order.total, { hasUnit: true }) }}</p>
</div>
</div>
<hr class="m-0" />
<div class="buttons m-0">
<button class="button fs-14 is-flex-grow-1 is-primary">Xác nhận đơn</button>
<button class="button fs-14 is-flex-grow-1">Ghi thanh toán</button>
</div>
<hr class="m-0" />
<div class="tabs is-toggle fs-13">
<ul>
<li class="is-active">
<a>
<span>Chi tiết đơn</span>
</a>
</li>
<li>
<a>
<span>Giao hàng</span>
</a>
</li>
<li>
<a>
<span>Hoá đơn</span>
</a>
</li>
<li>
<a>
<span>Thanh toán</span>
</a>
</li>
<li>
<a>
<span>Lịch sử</span>
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.card-content {
padding: 0; /* 1.5rem */
> div {
padding: var(--bulma-card-content-padding);
}
}
.tabs {
--bulma-tabs-toggle-link-active-background-color: var(--bulma-link-90);
--bulma-tabs-toggle-link-active-border-color: var(--bulma-link-90);
--bulma-tabs-toggle-link-active-color: var(--bulma-link-40);
}
</style>

View File

@@ -296,9 +296,4 @@ function cancelEditDocument() {
</tbody>
</table>
</div>
</template>
<style>
.table th {
background-color: #f5f5f5;
}
</style>
</template>

View File

@@ -1,6 +1,7 @@
<template>
<div
style="min-height: 100vh; background-color: #f9fafb;"
style="min-height: 100vh"
class="has-background-blue-100"
data-theme="light"
lang="vi"
>

View File

@@ -5,12 +5,16 @@ import dayjs from 'dayjs';
import weekday from 'dayjs/plugin/weekday';
import weekOfYear from 'dayjs/plugin/weekOfYear';
import relativeTime from 'dayjs/plugin/relativeTime';
import localizedFormat from 'dayjs/plugin/localizedFormat'
import localizedFormat from 'dayjs/plugin/localizedFormat';
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
import isSameOrAfter from 'dayjs/plugin/isSameOrAfter';
import 'dayjs/locale/vi';
dayjs.extend(weekday);
dayjs.extend(weekOfYear);
dayjs.extend(relativeTime);
dayjs.extend(localizedFormat);
dayjs.extend(isSameOrBefore);
dayjs.extend(isSameOrAfter);
dayjs.locale('vi');
export default defineNuxtPlugin(() => {