This commit is contained in:
Viet An
2026-05-11 13:34:53 +07:00
parent edad738489
commit f1ecd5c7ff
22 changed files with 1582 additions and 326 deletions

View File

@@ -1,3 +0,0 @@
<script lang="ts" setup></script>
<template>AddOS</template>

View File

@@ -28,237 +28,312 @@ async function createProduct() {
const res = await $insertapi("product", body.value);
isPending.value = false;
}
/* TODO: <SearchBox> addons */
const addOS = {
component: "imports/AddOS",
width: "60%",
height: "auto",
title: "AddOS",
};
</script>
<template>
<h1 class="subtitle is-4">AddProductForm</h1>
<form class="fixed-grid has-12-cols">
<div class="grid">
<div class="cell is-col-span-8">
<div class="field">
<label class="label">Tên sản phẩm</label>
<div class="control">
<input
class="input"
v-model.trim="body.name"
type="text"
placeholder="Tên"
<div>
<h1 class="subtitle is-4">AddProductForm</h1>
<form class="fixed-grid has-12-cols">
<div class="grid">
<div class="cell is-col-span-8">
<div class="field">
<label class="label">Tên sản phẩm</label>
<div class="control">
<input
class="input"
v-model.trim="body.name"
type="text"
placeholder="Tên"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">OS</label>
<SearchBox
v-bind="{
api: 'OS',
field: 'name',
column: ['name'],
first: true,
placeholder: 'OS',
addon: {
component: 'imports/addons/AddOS',
width: '70%',
height: 'auto',
title: 'Thêm hệ điều hành',
},
}"
@option="selected('os', $event)"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">OS</label>
<SearchBox
v-bind="{
api: 'OS',
field: 'name',
column: ['name'],
first: true,
placeholder: 'OS',
}"
@option="selected('os', $event)"
/>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Hãng</label>
<SearchBox
v-bind="{
api: 'Manufacturer',
field: 'name',
column: ['name'],
first: true,
placeholder: 'Hãng',
addon: {
component: 'imports/addons/AddManufacturer',
width: '70%',
height: 'auto',
title: 'Thêm hãng',
},
}"
@option="selected('manufacturer', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Pin</label>
<SearchBox
v-bind="{
api: 'Battery',
field: 'code',
column: ['code'],
first: true,
placeholder: 'Pin',
addon: {
component: 'imports/addons/AddBattery',
width: '70%',
height: 'auto',
title: 'Thêm pin',
},
}"
@option="selected('battery', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Màn hình</label>
<SearchBox
v-bind="{
api: 'Screen',
field: 'code',
column: ['code'],
first: true,
placeholder: 'Màn hình',
addon: {
component: 'imports/addons/AddScreen',
width: '70%',
height: 'auto',
title: 'Thêm màn hình',
},
}"
@option="selected('screen', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">CPU</label>
<SearchBox
v-bind="{
api: 'CPU',
field: 'name',
column: ['name'],
first: true,
placeholder: 'CPU',
addon: {
component: 'imports/addons/AddCPU',
width: '70%',
height: 'auto',
title: 'Thêm CPU',
},
}"
@option="selected('cpu', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">GPU</label>
<SearchBox
v-bind="{
api: 'GPU',
field: 'name',
column: ['name'],
first: true,
placeholder: 'GPU',
addon: {
component: 'imports/addons/AddGPU',
width: '70%',
height: 'auto',
title: 'Thêm GPU',
},
}"
@option="selected('gpu', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Camera</label>
<SearchBox
v-bind="{
api: 'Camera_System',
field: 'code',
column: ['code'],
first: true,
placeholder: 'Camera',
addon: {
component: 'imports/addons/AddCamera',
width: '70%',
height: 'auto',
title: 'Thêm camera',
},
}"
@option="selected('camera_system', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">SIM</label>
<SearchBox
v-bind="{
api: 'SIM',
field: 'code',
column: ['code'],
first: true,
placeholder: 'SIM',
addon: {
component: 'imports/addons/AddSIM',
width: '70%',
height: 'auto',
title: 'Thêm SIM',
},
}"
@option="selected('sim', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Kết nối</label>
<SearchBox
v-bind="{
api: 'Network_Technology',
field: 'name',
column: ['name'],
first: true,
placeholder: 'Kết nối',
addon: {
component: 'imports/addons/AddNetworkTechnology',
width: '70%',
height: 'auto',
title: 'Thêm kết nối',
},
}"
@option="selected('network_technology', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Công nghệ sạc</label>
<SearchBox
v-bind="{
api: 'Charging_Technology',
field: 'code',
column: ['code'],
first: true,
placeholder: 'Công nghệ sạc',
addon: {
component: 'imports/addons/AddChargingTechnology',
width: '70%',
height: 'auto',
title: 'Thêm công nghệ sạc',
},
}"
@option="selected('charging_technology', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Bộ nhớ ngoài</label>
<SearchBox
v-bind="{
api: 'External_Storage',
field: 'code',
column: ['code'],
first: true,
placeholder: 'Bộ nhớ ngoài',
addon: {
component: 'imports/addons/AddExternalStorage',
width: '70%',
height: 'auto',
title: 'Thêm bộ nhớ ngoài',
},
}"
@option="selected('external_storage', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Chỉ số IP</label>
<SearchBox
v-bind="{
api: 'IP_Rating',
field: 'name',
column: ['name'],
first: true,
placeholder: 'Chỉ số IP',
addon: {
component: 'imports/addons/AddIPRating',
width: '70%',
height: 'auto',
title: 'Thêm chỉ số IP',
},
}"
@option="selected('ip_rating', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Chất liệu</label>
<SearchBox
v-bind="{
api: 'Design',
field: 'label',
column: ['frame_material', 'back_material'],
first: true,
placeholder: 'Chất liệu',
addon: {
component: 'imports/addons/AddDesign',
width: '70%',
height: 'auto',
title: 'Thêm chất liệu',
},
}"
@option="selected('design', $event)"
/>
</div>
</div>
<div class="cell is-col-span-12">
<button
:class="['button is-primary', { 'is-loading': isPending }]"
:disabled="Object.values(body).every((v) => v === null)"
@click.prevent="createProduct"
>
<span class="icon">
<Icon name="material-symbols:add-2-rounded" />
</span>
<span>Tạo sản phẩm</span>
</button>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Hãng</label>
<SearchBox
v-bind="{
api: 'Manufacturer',
field: 'name',
column: ['name'],
first: true,
placeholder: 'Hãng',
}"
@option="selected('manufacturer', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Pin</label>
<SearchBox
v-bind="{
api: 'Battery',
field: 'code',
column: ['code'],
first: true,
placeholder: 'Pin',
}"
@option="selected('battery', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Màn hình</label>
<SearchBox
v-bind="{
api: 'Screen',
field: 'code',
column: ['code'],
first: true,
placeholder: 'Màn hình',
}"
@option="selected('screen', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">CPU</label>
<SearchBox
v-bind="{
api: 'CPU',
field: 'name',
column: ['name'],
first: true,
placeholder: 'CPU',
}"
@option="selected('cpu', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">GPU</label>
<SearchBox
v-bind="{
api: 'GPU',
field: 'name',
column: ['name'],
first: true,
placeholder: 'GPU',
}"
@option="selected('gpu', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Camera</label>
<SearchBox
v-bind="{
api: 'Camera_System',
field: 'code',
column: ['code'],
first: true,
placeholder: 'Camera',
}"
@option="selected('camera_system', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">SIM</label>
<SearchBox
v-bind="{
api: 'SIM',
field: 'code',
column: ['code'],
first: true,
placeholder: 'SIM',
}"
@option="selected('sim', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Kết nối</label>
<SearchBox
v-bind="{
api: 'Network_Technology',
field: 'name',
column: ['name'],
first: true,
placeholder: 'Kết nối',
}"
@option="selected('network_technology', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Công nghệ sạc</label>
<SearchBox
v-bind="{
api: 'Charging_Technology',
field: 'code',
column: ['code'],
first: true,
placeholder: 'Công nghệ sạc',
}"
@option="selected('charging_technology', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Bộ nhớ ngoài</label>
<SearchBox
v-bind="{
api: 'External_Storage',
field: 'code',
column: ['code'],
first: true,
placeholder: 'Bộ nhớ ngoài',
}"
@option="selected('external_storage', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Chỉ số IP</label>
<SearchBox
v-bind="{
api: 'IP_Rating',
field: 'name',
column: ['name'],
first: true,
placeholder: 'Chỉ số IP',
}"
@option="selected('ip_rating', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Chất liệu</label>
<SearchBox
v-bind="{
api: 'Design',
field: 'label',
column: ['frame_material', 'back_material'],
first: true,
placeholder: 'Chất liệu',
}"
@option="selected('design', $event)"
/>
</div>
</div>
<div class="cell is-col-span-12">
<button
:class="['button is-primary', { 'is-loading': isPending }]"
:disabled="Object.values(body).every((v) => v === null)"
@click.prevent="createProduct"
>
Tạo sản phẩm
</button>
</div>
</div>
</form>
</form>
</div>
</template>

View File

@@ -29,106 +29,135 @@ async function createProductVariant() {
</script>
<template>
<h1 class="subtitle is-4">AddProductVariantForm</h1>
<form class="fixed-grid has-12-cols">
<div class="grid">
<div class="cell is-col-span-8">
<div class="field">
<label class="label">Sản phẩm</label>
<SearchBox
v-bind="{
api: 'product',
field: 'name',
column: ['name'],
first: true,
placeholder: 'Sản phẩm',
}"
@option="selected('product', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Đơn giá</label>
<div class="control">
<InputNumber
<div>
<h1 class="subtitle is-4">AddProductVariantForm</h1>
<form class="fixed-grid has-12-cols">
<div class="grid">
<div class="cell is-col-span-8">
<div class="field">
<label class="label">Sản phẩm</label>
<SearchBox
v-bind="{
record: body,
attr: 'price',
placeholder: 'Đơn giá',
api: 'product',
field: 'name',
column: ['name'],
first: true,
placeholder: 'Sản phẩm',
addon: {
component: 'imports/AddProductForm',
width: '90%',
height: 'auto',
title: 'Thêm sản phẩm',
},
}"
@number="selected('price', $event)"
@option="selected('product', $event)"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Màu sắc</label>
<SearchBox
v-bind="{
api: 'color',
field: 'name',
column: ['name'],
first: true,
placeholder: 'Màu sắc',
}"
@option="selected('color', $event)"
/>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Đơn giá</label>
<div class="control">
<InputNumber
v-bind="{
record: body,
attr: 'price',
placeholder: 'Đơn giá',
unit: 'VND',
}"
@number="selected('price', $event)"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Màu sắc</label>
<SearchBox
v-bind="{
api: 'color',
field: 'name',
column: ['name'],
first: true,
placeholder: 'Màu sắc',
addon: {
component: 'imports/addons/AddColor',
width: '60%',
height: 'auto',
title: 'Thêm màu sắc',
},
}"
@option="selected('color', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">RAM</label>
<SearchBox
v-bind="{
api: 'RAM',
field: 'code',
column: ['code'],
first: true,
placeholder: 'RAM',
addon: {
component: 'imports/addons/AddRAM',
width: '60%',
height: 'auto',
title: 'Thêm RAM',
},
}"
@option="selected('ram', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Bộ nhớ trong</label>
<SearchBox
v-bind="{
api: 'Internal_Storage',
field: 'code',
column: ['code'],
first: true,
placeholder: 'Bộ nhớ trong',
addon: {
component: 'imports/addons/AddInternalStorage',
width: '60%',
height: 'auto',
title: 'Thêm bộ nhớ trong',
},
}"
@option="selected('internal_storage', $event)"
/>
</div>
</div>
<div class="cell is-col-span-12">
<div class="field">
<label class="label">Ghi chú</label>
<textarea
v-model.trim="body.note"
class="textarea"
name="note"
placeholder="Ghi chú"
rows="1"
></textarea>
</div>
</div>
<div class="cell is-col-span-12">
<button
:class="['button is-primary', { 'is-loading': isPending }]"
:disabled="Object.values(body).every((v) => v === null)"
@click.prevent="createProductVariant"
>
<span class="icon">
<Icon name="material-symbols:add-2-rounded" />
</span>
<span>Thêm phiên bản</span>
</button>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">RAM</label>
<SearchBox
v-bind="{
api: 'RAM',
field: 'code',
column: ['code'],
first: true,
placeholder: 'RAM',
}"
@option="selected('ram', $event)"
/>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Bộ nhớ trong</label>
<SearchBox
v-bind="{
api: 'internalstorage',
field: 'code',
column: ['code'],
first: true,
placeholder: 'Bộ nhớ trong',
}"
@option="selected('internal_storage', $event)"
/>
</div>
</div>
<div class="cell is-col-span-12">
<div class="field">
<label class="label">Ghi chú</label>
<textarea
v-model.trim="body.note"
class="textarea"
name="note"
placeholder="Ghi chú"
rows="2"
></textarea>
</div>
</div>
<div class="cell is-col-span-12">
<button
:class="['button is-primary', { 'is-loading': isPending }]"
:disabled="Object.values(body).every((v) => v === null)"
@click.prevent="createProductVariant"
>
Thêm phiên bản
</button>
</div>
</div>
</form>
</form>
</div>
</template>

View File

@@ -17,6 +17,6 @@ import FileUpload from "@/components/media/FileUpload.vue";
</template>
<span class="font-medium">Import</span>
</FileUpload>
<AddProductVariantForm />
<AddProductForm />
<AddProductVariantForm />
</template>

View File

@@ -0,0 +1,71 @@
<script setup>
const { $empty, $insertapi } = useNuxtApp();
const isLoading = ref(false);
const body = ref({
code: null,
battery_type: null,
capacity: null,
});
async function submit() {
isLoading.value = true;
await $insertapi("Battery", body.value);
isLoading.value = false;
}
</script>
<template>
<form class="fixed-grid has-12-cols">
<div class="grid">
<div class="cell is-col-span-4">
<div class="field">
<label class="label"></label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.code"
placeholder="Mã"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Loại pin</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.battery_type"
placeholder="Loại pin"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Dung lượng</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.capacity"
placeholder="Dung lượng"
/>
</div>
</div>
</div>
<div class="cell is-col-span-12">
<button
@click.prevent="submit"
:disabled="Object.values(body).every($empty)"
:class="['button is-primary', { 'is-loading': isLoading }]"
>
Thêm
</button>
</div>
</div>
</form>
</template>

View File

@@ -0,0 +1,71 @@
<script setup>
const { $empty, $insertapi } = useNuxtApp();
const isLoading = ref(false);
const body = ref({
code: null,
name: null,
core_count: null,
});
async function submit() {
isLoading.value = true;
await $insertapi("CPU", body.value);
isLoading.value = false;
}
</script>
<template>
<form class="fixed-grid has-12-cols">
<div class="grid">
<div class="cell is-col-span-4">
<div class="field">
<label class="label"></label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.code"
placeholder="Mã"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Tên</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.name"
placeholder="Tên"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Số lõi</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.core_count"
placeholder="Số lõi"
/>
</div>
</div>
</div>
<div class="cell is-col-span-12">
<button
@click.prevent="submit"
:disabled="Object.values(body).every($empty)"
:class="['button is-primary', { 'is-loading': isLoading }]"
>
Thêm
</button>
</div>
</div>
</form>
</template>

View File

@@ -0,0 +1,71 @@
<script setup>
const { $empty, $insertapi } = useNuxtApp();
const isLoading = ref(false);
const body = ref({
code: null,
rear_camera_specs: null,
front_camera_specs: null,
});
async function submit() {
isLoading.value = true;
await $insertapi("Camera_System", body.value);
isLoading.value = false;
}
</script>
<template>
<form class="fixed-grid has-12-cols">
<div class="grid">
<div class="cell is-col-span-6">
<div class="field">
<label class="label"></label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.code"
placeholder="Mã"
/>
</div>
</div>
</div>
<div class="cell is-col-span-6">
<div class="field">
<label class="label">Camera sau</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.rear_camera_specs"
placeholder="Camera sau"
/>
</div>
</div>
</div>
<div class="cell is-col-span-6">
<div class="field">
<label class="label">Camera trước</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.front_camera_specs"
placeholder="Camera trước"
/>
</div>
</div>
</div>
<div class="cell is-col-span-12">
<button
@click.prevent="submit"
:disabled="Object.values(body).every($empty)"
:class="['button is-primary', { 'is-loading': isLoading }]"
>
Thêm
</button>
</div>
</div>
</form>
</template>

View File

@@ -0,0 +1,71 @@
<script setup>
const { $empty, $insertapi } = useNuxtApp();
const isLoading = ref(false);
const body = ref({
code: null,
port: null,
technologies: null,
});
async function submit() {
isLoading.value = true;
await $insertapi("Charging_Technology", body.value);
isLoading.value = false;
}
</script>
<template>
<form class="fixed-grid has-12-cols">
<div class="grid">
<div class="cell is-col-span-4">
<div class="field">
<label class="label"></label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.code"
placeholder="Mã"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Cổng</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.port"
placeholder="Cổng"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Công nghệ</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.technologies"
placeholder="Công nghệ"
/>
</div>
</div>
</div>
<div class="cell is-col-span-12">
<button
@click.prevent="submit"
:disabled="Object.values(body).every($empty)"
:class="['button is-primary', { 'is-loading': isLoading }]"
>
Thêm
</button>
</div>
</div>
</form>
</template>

View File

@@ -0,0 +1,71 @@
<script setup>
const { $empty, $insertapi } = useNuxtApp();
const isLoading = ref(false);
const body = ref({
code: null,
name: null,
hex_code: null,
});
async function submit() {
isLoading.value = true;
await $insertapi("Color", body.value);
isLoading.value = false;
}
</script>
<template>
<form class="fixed-grid has-12-cols">
<div class="grid">
<div class="cell is-col-span-4">
<div class="field">
<label class="label"></label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.code"
placeholder="Mã"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Tên</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.name"
placeholder="Tên"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Hex Code</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.hex_code"
placeholder="e.g. #f27a90"
/>
</div>
</div>
</div>
<div class="cell is-col-span-12">
<button
@click.prevent="submit"
:disabled="Object.values(body).every($empty)"
:class="['button is-primary', { 'is-loading': isLoading }]"
>
Thêm
</button>
</div>
</div>
</form>
</template>

View File

@@ -0,0 +1,71 @@
<script setup>
const { $empty, $insertapi } = useNuxtApp();
const isLoading = ref(false);
const body = ref({
code: null,
frame_material: null,
back_material: null,
});
async function submit() {
isLoading.value = true;
await $insertapi("Design", body.value);
isLoading.value = false;
}
</script>
<template>
<form class="fixed-grid has-12-cols">
<div class="grid">
<div class="cell is-col-span-4">
<div class="field">
<label class="label"></label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.code"
placeholder="Mã"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Khung</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.frame_material"
placeholder="Khung"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Lưng</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.back_material"
placeholder="Lưng"
/>
</div>
</div>
</div>
<div class="cell is-col-span-12">
<button
@click.prevent="submit"
:disabled="Object.values(body).every($empty)"
:class="['button is-primary', { 'is-loading': isLoading }]"
>
Thêm
</button>
</div>
</div>
</form>
</template>

View File

@@ -0,0 +1,60 @@
<script setup>
const { $empty, $insertapi } = useNuxtApp();
const isLoading = ref(false);
const body = ref({
code: null,
max_capacity: null,
});
async function submit() {
isLoading.value = true;
await $insertapi("External_Storage", body.value);
isLoading.value = false;
}
</script>
<template>
<form class="fixed-grid has-12-cols">
<div class="grid">
<div class="cell is-col-span-6">
<div class="field">
<label class="label"></label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.code"
placeholder="Mã"
/>
</div>
</div>
</div>
<div class="cell is-col-span-6">
<div class="field">
<label class="label">Dung lượng max</label>
<div class="control">
<InputNumber
v-bind="{
record: body,
attr: 'max_capacity',
placeholder: 'Dung lượng max',
unit: 'GB',
}"
@number="(num) => (body.max_capacity = num)"
/>
</div>
</div>
</div>
<div class="cell is-col-span-12">
<button
@click.prevent="submit"
:disabled="Object.values(body).every($empty)"
:class="['button is-primary', { 'is-loading': isLoading }]"
>
Thêm
</button>
</div>
</div>
</form>
</template>

View File

@@ -0,0 +1,57 @@
<script setup>
const { $empty, $insertapi } = useNuxtApp();
const isLoading = ref(false);
const body = ref({
code: null,
name: null,
});
async function submit() {
isLoading.value = true;
await $insertapi("GPU", body.value);
isLoading.value = false;
}
</script>
<template>
<form class="fixed-grid has-12-cols">
<div class="grid">
<div class="cell is-col-span-6">
<div class="field">
<label class="label"></label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.code"
placeholder="Mã"
/>
</div>
</div>
</div>
<div class="cell is-col-span-6">
<div class="field">
<label class="label">Tên</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.name"
placeholder="Tên"
/>
</div>
</div>
</div>
<div class="cell is-col-span-12">
<button
@click.prevent="submit"
:disabled="Object.values(body).every($empty)"
:class="['button is-primary', { 'is-loading': isLoading }]"
>
Thêm
</button>
</div>
</div>
</form>
</template>

View File

@@ -0,0 +1,57 @@
<script setup>
const { $empty, $insertapi } = useNuxtApp();
const isLoading = ref(false);
const body = ref({
code: null,
name: null,
});
async function submit() {
isLoading.value = true;
await $insertapi("IP_Rating", body.value);
isLoading.value = false;
}
</script>
<template>
<form class="fixed-grid has-12-cols">
<div class="grid">
<div class="cell is-col-span-6">
<div class="field">
<label class="label"></label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.code"
placeholder="Mã"
/>
</div>
</div>
</div>
<div class="cell is-col-span-6">
<div class="field">
<label class="label">Tên</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.name"
placeholder="Tên"
/>
</div>
</div>
</div>
<div class="cell is-col-span-12">
<button
@click.prevent="submit"
:disabled="Object.values(body).every($empty)"
:class="['button is-primary', { 'is-loading': isLoading }]"
>
Thêm
</button>
</div>
</div>
</form>
</template>

View File

@@ -0,0 +1,62 @@
<script setup>
import InputNumber from "@/components/common/InputNumber.vue";
const { $empty, $insertapi } = useNuxtApp();
const isLoading = ref(false);
const body = ref({
code: null,
capacity: null,
});
async function submit() {
isLoading.value = true;
await $insertapi("Internal_Storage", body.value);
isLoading.value = false;
}
</script>
<template>
<form class="fixed-grid has-12-cols">
<div class="grid">
<div class="cell is-col-span-6">
<div class="field">
<label class="label"></label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.code"
placeholder="Mã"
/>
</div>
</div>
</div>
<div class="cell is-col-span-6">
<div class="field">
<label class="label">Dung lượng</label>
<div class="control">
<InputNumber
v-bind="{
record: body,
attr: 'capacity',
placeholder: 'Dung lượng',
unit: 'GB',
}"
@number="(num) => (body.capacity = num)"
/>
</div>
</div>
</div>
<div class="cell is-col-span-12">
<button
@click.prevent="submit"
:disabled="Object.values(body).every($empty)"
:class="['button is-primary', { 'is-loading': isLoading }]"
>
Thêm
</button>
</div>
</div>
</form>
</template>

View File

@@ -0,0 +1,57 @@
<script setup>
const { $empty, $insertapi } = useNuxtApp();
const isLoading = ref(false);
const body = ref({
code: null,
name: null,
});
async function submit() {
isLoading.value = true;
await $insertapi("Manufacturer", body.value);
isLoading.value = false;
}
</script>
<template>
<form class="fixed-grid has-12-cols">
<div class="grid">
<div class="cell is-col-span-6">
<div class="field">
<label class="label"></label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.code"
placeholder="Mã"
/>
</div>
</div>
</div>
<div class="cell is-col-span-6">
<div class="field">
<label class="label">Tên</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.name"
placeholder="Tên"
/>
</div>
</div>
</div>
<div class="cell is-col-span-12">
<button
@click.prevent="submit"
:disabled="Object.values(body).every($empty)"
:class="['button is-primary', { 'is-loading': isLoading }]"
>
Thêm
</button>
</div>
</div>
</form>
</template>

View File

@@ -0,0 +1,57 @@
<script setup>
const { $empty, $insertapi } = useNuxtApp();
const isLoading = ref(false);
const body = ref({
code: null,
name: null,
});
async function submit() {
isLoading.value = true;
await $insertapi("Network_Technology", body.value);
isLoading.value = false;
}
</script>
<template>
<form class="fixed-grid has-12-cols">
<div class="grid">
<div class="cell is-col-span-6">
<div class="field">
<label class="label"></label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.code"
placeholder="Mã"
/>
</div>
</div>
</div>
<div class="cell is-col-span-6">
<div class="field">
<label class="label">Tên</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.name"
placeholder="Tên"
/>
</div>
</div>
</div>
<div class="cell is-col-span-12">
<button
@click.prevent="submit"
:disabled="Object.values(body).every($empty)"
:class="['button is-primary', { 'is-loading': isLoading }]"
>
Thêm
</button>
</div>
</div>
</form>
</template>

View File

@@ -0,0 +1,71 @@
<script setup>
const { $empty, $insertapi } = useNuxtApp();
const isLoading = ref(false);
const body = ref({
code: null,
name: null,
version: null,
});
async function submit() {
isLoading.value = true;
await $insertapi("OS", body.value);
isLoading.value = false;
}
</script>
<template>
<form class="fixed-grid has-12-cols">
<div class="grid">
<div class="cell is-col-span-4">
<div class="field">
<label class="label"></label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.code"
placeholder="Mã"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Tên</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.name"
placeholder="Tên"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Phiên bản</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.version"
placeholder="Phiên bản"
/>
</div>
</div>
</div>
<div class="cell is-col-span-12">
<button
@click.prevent="submit"
:disabled="Object.values(body).every($empty)"
:class="['button is-primary', { 'is-loading': isLoading }]"
>
Thêm
</button>
</div>
</div>
</form>
</template>

View File

@@ -0,0 +1,62 @@
<script setup>
import InputNumber from "@/components/common/InputNumber.vue";
const { $empty, $insertapi } = useNuxtApp();
const isLoading = ref(false);
const body = ref({
code: null,
capacity: null,
});
async function submit() {
isLoading.value = true;
await $insertapi("RAM", body.value);
isLoading.value = false;
}
</script>
<template>
<form class="fixed-grid has-12-cols">
<div class="grid">
<div class="cell is-col-span-6">
<div class="field">
<label class="label"></label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.code"
placeholder="Mã"
/>
</div>
</div>
</div>
<div class="cell is-col-span-6">
<div class="field">
<label class="label">Dung lượng</label>
<div class="control">
<InputNumber
v-bind="{
record: body,
attr: 'capacity',
placeholder: 'Dung lượng',
unit: 'GB',
}"
@number="(num) => (body.capacity = num)"
/>
</div>
</div>
</div>
<div class="cell is-col-span-12">
<button
@click.prevent="submit"
:disabled="Object.values(body).every($empty)"
:class="['button is-primary', { 'is-loading': isLoading }]"
>
Thêm
</button>
</div>
</div>
</form>
</template>

View File

@@ -0,0 +1,75 @@
<script setup>
import InputNumber from "@/components/common/InputNumber.vue";
const { $empty, $insertapi } = useNuxtApp();
const isLoading = ref(false);
const body = ref({
code: null,
sim_count: null,
sim_types: null,
});
async function submit() {
isLoading.value = true;
await $insertapi("SIM", body.value);
isLoading.value = false;
}
</script>
<template>
<form class="fixed-grid has-12-cols">
<div class="grid">
<div class="cell is-col-span-4">
<div class="field">
<label class="label"></label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.code"
placeholder="Mã"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Số lượng SIM</label>
<div class="control">
<InputNumber
v-bind="{
record: body,
attr: 'sim_count',
placeholder: 'Số lượng SIM',
}"
@number="(num) => (body.sim_count = num)"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Loại SIM</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.sim_types"
placeholder="Loại SIM"
/>
</div>
</div>
</div>
<div class="cell is-col-span-12">
<button
@click.prevent="submit"
:disabled="Object.values(body).every($empty)"
:class="['button is-primary', { 'is-loading': isLoading }]"
>
Thêm
</button>
</div>
</div>
</form>
</template>

View File

@@ -0,0 +1,141 @@
<script setup>
const { $empty, $insertapi } = useNuxtApp();
const isLoading = ref(false);
const body = ref({
code: null,
technology: null,
standard: null,
size: null,
resolution: null,
max_brightness: null,
refresh_rate: null,
screen_type: null,
});
async function submit() {
isLoading.value = true;
await $insertapi("Screen", body.value);
isLoading.value = false;
}
</script>
<template>
<form class="fixed-grid has-12-cols">
<div class="grid">
<div class="cell is-col-span-4">
<div class="field">
<label class="label"></label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.code"
placeholder="Mã"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Công nghệ màn hình</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.technology"
placeholder="Công nghệ màn hình"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Tiêu chuẩn</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.standard"
placeholder="Tiêu chuẩn"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Kích thước</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.size"
placeholder="Kích thước"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Độ phân giải</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.resolution"
placeholder="Độ phân giải"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Độ sáng tối đa</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.max_brightness"
placeholder="Độ sáng tối đa"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Tần số quét</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.refresh_rate"
placeholder="Tần số quét"
/>
</div>
</div>
</div>
<div class="cell is-col-span-4">
<div class="field">
<label class="label">Loại màn hình</label>
<div class="control">
<input
type="text"
class="input"
v-model.trim="body.screen_type"
placeholder="Loại màn hình"
/>
</div>
</div>
</div>
<div class="cell is-col-span-12">
<button
@click.prevent="submit"
:disabled="Object.values(body).every($empty)"
:class="['button is-primary', { 'is-loading': isLoading }]"
>
Thêm
</button>
</div>
</div>
</form>
</template>

View File

@@ -1092,7 +1092,7 @@ export default defineNuxtPlugin((nuxtApp) => {
},
},
{
name: "internalstorage",
name: "Internal_Storage",
url: "data/Internal_Storage/",
url_detail: "data-detail/Internal_Storage/",
params: {

View File

@@ -7,7 +7,22 @@ import POS from "@/components/pos/POS.vue";
import CreateReceipts from "@/components/receipts/CreateReceipts.vue";
import Return from "@/components/receipts/Return.vue";
import Imports from "@/components/imports/Imports.vue";
import AddOS from "@/components/imports/AddOS.vue";
import AddOS from "@/components/imports/addons/AddOS.vue";
import AddManufacturer from "@/components/imports/addons/AddManufacturer.vue";
import AddBattery from "@/components/imports/addons/AddBattery.vue";
import AddScreen from "@/components/imports/addons/AddScreen.vue";
import AddCPU from "@/components/imports/addons/AddCPU.vue";
import AddGPU from "@/components/imports/addons/AddGPU.vue";
import AddCamera from "@/components/imports/addons/AddCamera.vue";
import AddSIM from "@/components/imports/addons/AddSIM.vue";
import AddNetworkTechnology from "@/components/imports/addons/AddNetworkTechnology.vue";
import AddChargingTechnology from "@/components/imports/addons/AddChargingTechnology.vue";
import AddExternalStorage from "@/components/imports/addons/AddExternalStorage.vue";
import AddIPRating from "@/components/imports/addons/AddIPRating.vue";
import AddDesign from "@/components/imports/addons/AddDesign.vue";
import AddColor from "@/components/imports/addons/AddColor.vue";
import AddRAM from "@/components/imports/addons/AddRAM.vue";
import AddInternalStorage from "@/components/imports/addons/AddInternalStorage.vue";
import Returns from "@/components/imports/Returns.vue";
import Exports from "@/components/exports/Exports.vue";
import ExportsDamaged from "@/components/exports/ExportsDamaged.vue";
@@ -147,6 +162,21 @@ const components = {
Return,
Imports,
AddOS,
AddManufacturer,
AddBattery,
AddScreen,
AddCPU,
AddGPU,
AddCamera,
AddSIM,
AddNetworkTechnology,
AddChargingTechnology,
AddExternalStorage,
AddIPRating,
AddDesign,
AddColor,
AddRAM,
AddInternalStorage,
Returns,
Exports,
ExportsDamaged,