changes
This commit is contained in:
@@ -126,12 +126,6 @@ $size: (
|
|||||||
// 4. CUSTOM CLASSES
|
// 4. CUSTOM CLASSES
|
||||||
// ==========================================
|
// ==========================================
|
||||||
|
|
||||||
.header-logo {
|
|
||||||
background: url('/logo_dev.png') no-repeat center center;
|
|
||||||
background-size: 40px;
|
|
||||||
width: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Block Layout
|
// Block Layout
|
||||||
.blockdiv {
|
.blockdiv {
|
||||||
max-width: 1900px !important;
|
max-width: 1900px !important;
|
||||||
|
|||||||
@@ -4,3 +4,13 @@
|
|||||||
--bulma-card-shadow: none;
|
--bulma-card-shadow: none;
|
||||||
border: 1px solid $grey-lighter;
|
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;
|
||||||
|
// }
|
||||||
@@ -59,49 +59,20 @@
|
|||||||
border-radius: calc(infinity * 1px);
|
border-radius: calc(infinity * 1px);
|
||||||
}
|
}
|
||||||
|
|
||||||
$base: 0.25rem;
|
.static {
|
||||||
|
position: static;
|
||||||
@function spacing($step) {
|
|
||||||
@return $step * $base;
|
|
||||||
}
|
}
|
||||||
|
.fixed {
|
||||||
$spacing-types: (
|
position: fixed;
|
||||||
"p": "padding",
|
}
|
||||||
"m": "margin",
|
.absolute {
|
||||||
);
|
position: absolute;
|
||||||
|
}
|
||||||
$spacing-variants: (
|
.relative {
|
||||||
"": (""),
|
position: relative;
|
||||||
"x": ("-left", "-right"),
|
}
|
||||||
"y": ("-top", "-bottom"),
|
.sticky {
|
||||||
"t": ("-top"),
|
position: sticky;
|
||||||
"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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── CSS custom properties ─────────────────────────────────────────────────
|
// ─── CSS custom properties ─────────────────────────────────────────────────
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
<template v-for="(v, i) in leftmenu" :key="i" :id="v.code">
|
<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)">
|
<a class="navbar-item rounded-lg is-clipped p-0" v-if="!v.submenu" @click="changeTab(v)">
|
||||||
<span :class="[
|
<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'
|
currentTab.code === v.code ? 'has-text-primary-50 has-background-primary-95' : 'has-text-grey-30'
|
||||||
]">
|
]">
|
||||||
{{ v[lang] }}
|
{{ v[lang] }}
|
||||||
|
|||||||
@@ -12,7 +12,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span class="icon is-left">
|
<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>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="p-2" style="width: 300px">
|
<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">
|
<div class="control pl-2">
|
||||||
<a class="mr-1" @click="previousYear()">
|
<a class="mr-1" @click="previousYear()">
|
||||||
<SvgIcon v-bind="{name: 'doubleleft.svg', type: 'gray', size: 18}"></SvgIcon>
|
<SvgIcon v-bind="{name: 'doubleleft.svg', type: 'gray', size: 18}"></SvgIcon>
|
||||||
@@ -10,8 +10,8 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="control is-expanded has-text-centered">
|
<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="font-bold 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" @click="type='years'">{{ caption || year }}</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="control pr-2">
|
<div class="control pr-2">
|
||||||
<a class="mr-1" @click="nextMonth()" v-if="type==='days'">
|
<a class="mr-1" @click="nextMonth()" v-if="type==='days'">
|
||||||
@@ -22,36 +22,41 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<hr class="mt-0 mb-5" />
|
||||||
<div v-if="type==='days'">
|
<div v-if="type==='days'">
|
||||||
<div class="columns is-mobile mx-0 mb-3">
|
<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 }}
|
{{ m.text }}
|
||||||
</div>
|
</div>
|
||||||
</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="`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">
|
<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}}
|
{{m.dayPrint}}
|
||||||
</span>
|
</span>
|
||||||
<a class="fs-14" @click="choose(m)" v-else>
|
<span class="fs-13 is-clickable" @click="choose(m)" v-else>
|
||||||
<span
|
<span
|
||||||
style="width: 25px; height: 25px; border-radius: 4px"
|
style="width: 25px; height: 25px"
|
||||||
:class="[
|
: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-primary-50 has-text-white': m.date === curdate,
|
||||||
'has-background-light has-text-white': m.date === today,
|
'has-background-success-50 has-text-white': m.date === today,
|
||||||
'has-text-grey-light': m.currentMonth !== m.monthCondition
|
'has-text-grey-70': m.currentMonth !== m.monthCondition
|
||||||
}
|
}
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
{{ m.dayPrint }}
|
{{ m.dayPrint }}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="border-bottom"></div>
|
<hr class="my-1" />
|
||||||
<div class="mt-2">
|
<div class="mt-2 fs-14">
|
||||||
<span class="ml-2">Hôm nay: </span>
|
<span class="ml-2">Hôm nay: </span>
|
||||||
<a class="has-text-primary" @click="chooseToday()">{{ $dayjs(today).format('DD/MM/YYYY') }}</a>
|
<a class="has-text-primary" @click="chooseToday()">{{ $dayjs(today).format('DD/MM/YYYY') }}</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -112,6 +117,7 @@
|
|||||||
weeks.value.map(v=>{
|
weeks.value.map(v=>{
|
||||||
v.dates = dates.filter(x=>x.week===v.week)
|
v.dates = dates.filter(x=>x.week===v.week)
|
||||||
})
|
})
|
||||||
|
console.log('weeks.value', weeks.value)
|
||||||
}
|
}
|
||||||
function nextMonth() {
|
function nextMonth() {
|
||||||
month = month + 1
|
month = month + 1
|
||||||
@@ -177,5 +183,9 @@
|
|||||||
watch(() => props.date, (newVal, oldVal) => {
|
watch(() => props.date, (newVal, oldVal) => {
|
||||||
showDate()
|
showDate()
|
||||||
})
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
a {
|
||||||
|
color: var(--bulma-link-60);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="columns is-mobile is-multiline mx-0">
|
<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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div class="columns is-mobile is-multiline mx-0">
|
<div class="columns is-mobile is-multiline mx-0">
|
||||||
<span
|
<span
|
||||||
v-for="(v,i) in years"
|
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' : ''"
|
:class="i===0 || i===11 ? 'has-text-grey-light' : ''"
|
||||||
@click="$emit('year', v)">{{ v }}</span>
|
@click="$emit('year', v)">{{ v }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,75 +1,61 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
id: Number,
|
order: Object,
|
||||||
code: String,
|
selected: Boolean
|
||||||
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
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const { $dayjs, $shortenCurrency } = useNuxtApp();
|
const { $dayjs, $shortenCurrency } = useNuxtApp();
|
||||||
|
const emit = defineEmits(['selectOrder', 'unselect'])
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<tr>
|
<tr
|
||||||
|
:class="['is-clickable', selected && 'is-selected']"
|
||||||
|
@click="selected ? emit('unselect') : emit('selectOrder', order.id) "
|
||||||
|
>
|
||||||
<td>
|
<td>
|
||||||
<div>
|
<div>
|
||||||
<p class="fs-15 font-semibold">{{ code }}</p>
|
<p class="fs-15 font-semibold">{{ order.code }}</p>
|
||||||
<p class="fs-13 has-text-grey">{{ employee__name }}</p>
|
<p class="has-text-grey">{{ order.employee__name }}</p>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div>
|
<div>
|
||||||
<p>{{ customer__name }}</p>
|
<p>{{ order.customer__name }}</p>
|
||||||
<div class="is-flex is-gap-0.5 is-align-items-center mt-1 fs-13 has-text-grey">
|
<div class="is-flex is-gap-0.5 is-align-items-center mt-1 has-text-grey">
|
||||||
<Icon name="material-symbols:call-outline-rounded"
|
<Icon name="material-symbols:call-outline-rounded"
|
||||||
:size="15"
|
:size="15"
|
||||||
/>
|
/>
|
||||||
<span class="fs-12">{{ customer__phone }}</span>
|
<span class="fs-12">{{ order.customer__phone }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="has-text-right">
|
<td class="has-text-right">
|
||||||
<div>
|
<div>
|
||||||
<p class="font-semibold">{{ $shortenCurrency(total) }}</p>
|
<p class="fs-14 font-semibold">{{ $shortenCurrency(order.total) }}</p>
|
||||||
<p class="fs-13 has-text-grey">{{ order__products.length }} SP</p>
|
<p class="has-text-grey">{{ order.order__products.length }} SP</p>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="has-text-centered">
|
<td class="has-text-centered">
|
||||||
<span :class="[
|
<span :class="[
|
||||||
'tag rounded-full',
|
'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>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<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>
|
||||||
<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>
|
||||||
<td>
|
<td>
|
||||||
<div>
|
<div>
|
||||||
<div class="is-flex is-gap-0.5">
|
<div class="is-flex is-gap-0.5">
|
||||||
<Icon :size="18" name="material-symbols:calendar-month-outline-rounded" />
|
<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>
|
</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>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -78,6 +64,10 @@ const { $dayjs, $shortenCurrency } = useNuxtApp();
|
|||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
tr.is-selected {
|
||||||
|
--bulma-table-row-active-background-color: var(--bulma-primary-95);
|
||||||
|
color: unset;
|
||||||
|
}
|
||||||
td {
|
td {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
--bulma-table-cell-padding: 0.75em;
|
--bulma-table-cell-padding: 0.75em;
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import OrderRow from '@/components/orders/OrderRow.vue';
|
import OrderRow from '@/components/orders/OrderRow.vue';
|
||||||
|
import SelectedOrder from '@/components/orders/SelectedOrder.vue';
|
||||||
|
import { pull } from 'es-toolkit';
|
||||||
|
|
||||||
|
const { $dayjs } = useNuxtApp();
|
||||||
|
|
||||||
const orders = [
|
const orders = [
|
||||||
{
|
{
|
||||||
@@ -62,7 +66,7 @@ const orders = [
|
|||||||
status__color: 'blue',
|
status__color: 'blue',
|
||||||
payment_status: 2,
|
payment_status: 2,
|
||||||
payment_status__name: 'Một phần',
|
payment_status__name: 'Một phần',
|
||||||
payment_status__color: 'orange',
|
payment_status__color: 'yellow',
|
||||||
delivery_status: 2,
|
delivery_status: 2,
|
||||||
delivery_status__name: 'Sẵn sàng',
|
delivery_status__name: 'Sẵn sàng',
|
||||||
delivery_status__color: 'blue',
|
delivery_status__color: 'blue',
|
||||||
@@ -186,46 +190,408 @@ const orders = [
|
|||||||
],
|
],
|
||||||
create_time: '2026-04-04T23:21:11.587660+07:00'
|
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>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-content"></div>
|
<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>
|
||||||
|
<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"
|
||||||
|
/>
|
||||||
|
</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">
|
||||||
<div class="card-content p-0">
|
<div class="card-content p-0">
|
||||||
<p class="p-5 fs-17 font-semibold is-flex is-align-items-center is-gap-1">
|
<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" />
|
<Icon name="material-symbols:list-alt-outline-rounded" :size="22" />
|
||||||
<span>Danh sách đơn hàng ({{ orders.length }})</span>
|
<span>Danh sách đơn hàng ({{ filteredOrders.length }})</span>
|
||||||
</p>
|
</p>
|
||||||
<table class="table is-fullwidth is-hoverable fs-14">
|
<table class="table is-fullwidth is-hoverable fs-13">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Đơn hàng</th>
|
<th class="font-semibold">Đơn hàng</th>
|
||||||
<th>Khách hàng</th>
|
<th class="font-semibold">Khách hàng</th>
|
||||||
<th class="has-text-right">Tổng tiền</th>
|
<th class="font-semibold has-text-right">Tổng tiền</th>
|
||||||
<th class="has-text-centered">Trạng thái</th>
|
<th class="font-semibold has-text-centered">Trạng thái</th>
|
||||||
<th>Thanh toán</th>
|
<th class="font-semibold">Thanh toán</th>
|
||||||
<th>Giao hàng</th>
|
<th class="font-semibold">Giao hàng</th>
|
||||||
<th>Ngày tạo</th>
|
<th class="font-semibold">Ngày tạo</th>
|
||||||
<th>Thao tác</th>
|
<th class="font-semibold">Thao tác</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<OrderRow
|
<OrderRow
|
||||||
v-for="order in orders"
|
v-for="order in filteredOrders"
|
||||||
:key="order.id"
|
:key="order.id"
|
||||||
v-bind="order"
|
v-bind="{ order, selected: order.id === selectedOrder?.id }"
|
||||||
|
@selectOrder="(id) => {
|
||||||
|
selectedOrder = filteredOrders.find(order => order.id === id);
|
||||||
|
}"
|
||||||
|
@unselect="selectedOrder = null"
|
||||||
/>
|
/>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<SelectedOrder :order="selectedOrder" @unselect="selectedOrder = null" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<style scoped>
|
|
||||||
th {
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
105
app/components/orders/SelectedOrder.vue
Normal file
105
app/components/orders/SelectedOrder.vue
Normal 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>
|
||||||
@@ -297,8 +297,3 @@ function cancelEditDocument() {
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<style>
|
|
||||||
.table th {
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
style="min-height: 100vh; background-color: #f9fafb;"
|
style="min-height: 100vh"
|
||||||
|
class="has-background-blue-100"
|
||||||
data-theme="light"
|
data-theme="light"
|
||||||
lang="vi"
|
lang="vi"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -5,12 +5,16 @@ import dayjs from 'dayjs';
|
|||||||
import weekday from 'dayjs/plugin/weekday';
|
import weekday from 'dayjs/plugin/weekday';
|
||||||
import weekOfYear from 'dayjs/plugin/weekOfYear';
|
import weekOfYear from 'dayjs/plugin/weekOfYear';
|
||||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
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';
|
import 'dayjs/locale/vi';
|
||||||
dayjs.extend(weekday);
|
dayjs.extend(weekday);
|
||||||
dayjs.extend(weekOfYear);
|
dayjs.extend(weekOfYear);
|
||||||
dayjs.extend(relativeTime);
|
dayjs.extend(relativeTime);
|
||||||
dayjs.extend(localizedFormat);
|
dayjs.extend(localizedFormat);
|
||||||
|
dayjs.extend(isSameOrBefore);
|
||||||
|
dayjs.extend(isSameOrAfter);
|
||||||
dayjs.locale('vi');
|
dayjs.locale('vi');
|
||||||
|
|
||||||
export default defineNuxtPlugin(() => {
|
export default defineNuxtPlugin(() => {
|
||||||
|
|||||||
1376
my-bulma-project.css
1376
my-bulma-project.css
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -26,7 +26,38 @@ $grey: #767676;
|
|||||||
"purple": $purple,
|
"purple": $purple,
|
||||||
"pink": $pink,
|
"pink": $pink,
|
||||||
"grey": $grey
|
"grey": $grey
|
||||||
)
|
),
|
||||||
|
$spacing-values: (
|
||||||
|
"auto": auto,
|
||||||
|
"px": 1px,
|
||||||
|
"full": 100%,
|
||||||
|
"min": min-content,
|
||||||
|
"max": max-content,
|
||||||
|
"fit": fit-content,
|
||||||
|
"0": 0,
|
||||||
|
"1": 0.25rem,
|
||||||
|
"2": 0.5rem,
|
||||||
|
"3": 0.75rem,
|
||||||
|
"4": 1rem,
|
||||||
|
"5": 1.25rem,
|
||||||
|
"6": 1.5rem,
|
||||||
|
"7": 1.75rem,
|
||||||
|
"8": 2rem,
|
||||||
|
"9": 2.25rem,
|
||||||
|
"10": 2.5rem,
|
||||||
|
"11": 2.75rem,
|
||||||
|
"12": 3rem,
|
||||||
|
"14": 3.5rem,
|
||||||
|
"16": 4rem,
|
||||||
|
"20": 5rem,
|
||||||
|
"24": 6rem,
|
||||||
|
"28": 7rem,
|
||||||
|
"32": 8rem,
|
||||||
|
"36": 9rem,
|
||||||
|
"40": 10rem,
|
||||||
|
"44": 11rem,
|
||||||
|
"48": 12rem,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900');
|
@import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900');
|
||||||
306
package-lock.json
generated
306
package-lock.json
generated
@@ -7,9 +7,6 @@
|
|||||||
"name": "nuxt-app",
|
"name": "nuxt-app",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aps_sdk/authentication": "^1.0.0",
|
|
||||||
"@aps_sdk/model-derivative": "^1.2.0",
|
|
||||||
"@aps_sdk/oss": "^1.2.2",
|
|
||||||
"@nuxt/image": "^1.11.0",
|
"@nuxt/image": "^1.11.0",
|
||||||
"@pinia/nuxt": "^0.11.2",
|
"@pinia/nuxt": "^0.11.2",
|
||||||
"@tato30/vue-pdf": "^1.11.4",
|
"@tato30/vue-pdf": "^1.11.4",
|
||||||
@@ -62,50 +59,6 @@
|
|||||||
"url": "https://github.com/sponsors/antfu"
|
"url": "https://github.com/sponsors/antfu"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@aps_sdk/authentication": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@aps_sdk/authentication/-/authentication-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-nCRi0UCw1UKQAg1jZj8SOvZJU75rQgUVDjvljhvaKXlwol8+KHxl2qNHINOzCaJUyi8FW/QRqlaqSzWDyuY0lw==",
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"dependencies": {
|
|
||||||
"@aps_sdk/autodesk-sdkmanager": "^1.0.0",
|
|
||||||
"@types/node": "^20.9.0",
|
|
||||||
"axios": "^1.7.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@aps_sdk/autodesk-sdkmanager": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@aps_sdk/autodesk-sdkmanager/-/autodesk-sdkmanager-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-Nqi59aa3xHa5qG9KZZ9HhxYMrMGFimmbqLq8406MZB9Tje0gqwZLdEFfu25VDUhbzvONuq+ZX2m0e+yhBHl2QQ==",
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"dependencies": {
|
|
||||||
"axios": "^1.7.8",
|
|
||||||
"cockatiel": "^3.1.1",
|
|
||||||
"winston": "^3.9.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@aps_sdk/model-derivative": {
|
|
||||||
"version": "1.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@aps_sdk/model-derivative/-/model-derivative-1.2.0.tgz",
|
|
||||||
"integrity": "sha512-2offgFmKpgyv/0tKK5kvvHCnZwFb73wCMHD9wkJHHPCE2cMt8awXPEmeCpddXiJBT5TuIlI/hAj6K+c96gc0fw==",
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"dependencies": {
|
|
||||||
"@aps_sdk/autodesk-sdkmanager": "^1.0.0",
|
|
||||||
"@types/node": "^20.9.0",
|
|
||||||
"axios": "^1.7.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@aps_sdk/oss": {
|
|
||||||
"version": "1.2.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@aps_sdk/oss/-/oss-1.2.2.tgz",
|
|
||||||
"integrity": "sha512-K6t+3IYzVYLDPZOY45wkdfcShxVo/NltW+Ty3OWRJ9wu3DkzoiaaQPmHQSZ3iZN6g/Q/Tpqg1wO+ORif/DqrbA==",
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"dependencies": {
|
|
||||||
"@aps_sdk/autodesk-sdkmanager": "^1.0.0",
|
|
||||||
"@types/node": "^20.9.0",
|
|
||||||
"axios": "^1.7.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@babel/code-frame": {
|
"node_modules/@babel/code-frame": {
|
||||||
"version": "7.27.1",
|
"version": "7.27.1",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
|
||||||
@@ -563,26 +516,6 @@
|
|||||||
"node": ">=10.0.0"
|
"node": ">=10.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@colors/colors": {
|
|
||||||
"version": "1.6.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz",
|
|
||||||
"integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.1.90"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@dabh/diagnostics": {
|
|
||||||
"version": "2.0.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.8.tgz",
|
|
||||||
"integrity": "sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@so-ric/colorspace": "^1.1.6",
|
|
||||||
"enabled": "2.0.x",
|
|
||||||
"kuler": "^2.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@dxup/nuxt": {
|
"node_modules/@dxup/nuxt": {
|
||||||
"version": "0.2.2",
|
"version": "0.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/@dxup/nuxt/-/nuxt-0.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/@dxup/nuxt/-/nuxt-0.2.2.tgz",
|
||||||
@@ -4672,62 +4605,6 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@so-ric/colorspace": {
|
|
||||||
"version": "1.1.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/@so-ric/colorspace/-/colorspace-1.1.6.tgz",
|
|
||||||
"integrity": "sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"color": "^5.0.2",
|
|
||||||
"text-hex": "1.0.x"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@so-ric/colorspace/node_modules/color": {
|
|
||||||
"version": "5.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/color/-/color-5.0.3.tgz",
|
|
||||||
"integrity": "sha512-ezmVcLR3xAVp8kYOm4GS45ZLLgIE6SPAFoduLr6hTDajwb3KZ2F46gulK3XpcwRFb5KKGCSezCBAY4Dw4HsyXA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"color-convert": "^3.1.3",
|
|
||||||
"color-string": "^2.1.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@so-ric/colorspace/node_modules/color-convert": {
|
|
||||||
"version": "3.1.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-3.1.3.tgz",
|
|
||||||
"integrity": "sha512-fasDH2ont2GqF5HpyO4w0+BcewlhHEZOFn9c1ckZdHpJ56Qb7MHhH/IcJZbBGgvdtwdwNbLvxiBEdg336iA9Sg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"color-name": "^2.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@so-ric/colorspace/node_modules/color-name": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12.20"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@so-ric/colorspace/node_modules/color-string": {
|
|
||||||
"version": "2.1.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/color-string/-/color-string-2.1.4.tgz",
|
|
||||||
"integrity": "sha512-Bb6Cq8oq0IjDOe8wJmi4JeNn763Xs9cfrBcaylK1tPypWzyoy2G3l90v9k64kjphl/ZJjPIShFztenRomi8WTg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"color-name": "^2.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@socket.io/component-emitter": {
|
"node_modules/@socket.io/component-emitter": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
|
||||||
@@ -4832,7 +4709,10 @@
|
|||||||
"version": "20.19.25",
|
"version": "20.19.25",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.25.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.25.tgz",
|
||||||
"integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==",
|
"integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~6.21.0"
|
"undici-types": "~6.21.0"
|
||||||
}
|
}
|
||||||
@@ -4851,12 +4731,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/triple-beam": {
|
|
||||||
"version": "1.3.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz",
|
|
||||||
"integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/@types/unist": {
|
"node_modules/@types/unist": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
|
||||||
@@ -6354,6 +6228,7 @@
|
|||||||
"version": "3.2.6",
|
"version": "3.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
|
||||||
"integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
|
"integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/async-each": {
|
"node_modules/async-each": {
|
||||||
@@ -7836,15 +7711,6 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cockatiel": {
|
|
||||||
"version": "3.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/cockatiel/-/cockatiel-3.2.1.tgz",
|
|
||||||
"integrity": "sha512-gfrHV6ZPkquExvMh9IOkKsBzNDk6sDuZ6DdBGUBkvFnTCqCxzpuq48RySgP0AnaqQkw2zynOFj9yly6T1Q2G5Q==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=16"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/collection-visit": {
|
"node_modules/collection-visit": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
|
||||||
@@ -9227,12 +9093,6 @@
|
|||||||
"node": ">= 4"
|
"node": ">= 4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/enabled": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/encodeurl": {
|
"node_modules/encodeurl": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
|
||||||
@@ -9787,12 +9647,6 @@
|
|||||||
"reusify": "^1.0.4"
|
"reusify": "^1.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fecha": {
|
|
||||||
"version": "4.2.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz",
|
|
||||||
"integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/figgy-pudding": {
|
"node_modules/figgy-pudding": {
|
||||||
"version": "3.5.2",
|
"version": "3.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
|
||||||
@@ -9859,12 +9713,6 @@
|
|||||||
"readable-stream": "^2.3.6"
|
"readable-stream": "^2.3.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fn.name": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/follow-redirects": {
|
"node_modules/follow-redirects": {
|
||||||
"version": "1.15.11",
|
"version": "1.15.11",
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
|
||||||
@@ -11937,12 +11785,6 @@
|
|||||||
"integrity": "sha512-4LqMNoONzR43B1W0ek0fhXMsDNW/zxa1NdFAVMY+k28pgZLovR4G3PB5MrpTxCy1QaZCqNoiaKPr5w5qZHfSNw==",
|
"integrity": "sha512-4LqMNoONzR43B1W0ek0fhXMsDNW/zxa1NdFAVMY+k28pgZLovR4G3PB5MrpTxCy1QaZCqNoiaKPr5w5qZHfSNw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/kuler": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/launch-editor": {
|
"node_modules/launch-editor": {
|
||||||
"version": "2.12.0",
|
"version": "2.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.12.0.tgz",
|
||||||
@@ -12156,23 +11998,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/logform": {
|
|
||||||
"version": "2.7.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz",
|
|
||||||
"integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@colors/colors": "1.6.0",
|
|
||||||
"@types/triple-beam": "^1.3.2",
|
|
||||||
"fecha": "^4.2.0",
|
|
||||||
"ms": "^2.1.1",
|
|
||||||
"safe-stable-stringify": "^2.3.1",
|
|
||||||
"triple-beam": "^1.3.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 12.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/lop": {
|
"node_modules/lop": {
|
||||||
"version": "0.4.2",
|
"version": "0.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/lop/-/lop-0.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/lop/-/lop-0.4.2.tgz",
|
||||||
@@ -13688,15 +13513,6 @@
|
|||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/one-time": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"fn.name": "1.x.x"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/onetime": {
|
"node_modules/onetime": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
|
||||||
@@ -15881,15 +15697,6 @@
|
|||||||
"ret": "~0.1.10"
|
"ret": "~0.1.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/safe-stable-stringify": {
|
|
||||||
"version": "2.5.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz",
|
|
||||||
"integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/safer-buffer": {
|
"node_modules/safer-buffer": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
@@ -16759,15 +16566,6 @@
|
|||||||
"figgy-pudding": "^3.5.1"
|
"figgy-pudding": "^3.5.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/stack-trace": {
|
|
||||||
"version": "0.0.10",
|
|
||||||
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
|
|
||||||
"integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/standard-as-callback": {
|
"node_modules/standard-as-callback": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz",
|
||||||
@@ -17335,12 +17133,6 @@
|
|||||||
"b4a": "^1.6.4"
|
"b4a": "^1.6.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/text-hex": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/through2": {
|
"node_modules/through2": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
|
||||||
@@ -17623,15 +17415,6 @@
|
|||||||
"url": "https://github.com/sponsors/wooorm"
|
"url": "https://github.com/sponsors/wooorm"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/triple-beam": {
|
|
||||||
"version": "1.4.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz",
|
|
||||||
"integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/tslib": {
|
"node_modules/tslib": {
|
||||||
"version": "2.8.1",
|
"version": "2.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
@@ -17765,7 +17548,10 @@
|
|||||||
"version": "6.21.0",
|
"version": "6.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
||||||
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
|
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
|
||||||
"license": "MIT"
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/unenv": {
|
"node_modules/unenv": {
|
||||||
"version": "2.0.0-rc.24",
|
"version": "2.0.0-rc.24",
|
||||||
@@ -19838,82 +19624,6 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/winston": {
|
|
||||||
"version": "3.18.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/winston/-/winston-3.18.3.tgz",
|
|
||||||
"integrity": "sha512-NoBZauFNNWENgsnC9YpgyYwOVrl2m58PpQ8lNHjV3kosGs7KJ7Npk9pCUE+WJlawVSe8mykWDKWFSVfs3QO9ww==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@colors/colors": "^1.6.0",
|
|
||||||
"@dabh/diagnostics": "^2.0.8",
|
|
||||||
"async": "^3.2.3",
|
|
||||||
"is-stream": "^2.0.0",
|
|
||||||
"logform": "^2.7.0",
|
|
||||||
"one-time": "^1.0.0",
|
|
||||||
"readable-stream": "^3.4.0",
|
|
||||||
"safe-stable-stringify": "^2.3.1",
|
|
||||||
"stack-trace": "0.0.x",
|
|
||||||
"triple-beam": "^1.3.0",
|
|
||||||
"winston-transport": "^4.9.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 12.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/winston-transport": {
|
|
||||||
"version": "4.9.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.9.0.tgz",
|
|
||||||
"integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"logform": "^2.7.0",
|
|
||||||
"readable-stream": "^3.6.2",
|
|
||||||
"triple-beam": "^1.3.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 12.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/winston-transport/node_modules/readable-stream": {
|
|
||||||
"version": "3.6.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
|
||||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"inherits": "^2.0.3",
|
|
||||||
"string_decoder": "^1.1.1",
|
|
||||||
"util-deprecate": "^1.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/winston/node_modules/is-stream": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
|
||||||
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/winston/node_modules/readable-stream": {
|
|
||||||
"version": "3.6.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
|
||||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"inherits": "^2.0.3",
|
|
||||||
"string_decoder": "^1.1.1",
|
|
||||||
"util-deprecate": "^1.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/worker-farm": {
|
"node_modules/worker-farm": {
|
||||||
"version": "1.7.0",
|
"version": "1.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
|
||||||
|
|||||||
@@ -11,9 +11,6 @@
|
|||||||
"build-bulma": "sass --load-path=node_modules my-bulma-project.scss my-bulma-project.css"
|
"build-bulma": "sass --load-path=node_modules my-bulma-project.scss my-bulma-project.css"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aps_sdk/authentication": "^1.0.0",
|
|
||||||
"@aps_sdk/model-derivative": "^1.2.0",
|
|
||||||
"@aps_sdk/oss": "^1.2.2",
|
|
||||||
"@nuxt/image": "^1.11.0",
|
"@nuxt/image": "^1.11.0",
|
||||||
"@pinia/nuxt": "^0.11.2",
|
"@pinia/nuxt": "^0.11.2",
|
||||||
"@tato30/vue-pdf": "^1.11.4",
|
"@tato30/vue-pdf": "^1.11.4",
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
import { getViewerToken } from '../utils/aps.js';
|
|
||||||
|
|
||||||
export default defineEventHandler(getViewerToken);
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
export default defineEventHandler(async (event) => {
|
|
||||||
const urn = getRouterParam(event, 'urn');
|
|
||||||
const manifest = await getManifest(urn);
|
|
||||||
|
|
||||||
if (!manifest)
|
|
||||||
return { status: 'n/a' };
|
|
||||||
|
|
||||||
let messages = [];
|
|
||||||
if (manifest.derivatives) {
|
|
||||||
for (const derivative of manifest.derivatives) {
|
|
||||||
messages = messages.concat(derivative.messages || []);
|
|
||||||
if (derivative.children) {
|
|
||||||
for (const child of derivative.children) {
|
|
||||||
messages.concat(child.messages || []);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
status: manifest.status,
|
|
||||||
progress: manifest.progress,
|
|
||||||
messages
|
|
||||||
};
|
|
||||||
})
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
export default defineEventHandler(async (event) => {
|
|
||||||
if (event.method === 'GET') {
|
|
||||||
const objects = await listObjects();
|
|
||||||
return objects.map((o) => ({
|
|
||||||
name: o.objectKey,
|
|
||||||
urn: urnify(o.objectId),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.method === 'POST') {
|
|
||||||
const formData = await readMultipartFormData(event);
|
|
||||||
if (!formData) {
|
|
||||||
throw createError({
|
|
||||||
statusCode: 400,
|
|
||||||
statusMessage: `formData should not be ${formData}`,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const file = formData[0];
|
|
||||||
|
|
||||||
try {
|
|
||||||
const obj = await uploadObject(file.filename, file.data);
|
|
||||||
await translateObject(urnify(obj.objectId), req.fields['model-zip-entrypoint']);
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: obj.objectKey,
|
|
||||||
urn: urnify(obj.objectId),
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
throw createError({
|
|
||||||
statusCode: 400,
|
|
||||||
statusMessage: 'Upload file failed',
|
|
||||||
error,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
export default defineEventHandler((event) => {
|
|
||||||
const originalUrl = event.node.req.url || "";
|
|
||||||
if (originalUrl.startsWith("/product:")) {
|
|
||||||
const rewritten = originalUrl.replace("/product:", "/product/");
|
|
||||||
event.node.req.url = rewritten;
|
|
||||||
event._path = rewritten;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../.nuxt/tsconfig.server.json"
|
|
||||||
}
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
import { AuthenticationClient, Scopes } from '@aps_sdk/authentication';
|
|
||||||
import { ModelDerivativeClient, View, OutputType } from '@aps_sdk/model-derivative';
|
|
||||||
import { OssClient, Region, PolicyKey } from '@aps_sdk/oss';
|
|
||||||
|
|
||||||
const apsClientId = 'PkqB8KlPGekLGKElPSjPhC9C2NGyXMN64QVhPSaqUhV46zEn';
|
|
||||||
const apsClientSecret = 'Jr70CpXFaV2PRd9lux3ZXBKpSMwFsyO6xq1Y7AJy1Q4xcK6nZMLq20KB8SlipC4Z';
|
|
||||||
const apsBucket = `${apsClientId.toLowerCase()}-basic-app`;
|
|
||||||
const authenticationClient = new AuthenticationClient();
|
|
||||||
const ossClient = new OssClient();
|
|
||||||
const modelDerivativeClient = new ModelDerivativeClient();
|
|
||||||
|
|
||||||
async function getInternalToken() {
|
|
||||||
const credentials = await authenticationClient.getTwoLeggedToken(
|
|
||||||
apsClientId,
|
|
||||||
apsClientSecret,
|
|
||||||
[Scopes.DataRead, Scopes.DataCreate, Scopes.DataWrite, Scopes.BucketCreate, Scopes.BucketRead],
|
|
||||||
);
|
|
||||||
return credentials.access_token;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getViewerToken = async () => {
|
|
||||||
return await authenticationClient.getTwoLeggedToken(apsClientId, apsClientSecret, [
|
|
||||||
Scopes.ViewablesRead,
|
|
||||||
]);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const ensureBucketExists = async (bucketKey) => {
|
|
||||||
const accessToken = await getInternalToken();
|
|
||||||
try {
|
|
||||||
await ossClient.getBucketDetails(bucketKey, { accessToken });
|
|
||||||
} catch (err) {
|
|
||||||
if (err.axiosError.response.status === 404) {
|
|
||||||
await ossClient.createBucket(
|
|
||||||
Region.Us,
|
|
||||||
{ bucketKey: bucketKey, policyKey: PolicyKey.Persistent },
|
|
||||||
{ accessToken },
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const listObjects = async () => {
|
|
||||||
await ensureBucketExists(apsBucket);
|
|
||||||
const accessToken = await getInternalToken();
|
|
||||||
let resp = await ossClient.getObjects(apsBucket, { limit: 64, accessToken });
|
|
||||||
let objects = resp.items;
|
|
||||||
while (resp.next) {
|
|
||||||
const startAt = new URL(resp.next).searchParams.get('startAt');
|
|
||||||
resp = await ossClient.getObjects(apsBucket, { limit: 64, startAt, accessToken });
|
|
||||||
objects = objects.concat(resp.items);
|
|
||||||
}
|
|
||||||
return objects;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const uploadObject = async (objectName, buffer) => {
|
|
||||||
await ensureBucketExists(apsBucket);
|
|
||||||
const accessToken = await getInternalToken();
|
|
||||||
const obj = await ossClient.uploadObject(apsBucket, objectName, buffer, { accessToken });
|
|
||||||
return obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const translateObject = async (urn, rootFilename) => {
|
|
||||||
const accessToken = await getInternalToken();
|
|
||||||
const job = await modelDerivativeClient.startJob(
|
|
||||||
{
|
|
||||||
input: {
|
|
||||||
urn,
|
|
||||||
compressedUrn: !!rootFilename,
|
|
||||||
rootFilename,
|
|
||||||
},
|
|
||||||
output: {
|
|
||||||
formats: [
|
|
||||||
{
|
|
||||||
views: [View._2d, View._3d],
|
|
||||||
type: OutputType.Svf2,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{ accessToken },
|
|
||||||
);
|
|
||||||
return job.result;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getManifest = async (urn) => {
|
|
||||||
const accessToken = await getInternalToken();
|
|
||||||
try {
|
|
||||||
const manifest = await modelDerivativeClient.getManifest(urn, { accessToken });
|
|
||||||
return manifest;
|
|
||||||
} catch (err) {
|
|
||||||
if (err.axiosError.response.status === 404) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const urnify = (id) => Buffer.from(id).toString('base64').replace(/=/g, '');
|
|
||||||
Reference in New Issue
Block a user