halaman view permission

This commit is contained in:
2025-06-30 11:09:10 +07:00
parent be4de9f24a
commit 8176411cfe
84 changed files with 5572 additions and 16 deletions

View File

@@ -0,0 +1,159 @@
<script setup>
import { computed, nextTick, ref, watch } from 'vue';
import UiParentCard from '@/components/shared/UiParentCard.vue';
import { Icon } from '@iconify/vue';
import dummy from '@/data/dummy/keuangan.type_user.json'
const search = ref();
const dialog = ref(false)
const dialogDelete = ref(false)
const headers = ref([
// {
// no:'No',
// title: 'Dessert (100g serving)',
// align: 'start',
// sortable: false,
// key: 'name',
// },
{ title: 'No', key: 'no' },
{ title: 'typeUser', key: 'typeUser' },
{ title: 'Actions', key: 'actions', sortable: false },
])
const Roles = ref([])
const editedIndex = ref(-1)
const editedItem = ref({
typeUser:'',
})
const defaultItem = ref({
typeUser: '',
})
const formTitle = computed(() => {
return editedIndex.value === -1 ? 'New Roles' : 'Edit Roles'
})
function initialize() {
Roles.value = dummy
}
function editItem(item) {
editedIndex.value = Roles.value.indexOf(item)
editedItem.value = Object.assign({}, item)
dialog.value = true
}
function deleteItem(item) {
editedIndex.value = Roles.value.indexOf(item)
editedItem.value = Object.assign({}, item)
dialogDelete.value = true
}
function deleteItemConfirm() {
Roles.value.splice(editedIndex.value, 1)
closeDelete()
}
function close() {
dialog.value = false
nextTick(() => {
editedItem.value = Object.assign({}, defaultItem.value)
editedIndex.value = -1
})
}
function closeDelete() {
dialogDelete.value = false
nextTick(() => {
editedItem.value = Object.assign({}, defaultItem.value)
editedIndex.value = -1
})
}
function save() {
if (editedIndex.value > -1) {
Object.assign(Roles.value[editedIndex.value], editedItem.value)
} else {
Roles.value.push(editedItem.value)
}
close()
}
watch(dialog, val => {
val || close()
})
watch(dialogDelete, val => {
val || closeDelete()
})
initialize()
</script>
<template>
<!-- <pre>{{ dummy }}</pre> -->
<v-row>
<v-col cols="12">
<!-- <UiParentCard title="Crud Table"> -->
<v-text-field v-model="search" append-inner-icon="mdi-magnify" label="Search" single-line hide-details
class="mb-5" />
<v-data-table class="border rounded-md datatabels" :headers="headers" :items="Roles" :search="search" :sort-by="[{ key: 'typeUser', order: 'asc' }]">
<template v-slot:top>
<v-toolbar class="bg-lightprimary" flat>
<v-toolbar-title>My Crud Table</v-toolbar-title>
<v-divider class="mx-4" inset vertical></v-divider>
<v-spacer></v-spacer>
<!-- dialog create & update -->
<v-btn color="primary" variant="flat" dark @click="dialog = true">Add New Item</v-btn>
<UiComponents2DialogsScrollable v-model="dialog">
<template v-slot:title>
{{ formTitle }}
</template>
<template v-slot:text>
<v-container class="px-0">
<v-row>
<v-col cols="12" sm="6" md="4">
<v-text-field v-model="editedItem.typeUser"
label="typeUser"></v-text-field>
</v-col>
</v-row>
</v-container>
</template>
<template v-slot:actions>
<v-btn color="error" variant="tonal" @click="close">
Cancel
</v-btn>
<v-btn color="success" variant="tonal" @click="save">
Save
</v-btn>
</template>
</UiComponents2DialogsScrollable>
<!-- dialog delete -->
<UiComponents2DialogsActivator v-model="dialogDelete">
<template v-slot:text>Are you sure you want to delete this item?</template>
<template v-slot:actions>
<v-btn color="error" variant="flat" dark @click="closeDelete">Cancel</v-btn>
<v-btn color="primary" variant="flat" dark @click="deleteItemConfirm">OK</v-btn>
</template>
</UiComponents2DialogsActivator>
</v-toolbar>
</template>
<template v-slot:item.no="{ index }">{{ index + 1 }}</template>
<template v-slot:item.actions="{ item }">
<div class="d-flex gap-3">
<Icon
icon="solar:pen-new-square-broken"
height="20"
class="text-primary cursor-pointer"
size="small"
@click="editItem(item)"
/>
<Icon
icon="solar:trash-bin-minimalistic-linear"
height="20"
class="text-error cursor-pointer"
size="small"
@click="deleteItem(item)"
/>
</div>
</template>
<template v-slot:no-data>
<v-btn color="primary" @click="initialize">
Reset
</v-btn>
</template>
</v-data-table>
<!-- </UiParentCard> -->
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,209 @@
<script setup lang="ts">
import { ref, onMounted, computed } from "vue";
import { HeartIcon, UsersIcon, TrashIcon } from "vue-tabler-icons";
import BaseBreadcrumb from "@/components/shared/BaseBreadcrumb.vue";
// import { useFrinedsStore } from '@/stores/apps/userprofile/friends';
import UserCards from "@/components/widgets2/cards/UserCards.vue";
import data from "@/data/dummy/keuangan.type_user.json";
import { toast } from "vue3-toastify";
import "vue3-toastify/dist/index.css";
import Form from "@/components/Setting/ViewPermission/Form.vue";
import { Icon } from "@iconify/vue";
import { useSettingStore } from "~/store/apps/Setting/setting";
import { toastAlert } from "@/composable/index";
const store = useSettingStore();
const dialog = ref(false);
const dialogDelete = ref(false);
const editedIndex = ref(-1);
const editedItem = ref({});
const defaultItem = ref({});
const permissionCategories = [
{
value: "0",
label: "General",
},
{
value: "1",
label: "ProductServce",
},
{
value: "2",
label: "Product",
},
];
const formTitle = computed(() => {
return editedIndex.value === -1 ? "New Item" : "Edit Item";
});
const typeForm = computed(() => {
return editedIndex.value === -1 ? "create" : "edit";
});
const getData: any = computed(() => {
return data;
});
const searchValue = ref("");
const filteredCards = computed(() => {
return getData.value.filter((card: any) => {
return card.typeUser
.toLowerCase()
.includes(searchValue.value.toLowerCase());
});
});
const findData = (item: string) => {
return permissionCategories.find((data) => data.value === item);
};
function editItem(item: any) {
editedIndex.value = filteredCards.value.indexOf(item);
store.getTypeUser(item);
dialog.value = true;
console.log("ini dialog:", dialog.value);
}
function deleteItem(item: any) {
editedIndex.value = filteredCards.value.indexOf(item);
dialogDelete.value = true;
}
function deleteItemConfirm() {
filteredCards.value.splice(editedIndex.value, 1);
closeDelete();
toastAlert("Berhasil hapus data!", "success");
}
function closeDelete() {
dialogDelete.value = false;
}
function saveData(data: object) {
//proses simpan data edit
if (editedIndex.value > -1) {
Object.assign(filteredCards.value[editedIndex.value], data.data);
toastAlert("Berhasil ubah data!", "success");
//proses simpan data create
} else {
filteredCards.value.push(data.data);
toastAlert("Berhasil simpan data!", "success");
}
dialog.value = false;
}
</script>
<template>
<!-- <pre>{{ filteredCards }}</pre> -->
<v-row class="justify-content-end mt-5">
<v-col cols="12">
<div class="d-sm-flex justify-end mb-2">
<v-btn
color="primary"
variant="flat"
dark
@click="
dialog = true;
editedIndex = -1;
"
>+ Type User</v-btn
>
</div>
<div class="d-sm-flex align-center mb-5">
<h3 class="text-h3">
Type User
<v-chip
size="small"
class="ml-2 elevation-0"
variant="elevated"
color="secondary"
>{{ getData.length }}</v-chip
>
</h3>
<v-sheet width="250" class="ml-0 ml-sm-auto mt-3 mt-sm-0">
<v-text-field
color="primary"
hide-details
variant="outlined"
placeholder="Search Friends"
density="compact"
prepend-inner-icon="mdi-magnify"
v-model="searchValue"
>
</v-text-field>
</v-sheet>
</div>
<!-- card list -->
<UserCards :data="filteredCards">
<template v-slot:avatar="data">
<Icon icon="solar:user-circle-broken" height="32" width="80" />
</template>
<template v-slot:title="data">
<!-- {{ data.prop.title }} -->
{{ data.prop.typeUser }}
</template>
<template v-slot:left-side-content="data">
<li
class="text-subtitle-1 text-textSecondary mr-2"
style="list-style-type: none"
v-for="(item, i) in data.prop.roleMenu"
:key="i"
>
{{ findData(item.permission)?.label }}
</li>
</template>
<template v-slot:right-side-content="data">
<v-chip size="small" color="secondary">{{
data.prop.roleMenu.length
}}</v-chip>
</template>
<template v-slot:actions="data">
<v-btn
color="secondary"
variant="tonal"
block
@click="editItem(data.prop)"
>Edit Type User</v-btn
>
<v-btn
color="error"
variant="tonal"
class="mt-3"
block
@click="deleteItem(data.prop)"
>Remove</v-btn
>
</template>
</UserCards>
<!-- dialog create & update -->
<UiComponents2DialogsScrollable v-model="dialog">
<template v-slot:title>
<div class="d-flex justify-space-between">
{{ formTitle }}
<v-btn @click="dialog = false">X</v-btn>
</div>
</template>
<template v-slot:text>
<Form :typeForm="typeForm" @stateValue="saveData" />
</template>
</UiComponents2DialogsScrollable>
<!-- dialog delete -->
<UiComponents2DialogsActivator v-model="dialogDelete">
<template v-slot:text
>Are you sure you want to delete this item?</template
>
<template v-slot:actions>
<v-btn color="error" variant="flat" dark @click="closeDelete"
>Cancel</v-btn
>
<v-btn color="primary" variant="flat" dark @click="deleteItemConfirm"
>OK</v-btn
>
</template>
</UiComponents2DialogsActivator>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,99 @@
<script setup>
import { ref, reactive } from "vue";
import permission from "@/components/Setting/ViewPermission/element/selectElement.vue";
import menuRoles from "@/components/Setting/ViewPermission/element/table.vue";
import { useSettingStore } from "~/store/apps/Setting/setting";
const store = useSettingStore();
const props = defineProps({
typeForm:{
type:String
}
})
const emit = defineEmits(['stateValue']);
const permissionCategories = [
{
value: "0",
label: "General",
},
{
value: "1",
label: "ProductServce",
},
{
value: "2",
label: "Product",
},
];
const form = ref({});
const data = ref(null);
const ready = ref(false);
const onSubmit = () => {
console.log(data.value.form$.data);
emit('stateValue', {data:data.value.form$.data, state:false})
};
onBeforeMount(() => {
console.log("props:",props.typeForm)
if(props.typeForm === "edit")
Object.assign(form.value, store.typeUser);
// console.log(form)
});
</script>
<template>
<!-- <pre>{{ form }}</pre> -->
<Vueform
ref="data"
v-model="form"
validate-on="change|step"
method="post"
:endpoint="onSubmit"
>
<template #empty>
<FormSteps>
<FormStep
name="page0"
label="Type User"
:elements="['typeUser', 'roleType']"
/>
<FormStep
name="page1"
label="Permission Categories"
:elements="['text', 'tab', 'gridTable', 'roleMenu', 'permission']"
/>
</FormSteps>
<FormElements>
<ListElement name="roleMenu" :default="form.roleMenu" class="mx-4" add-text="+ permission">
<template #default="{ index }">
<ObjectElement :name="index" class="px-3 py-3 border border-gray-200 rounded-xl">
<permission name="permission" :items="permissionCategories"/>
<div class="vf-element-layout vf-col-12">
<!-- <menuRoles name="gridTable" :items="form.roleMenu[index] != null ? form.roleMenu[index]: []"/> -->
<menuRoles name="gridTable" :items="props.typeForm === 'edit' ? form.roleMenu[index]: []"/>
</div>
</ObjectElement>
</template>
</ListElement>
<TextElement
:default="form.typeUser"
name="typeUser"
label="Role Name"
:columns="{
container: 6,
}"
/>
<TextElement
:default="form.typeUser"
name="roleType"
label="Role Type"
:columns="{
container: 6,
}"
/>
</FormElements>
<FormStepsControls />
</template>
</Vueform>
</template>

View File

@@ -0,0 +1,20 @@
<script setup>
const props = defineProps({
items:{
type:Array
}
})
</script>
<template>
<SelectElement
:items="props.items"
:search="true"
:native="false"
label="Permission Category"
input-type="search"
autocomplete="off"
:columns="{
container: 5,
}"
/>
</template>

View File

@@ -0,0 +1,97 @@
<script setup>
const props = defineProps({
items: {
type: Array,
default: [],
},
});
</script>
<template>
<!-- {{ props.items }} -->
<!-- <h1>Coba</h1> -->
<div class="overflow-x-auto" style="min-height: 300px">
<!-- <v-card style="width: 100%" class="py-3 px-3"> -->
<ListElement
:default="props.items.menu"
name="menu"
add-text="+ module"
:sort="true"
wrapper-class="flex flex-col items-center gap-4"
add-class="bg-green-500 text-white w-10 h-10 flex items-center justify-center rounded-full"
>
<template #default="{ index }">
<ObjectElement :name="index">
<div class="vf-element-layout vf-col-12">
<v-table style="min-width: 100%">
<thead v-if="index === 0">
<tr>
<th class="text-h6 ps-6">Module</th>
<!-- <th class="text-h6">Create</th>
<th class="text-h6">Update</th>
<th class="text-h6">Delete</th>
<th class="text-h6">Show</th> -->
</tr>
</thead>
<tbody>
<!-- <tr v-for="(item,index) in props.items.menu" :key="index" name="menu"> -->
<tr>
<!-- <td>{{item}}</td> -->
<td>
<TextElement name="Module" placeholder="Module" :columns="{
container: 6,
}" />
</td>
<td>
<CheckboxElement
name="create"
text="create"
:columns="{
container: 6,
}"
trueValue="true"
falseValue="false"
/>
</td>
<td>
<CheckboxElement
name="update"
text="update"
:columns="{
container: 6,
}"
trueValue="true"
falseValue="false"
/>
</td>
<td>
<CheckboxElement
name="delete"
text="delete"
:columns="{
container: 6,
}"
trueValue="true"
falseValue="false"
/>
</td>
<td>
<CheckboxElement
name="show"
text="show"
:columns="{
container: 6,
}"
trueValue="true"
falseValue="false"
/>
</td>
</tr>
</tbody>
</v-table>
</div>
</ObjectElement>
</template>
</ListElement>
<!-- </v-card> -->
</div>
</template>

View File

@@ -0,0 +1,232 @@
<script setup lang="ts">
import { ref, onMounted, computed } from "vue";
import { HeartIcon, UsersIcon, TrashIcon } from "vue-tabler-icons";
import BaseBreadcrumb from "@/components/shared/BaseBreadcrumb.vue";
// import { useFrinedsStore } from '@/stores/apps/userprofile/friends';
import UserCards from "@/components/widgets2/cards/UserCards.vue";
import { userCards } from "~/_mockApis/components/widget/card";
import { toast } from "vue3-toastify";
import "vue3-toastify/dist/index.css";
// const store = useFrinedsStore();
// onMounted(() => {
// store.fetchFrineds();
// });
const dialog = ref(false);
const dialogDelete = ref(false);
const editedIndex = ref(-1);
const editedItem = ref({});
const defaultItem = ref({});
const formTitle = computed(() => {
return editedIndex.value === -1 ? "New Item" : "Edit Item";
});
const getData: any = computed(() => {
// return store.friends;
return userCards;
});
const searchValue = ref("");
const filteredCards = computed(() => {
return getData.value.filter((card: any) => {
return card.title.toLowerCase().includes(searchValue.value.toLowerCase());
});
});
function editItem(item: any) {
editedIndex.value = filteredCards.value.indexOf(item);
editedItem.value = Object.assign({}, item);
dialog.value = true;
}
function deleteItem(item: any) {
editedIndex.value = filteredCards.value.indexOf(item);
editedItem.value = Object.assign({}, item);
dialogDelete.value = true;
}
function deleteItemConfirm() {
filteredCards.value.splice(editedIndex.value, 1);
closeDelete();
toast("Berhasil hapus data!", {
type: "success",
dangerouslyHTMLString: true,
autoClose: 2000,
});
}
function close() {
dialog.value = false;
nextTick(() => {
editedItem.value = Object.assign({}, defaultItem.value);
editedIndex.value = -1;
});
}
function closeDelete() {
dialogDelete.value = false;
nextTick(() => {
editedItem.value = Object.assign({}, defaultItem.value);
editedIndex.value = -1;
});
}
function save() {
if (editedIndex.value > -1) {
Object.assign(filteredCards.value[editedIndex.value], editedItem.value);
toast("Berhasil ubah data!", {
type: "success",
dangerouslyHTMLString: true,
autoClose: 2000,
});
} else {
filteredCards.value.push(editedItem.value);
toast("Berhasil simpan data!", {
type: "success",
dangerouslyHTMLString: true,
autoClose: 2000,
});
}
close();
}
watch(dialog, (val) => {
val || close();
});
watch(dialogDelete, (val) => {
val || closeDelete();
});
</script>
<template>
<v-row class="justify-content-end mt-5">
<v-col cols="12">
<div class="d-sm-flex justify-end mb-2">
<v-btn color="primary" variant="flat" dark @click="dialog = true"
>+ New Item</v-btn
>
</div>
<div class="d-sm-flex align-center mb-5">
<h3 class="text-h3">
Social Media Contacts
<v-chip
size="small"
class="ml-2 elevation-0"
variant="elevated"
color="secondary"
>4</v-chip
>
</h3>
<v-sheet width="250" class="ml-0 ml-sm-auto mt-3 mt-sm-0">
<v-text-field
color="primary"
hide-details
variant="outlined"
placeholder="Search Friends"
density="compact"
prepend-inner-icon="mdi-magnify"
v-model="searchValue"
>
</v-text-field>
</v-sheet>
</div>
<!-- card list -->
<UserCards :data="filteredCards">
<template v-slot:avatar="data">
<img :src="data.prop.avatar" :alt="data.prop.avatar" width="80" />
</template>
<template v-slot:title="data">
{{ data.prop.title }}
</template>
<template v-slot:left-side-content="data">
<v-avatar
size="32"
class="ml-n2 avtar-border"
v-for="user in data.prop.userGroup"
:key="user.icon"
>
<img :src="user.icon" alt="avatar" height="32" />
</v-avatar>
</template>
<template v-slot:right-side-content="data">
<p class="text-subtitle-1 textSecondary">{{ data.prop.subtitle }}</p>
</template>
<template v-slot:actions="data">
<v-btn
color="secondary"
variant="tonal"
block
@click="editItem(data.prop)"
>Edit Friend</v-btn
>
<v-btn
color="error"
variant="tonal"
class="mt-3"
block
@click="deleteItem(data.prop)"
>Remove</v-btn
>
</template>
</UserCards>
<!-- dialog create & update -->
<UiComponents2DialogsScrollable v-model="dialog">
<template v-slot:title>{{ formTitle }}</template>
<template v-slot:text>
<!-- <pre>{{ editedItem }}</pre> -->
<v-container class="px-0">
<v-row>
<v-col cols="12" sm="6" md="6">
<v-text-field
v-model="editedItem.title"
label="Name"
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="6">
<v-text-field
v-model="editedItem.subtitle"
label="Subtitle"
disabled
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="12">
<h5 class="text-h6 mb-8">Media</h5>
<v-file-input
color="primary"
label="Drop files here or click to upload."
placeholder="Select your files"
prepend-icon="mdi-paperclip"
variant="outlined"
chips
multiple
></v-file-input>
</v-col>
</v-row>
</v-container>
</template>
<template v-slot:actions>
<v-btn color="error" variant="tonal" @click="close"> Cancel </v-btn>
<v-btn color="success" variant="tonal" @click="save"> Save </v-btn>
</template>
</UiComponents2DialogsScrollable>
<!-- dialog delete -->
<UiComponents2DialogsActivator v-model="dialogDelete">
<template v-slot:text
>Are you sure you want to delete this item?</template
>
<template v-slot:actions>
<v-btn color="error" variant="flat" dark @click="closeDelete"
>Cancel</v-btn
>
<v-btn color="primary" variant="flat" dark @click="deleteItemConfirm"
>OK</v-btn
>
</template>
</UiComponents2DialogsActivator>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,280 @@
<script setup>
import { computed, nextTick, ref, watch } from "vue";
import UiParentCard from "@/components/shared/UiParentCard.vue";
import { Icon } from "@iconify/vue";
const search = ref();
const dialog = ref(false);
const dialogDelete = ref(false);
const headers = ref([
{
title: "Dessert (100g serving)",
align: "start",
sortable: false,
key: "name",
},
{ title: "Calories", key: "calories" },
{ title: "Fat (g)", key: "fat" },
{ title: "Carbs (g)", key: "carbs" },
{ title: "Protein (g)", key: "protein" },
{ title: "Actions", key: "actions", sortable: false },
]);
const desserts = ref([]);
const editedIndex = ref(-1);
const editedItem = ref({
name: "",
calories: 0,
fat: 0,
carbs: 0,
protein: 0,
});
const defaultItem = ref({
name: "",
calories: 0,
fat: 0,
carbs: 0,
protein: 0,
});
const formTitle = computed(() => {
return editedIndex.value === -1 ? "New Item" : "Edit Item";
});
function initialize() {
desserts.value = [
{
name: "Frozen Yogurt",
calories: 159,
fat: 6,
carbs: 24,
protein: 4,
},
{
name: "Ice cream sandwich",
calories: 237,
fat: 9,
carbs: 37,
protein: 4.3,
},
{
name: "Eclair",
calories: 262,
fat: 16,
carbs: 23,
protein: 6,
},
{
name: "Cupcake",
calories: 305,
fat: 3.7,
carbs: 67,
protein: 4.3,
},
{
name: "Gingerbread",
calories: 356,
fat: 16,
carbs: 49,
protein: 3.9,
},
{
name: "Jelly bean",
calories: 375,
fat: 0,
carbs: 94,
protein: 0,
},
{
name: "Lollipop",
calories: 392,
fat: 0.2,
carbs: 98,
protein: 0,
},
{
name: "Honeycomb",
calories: 408,
fat: 3.2,
carbs: 87,
protein: 6.5,
},
{
name: "Donut",
calories: 452,
fat: 25,
carbs: 51,
protein: 4.9,
},
{
name: "KitKat",
calories: 518,
fat: 26,
carbs: 65,
protein: 7,
},
];
}
function editItem(item) {
editedIndex.value = desserts.value.indexOf(item);
editedItem.value = Object.assign({}, item);
dialog.value = true;
}
function deleteItem(item) {
editedIndex.value = desserts.value.indexOf(item);
editedItem.value = Object.assign({}, item);
dialogDelete.value = true;
}
function deleteItemConfirm() {
desserts.value.splice(editedIndex.value, 1);
closeDelete();
}
function close() {
dialog.value = false;
nextTick(() => {
editedItem.value = Object.assign({}, defaultItem.value);
editedIndex.value = -1;
});
}
function closeDelete() {
dialogDelete.value = false;
nextTick(() => {
editedItem.value = Object.assign({}, defaultItem.value);
editedIndex.value = -1;
});
}
function save() {
if (editedIndex.value > -1) {
Object.assign(desserts.value[editedIndex.value], editedItem.value);
} else {
desserts.value.push(editedItem.value);
}
close();
}
watch(dialog, (val) => {
val || close();
});
watch(dialogDelete, (val) => {
val || closeDelete();
});
initialize();
</script>
<template>
<v-row>
<v-col cols="12">
<!-- <UiParentCard title="Crud Table"> -->
<v-text-field
v-model="search"
append-inner-icon="mdi-magnify"
label="Search"
single-line
hide-details
class="mb-5"
/>
<v-data-table
class="border rounded-md datatabels"
:headers="headers"
:items="desserts"
:search="search"
:sort-by="[{ key: 'calories', order: 'asc' }]"
>
<template v-slot:top>
<v-toolbar class="bg-lightprimary" flat>
<v-toolbar-title>My Crud Table</v-toolbar-title>
<v-divider class="mx-4" inset vertical></v-divider>
<v-spacer></v-spacer>
<!-- dialog create & update -->
<v-btn color="primary" variant="flat" dark @click="dialog = true"
>Add New Item</v-btn
>
<UiComponents2DialogsScrollable v-model="dialog">
<template v-slot:title> coba </template>
<template v-slot:text>
<v-container class="px-0">
<v-row>
<v-col cols="12" sm="6" md="4">
<v-text-field
v-model="editedItem.name"
label="Dessert name"
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field
v-model="editedItem.calories"
label="Calories"
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field
v-model="editedItem.fat"
label="Fat (g)"
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field
v-model="editedItem.carbs"
label="Carbs (g)"
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field
v-model="editedItem.protein"
label="Protein (g)"
></v-text-field>
</v-col>
</v-row>
</v-container>
</template>
<template v-slot:actions>
<v-btn color="error" variant="tonal" @click="close">
Cancel
</v-btn>
<v-btn color="success" variant="tonal" @click="save">
Save
</v-btn>
</template>
</UiComponents2DialogsScrollable>
<!-- dialog delete -->
<UiComponents2DialogsActivator v-model="dialogDelete">
<template v-slot:text
>Are you sure you want to delete this item?</template
>
<template v-slot:actions>
<v-btn color="error" variant="flat" dark @click="closeDelete"
>Cancel</v-btn
>
<v-btn
color="primary"
variant="flat"
dark
@click="deleteItemConfirm"
>OK</v-btn
>
</template>
</UiComponents2DialogsActivator>
</v-toolbar>
</template>
<template v-slot:item.actions="{ item }">
<div class="d-flex gap-3">
<Icon
icon="solar:pen-new-square-broken"
height="20"
class="text-primary cursor-pointer"
size="small"
@click="editItem(item)"
/>
<Icon
icon="solar:trash-bin-minimalistic-linear"
height="20"
class="text-error cursor-pointer"
size="small"
@click="deleteItem(item)"
/>
</div>
</template>
<template v-slot:no-data>
<v-btn color="primary" @click="initialize"> Reset </v-btn>
</template>
</v-data-table>
<!-- </UiParentCard> -->
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,114 @@
<script setup lang="ts">
import { ref, computed } from 'vue';
// import { useEcomStore } from '@/stores/apps/eCommerce';
// import StepFirst from './steps/StepFirst.vue';
// import StepSecond from './steps/StepSecond.vue';
// import Payment from './steps/Payment.vue';
import Thankyou from '@/components/app/table/steps/Thankyou.vue';
import { BasketIcon } from 'vue-tabler-icons';
import Table1 from '~/components/table/Table1.vue';
// const store = useEcomStore();
const thankyou = ref(false);
const getCart = computed(() => {
// return store.cart;
});
const tab = ref('tab-1');
function changeTab(e: string) {
tab.value = e;
}
</script>
<template>
<v-card elevation="0">
<v-card-item>
<v-tabs v-model="tab" color="primary" class="customTab">
<v-tab value="tab-1" rounded="md" class="mb-3 text-left me-4" height="70">
<span class="round-40 rounded-circle bg-grey100 d-flex justify-center align-center me-3 icon">
<BasketIcon stroke-width="1.5" width="20" />
</span>
<div>
<div class="text-h6">Item Cart</div>
<span class="text-subtitle-2 textSecondary font-weight-medium d-block"
>Product Summary</span
>
</div>
</v-tab>
<v-tab value="tab-2" rounded="md" class="mb-3 text-left me-4" height="70" >
<span class="round-40 rounded-circle bg-grey100 d-flex justify-center align-center me-3 icon">
<FileDescriptionIcon stroke-width="1.5" width="20" />
</span>
<div>
<div class="text-h6">Billing</div>
<span class="text-subtitle-2 textSecondary font-weight-medium d-block">
Billing Information
</span>
</div>
</v-tab>
<v-tab value="tab-3" rounded="md" class="mb-3 text-left" height="70" >
<span class="round-40 rounded-circle bg-grey100 d-flex justify-center align-center me-3 icon">
<CreditCardIcon stroke-width="1.5" width="20" />
</span>
<div>
<div class="text-h6">Payment</div>
<span class="text-subtitle-2 textSecondary font-weight-medium d-block">
Add & Update Card
</span>
</div>
</v-tab>
</v-tabs>
<v-window v-model="tab">
<v-window-item value="tab-1" class="pa-1">
<Table1 />
<v-row class="mt-3">
<v-col cols="12" sm="6">
<v-btn color="primary" variant="tonal" to="/ecommerce/products">Continue Shopping</v-btn>
</v-col>
<v-col cols="12" sm="6" class="text-sm-right">
<v-btn color="primary" @click="changeTab('tab-2')">CheckOut</v-btn>
</v-col>
</v-row>
</v-window-item>
<v-window-item value="tab-2" class="pa-1" >
<!-- <Table1 /> -->
<v-row class="mt-3">
<v-col cols="6">
<v-btn color="primary" variant="tonal" @click="changeTab('tab-1')">Back</v-btn>
</v-col>
<v-col cols="6" class="text-right">
<v-btn color="primary" @click="changeTab('tab-3')">Place an Order</v-btn>
</v-col>
</v-row>
</v-window-item>
<v-window-item value="tab-3" class="pa-1">
<!-- <Table1 /> -->
<v-row class="mt-3">
<v-col cols="12" sm="6">
<v-btn color="primary" variant="tonal" @click="changeTab('tab-2')">Back</v-btn>
</v-col>
<v-col cols="12" sm="6" class="text-sm-right">
<v-btn color="primary" @click="thankyou = true">Complete an Order</v-btn>
<!-- Modal -->
<v-dialog v-model="thankyou" max-width="750">
<Thankyou />
</v-dialog>
</v-col>
</v-row>
</v-window-item>
</v-window>
</v-card-item>
</v-card>
</template>
<style lang="scss">
.customTab {
min-height: 68px;
}
</style>

View File

@@ -0,0 +1,301 @@
<script setup lang="ts">
import { ref, onMounted, computed, watch } from "vue";
// import { useTicketstore } from "@/stores/apps/tickets";
// import { format } from "date-fns";
import { Icon } from "@iconify/vue";
import user3 from '@/assets/images/profile/user-3.jpg';
import TicketData from "@/data/dummy/ticket.json";
// const store = useTicketstore();
// Fetch tickets and ensure tickets are available
onMounted(async () => {
// await store.fetchTicket();
console.log("Fetched tickets:", getTickets.value);
setTicketType(TicketTypeVal.value);
});
// Get tickets from the store
const getTickets = computed(() =>
// store.ticket
TicketData
);
let FinalTickets = ref([...getTickets.value]);
const searchValue = ref("");
const TicketTypeVal = ref("total");
// Create New Ticket
const showCreateTicketModal = ref(false);
const newTicket = ref({ title: "", description: "", usernm: "Liam" });
const createTicket = () => {
if (
newTicket.value.title &&
newTicket.value.description &&
newTicket.value.usernm
) {
const newId = getTickets.value.length + 1;
const newTicketData = {
Id: newId,
ticketTitle: newTicket.value.title,
ticketDescription: newTicket.value.description,
AgentName: newTicket.value.usernm,
Label: "success",
Status: "Open",
Date: new Date().toISOString(),
thumb: user3,
};
// store.addTicket(newTicketData);
setTicketType("total");
newTicket.value.title = "";
newTicket.value.description = "";
showCreateTicketModal.value = false;
}
};
// Function to set the ticket type and filter based on status
const setTicketType = (type: string) => {
TicketTypeVal.value = type;
console.log(`TicketTypeVal changed to: ${type}`);
if (TicketTypeVal.value === "total") {
FinalTickets.value = [...getTickets.value];
} else {
FinalTickets.value = getTickets.value.filter((ticket) => {
console.log("Filtering ticket:", ticket);
return (
ticket.Status &&
ticket.Status.toLowerCase() === TicketTypeVal.value.toLowerCase()
);
});
}
applySearchFilter();
};
// Function to apply search filter to tickets
const applySearchFilter = () => {
if (searchValue.value) {
FinalTickets.value = FinalTickets.value.filter((ticket) =>
ticket.ticketTitle
?.toLowerCase()
.includes(searchValue.value.toLowerCase())
);
}
};
watch(searchValue, applySearchFilter);
const totalTicketCount = computed(() => getTickets.value.length);
const pendingTicketCount = computed(
() => getTickets.value.filter((ticket) => ticket.Status === "Pending").length
);
const openTicketCount = computed(
() => getTickets.value.filter((ticket) => ticket.Status === "Open").length
);
const closedTicketCount = computed(
() => getTickets.value.filter((ticket) => ticket.Status === "Closed").length
);
const handleDeleteTicket = (ticketId: number) => {
// store.deleteTicket(ticketId);
setTicketType(TicketTypeVal.value);
};
</script>
<template>
<v-card elevation="10">
<v-card-item>
<div class="overflow-x-reposive">
<v-row class="d-flex flex-nowrap">
<v-col cols="10" md="3" sm="6">
<div
class="bg-lightprimary pa-7 text-center cursor-pointer rounded-md"
@click="setTicketType('total')"
>
<h2 class="text-primary text-24">{{ totalTicketCount }}</h2>
<h6 class="text-primary text-h6">Total Tickets</h6>
</div>
</v-col>
<v-col cols="10" md="3" sm="6">
<div
class="bg-lightwarning pa-7 text-center cursor-pointer rounded-md"
@click="setTicketType('Pending')"
>
<h2 class="text-warning text-24">{{ pendingTicketCount }}</h2>
<h6 class="text-warning text-h6">Pending Tickets</h6>
</div>
</v-col>
<v-col cols="10" md="3" sm="6">
<div
class="bg-lightsuccess pa-7 text-center cursor-pointer rounded-md"
@click="setTicketType('Open')"
>
<h2 class="text-success text-24">{{ openTicketCount }}</h2>
<h6 class="text-success text-h6">Open Tickets</h6>
</div>
</v-col>
<v-col cols="10" md="3" sm="6">
<div
class="bg-lighterror pa-7 text-center cursor-pointer rounded-md"
@click="setTicketType('Closed')"
>
<h2 class="text-error text-24">{{ closedTicketCount }}</h2>
<h6 class="text-error text-h6">Closed Tickets</h6>
</div>
</v-col>
</v-row>
</div>
<div class="">
<div class="d-sm-flex justify-space-between align-center my-7">
<v-btn color="primary" @click="showCreateTicketModal = true"
>Create Ticket</v-btn
>
<v-sheet width="255" class="mt-lg-0 mt-4">
<v-text-field
v-model="searchValue"
label="Search Invoice"
variant="outlined"
hide-details
class="w-100"
density="compact"
>
<template v-slot:prepend-inner>
<Icon icon="solar:magnifer-linear" height="18" width="25" />
</template>
</v-text-field>
</v-sheet>
</div>
<!-- Render filtered tickets -->
<v-table class="ticket-table">
<template v-slot:default>
<thead>
<tr>
<th class="text-h6 text-no-wrap ">Id</th>
<th class="text-h6 text-no-wrap">Ticket</th>
<th class="text-h6 text-no-wrap">Assigned To</th>
<th class="text-h6 text-no-wrap">Status</th>
<th class="text-h6 text-no-wrap">Date</th>
<th class="text-h6 text-no-wrap">Action</th>
</tr>
</thead>
<tbody>
<tr
v-for="ticket in FinalTickets"
:key="ticket.Id"
@click="store.SelectTicket(ticket.Id)"
v-if="FinalTickets.length > 0"
>
<td class="text-body-1">
{{ ticket.Id }}
</td>
<td>
<h6 class="text-h6">{{ ticket.ticketTitle }}</h6>
<p
style="max-width: 280px"
class="text-body-1 text-muted text-truncate"
>
{{ ticket.ticketDescription }}
</p>
</td>
<td>
<div class="d-flex ga-2 align-center">
<v-avatar size="40">
<img :src="ticket.thumb" :alt="ticket.thumb" width="40"
/></v-avatar>
<h6 class="text-h6 text-no-wrap">{{ ticket.AgentName }}</h6>
</div>
</td>
<td>
<v-chip
rounded="sm"
class="font-weight-bold"
:color="ticket.Label"
size="small"
label
>{{ ticket.Status }}</v-chip
>
</td>
<td>
<p class="text-muted text-body-1 text-no-wrap">
<!-- {{
ticket?.Date
? format(new Date(ticket.Date), "E, MMM d")
: "N/A"
}} -->
{{ ticket?.Date }}
</p>
</td>
<td class="text-center">
<v-btn
icon
color="lighterror"
class="mx-auto"
size="x-small"
@click.stop="handleDeleteTicket(ticket.Id)"
>
<v-tooltip activator="parent" location="top"
>Delete Ticket</v-tooltip
>
<Icon
icon="solar:trash-bin-minimalistic-linear" class="text-error"
height="18"
/>
</v-btn>
</td>
</tr>
</tbody>
</template>
</v-table>
</div>
</v-card-item>
</v-card>
<!-- Add Ticket -->
<!-- Create Ticket Modal -->
<v-dialog v-model="showCreateTicketModal" max-width="500px">
<v-card>
<v-card-title class="pa-4 bg-primary">Create New Ticket</v-card-title>
<v-card-text>
<v-form>
<v-text-field
label="Ticket Title"
v-model="newTicket.title"
required
></v-text-field>
<v-textarea
label="Ticket Description"
v-model="newTicket.description"
rows="4"
required
></v-textarea>
<v-select
label="Assign To"
v-model="newTicket.usernm"
:items="['Liam', 'Steve', 'Jack', 'Wiliam', 'Dona']"
variant="outlined"
required
></v-select>
</v-form>
</v-card-text>
<v-card-actions class="ga-3">
<v-btn
color="error"
variant="flat"
@click="showCreateTicketModal = false"
>Cancel</v-btn
>
<v-btn color="primary" variant="flat" @click="createTicket"
>Create</v-btn
>
</v-card-actions>
</v-card>
</v-dialog>
</template>

View File

@@ -0,0 +1,25 @@
<script setup lang="ts">
import { ref } from 'vue';
import completed from '@/assets/images/products/payment-complete.svg';
</script>
<template>
<v-card>
<v-card-item class="py-8 text-center">
<h3 class="text-h3">Thank you for order!</h3>
<p class="text-medium-emphasis mt-3 mb-2">We will send a process notification, before it delivered.</p>
<p>Your order id: <span class="text-primary">dff796c4-1a08-5768-97e3-bd65d98b1559</span></p>
<div class="text-center">
<img :src="completed" alt="Thankyou" class="my-6" width="250" />
</div>
<small class="text-medium-emphasis"
>If you have any query or questions regarding purchase items, then fell to get in contact us</small
><br />
<span class="text-error">(555) 492-2175</span>
<div class="d-sm-flex align-center justify-center gap-3 mt-5 mb-5">
<v-btn color="primary" variant="tonal" to="/ecommerce/products">Continue to Shopping</v-btn>
<v-btn color="primary" class="mt-4 mt-sm-0">Download Invoice</v-btn>
</div>
</v-card-item>
</v-card>
</template>

View File

@@ -63,7 +63,7 @@ watch(priority, (newPriority) => {
</div>
<ThemeToggler />
<!-- <ThemeToggler /> -->
<!-- ---------------------------------------------- -->
<!-- translate -->

View File

@@ -44,6 +44,16 @@ const MiniSideIcons: minisidebar[] = [
icon:'mirror-left-line-duotone',
tooltip:'Others',
id: 8
},
{
icon:'settings-line-duotone',
tooltip:'Settings',
id: 9
},
{
icon:'notes-line-duotone',
tooltip:'App',
id: 10
}
]

View File

@@ -225,7 +225,7 @@ const sidebarItem: menu[] = [
{
title: 'Cards Widgets',
icon: 'cardholder-line-duotone',
to: '/widgets/cards'
to: '/widgets/cards/cards'
},
{
title: 'Charts Widgets',
@@ -393,32 +393,32 @@ const sidebarItem: menu[] = [
{
title: 'Basic Table',
icon: 'tablet-line-duotone',
to: '/tables/basic'
to: '/tables/tablebasic'
},
{
title: 'Dark Table',
icon: 'bedside-table-4-outline',
to: '/tables/dark'
to: '/tables/tabledark'
},
{
title: 'Density Table',
icon: 'bedside-table-3-linear',
to: '/tables/density'
to: '/tables/tabledensity'
},
{
title: 'Fixed Header Table',
icon: 'archive-up-minimlistic-broken',
to: '/tables/fixed-header'
to: '/tables/tableheaderfixed'
},
{
title: 'Height Table',
icon: 'archive-down-minimlistic-broken',
to: '/tables/height'
to: '/tables/tableheight'
},
{
title: 'Editable Table',
icon: 'document-add-linear',
to: '/tables/editable'
to: '/tables/tableeditable'
}
]
},
@@ -430,22 +430,22 @@ const sidebarItem: menu[] = [
{
title: 'Basic Table',
icon: 'database-outline',
to: '/tables/datatables/basic'
to: '/tables/datatables/basictable'
},
{
title: 'Header Table',
icon: 'folder-open-broken',
to: '/tables/datatables/header'
to: '/tables/datatables/headertables'
},
{
title: 'Selection Table',
icon: 'chart-square-broken',
to: '/tables/datatables/selection'
to: '/tables/datatables/selectable'
},
{
title: 'Sorting Table',
icon: 'card-send-line-duotone',
to: '/tables/datatables/sorting'
to: '/tables/datatables/sortingtable'
},
{
title: 'Pagination Table',
@@ -524,7 +524,22 @@ const sidebarItem: menu[] = [
{
title: 'Alert',
icon: 'info-circle-linear',
to: '/ui-components/alert'
to: '/ui-components/alerts'
},
{
title: 'Buttons',
icon: 'info-circle-linear',
to: '/ui-components/buttons'
},
{
title: 'Cards',
icon: 'info-circle-linear',
to: '/ui-components/cards'
},
{
title: 'Tables',
icon: 'info-circle-linear',
to: '/ui-components/tables'
},
{
title: 'Accordion',
@@ -539,12 +554,12 @@ const sidebarItem: menu[] = [
{
title: 'Chip',
icon: 'tag-horizontal-line-duotone',
to: '/ui-components/chip'
to: '/ui-components/uichip'
},
{
title: 'Dialog',
icon: 'bolt-line-duotone',
to: '/ui-components/dialogs'
to: '/ui-components/uidialog'
},
{
title: 'List',
@@ -703,6 +718,48 @@ const sidebarItem: menu[] = [
BgColor: 'success'
}
]
},
{
header: 'Settings',
id: 9,
children: [
{
title: 'Tipe Pengguna',
icon: 'check-circle-bold',
to: '/setting/tipepengguna/'
},
{
title: 'view permisson',
icon: 'check-circle-bold',
to: '/setting/viewpermission/'
},
]
},
{
header: 'Examples',
id: 10,
children: [
{
title: 'card list',
icon: 'table-line-duotone',
to: '/app/cardList'
},
{
title: 'CRUD table',
icon: 'table-line-duotone',
to: '/app/table'
},
{
title: 'step form',
icon: 'table-line-duotone',
to: '/app/table/StepTable'
},
{
title: 'CRUD table with steps',
icon: 'table-line-duotone',
to: '/app/table/StepTable2'
},
]
}
];

View File

@@ -0,0 +1,43 @@
<script setup >
import { Icon } from '@iconify/vue';
const props = defineProps({
title: String,
breadcrumbs: Array ,
icon: String,
text: String
});
</script>
<template>
<v-card elevation="10" class="mb-8">
<div class="px-6 py-4">
<div class="d-flex justify-space-between align-center">
<h5 class="text-h5">{{ title }}</h5>
<v-breadcrumbs :items="breadcrumbs" class="pa-0">
<template v-slot:prepend>
<router-link to="/" class="textSecondary lh-0">
<Icon icon="solar:home-2-line-duotone" height="20" />
</router-link>
</template>
<template v-slot:divider>
<div class="d-flex align-center textSecondary "></div>
</template>
<template v-slot:title="{ item }">
<v-chip size="small" class="rounded-sm" color="primary" >{{ item.text }}</v-chip>
</template>
</v-breadcrumbs>
</div>
</div>
</v-card>
</template>
<style lang="scss">
.page-breadcrumb {
.v-toolbar {
background: transparent;
}
}
</style>

View File

@@ -0,0 +1,221 @@
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
import { useContactStore } from '@/stores/apps/contact';
import user from '@/assets/images/profile/user-3.jpg';
import contact from '@/_mockApis/apps/contact';
const store = useContactStore();
onMounted(() => {
store.fetchContacts();
});
const getContacts: any = computed(() => {
return store.contacts;
});
const valid = ref(true);
const dialog = ref(false);
const search = ref('');
const rolesbg = ref(['primary', 'secondary', 'error', 'success', 'warning']);
const desserts = ref(contact);
const editedIndex = ref(-1);
const editedItem = ref({
id: '',
avatar: user,
userinfo: '',
usermail: '',
phone: '',
jdate: '',
role: '',
rolestatus: ''
});
const defaultItem = ref({
id: '',
avatar: user,
userinfo: '',
usermail: '',
phone: '',
jdate: '',
role: '',
rolestatus: ''
});
//Methods
const filteredList = computed(() => {
return desserts.value.filter((user: any) => {
return user.userinfo.toLowerCase().includes(search.value.toLowerCase());
});
});
function editItem(item: any) {
editedIndex.value = desserts.value.indexOf(item);
editedItem.value = Object.assign({}, item);
dialog.value = true;
}
function deleteItem(item: any) {
const index = desserts.value.indexOf(item);
confirm('Are you sure you want to delete this item?') && desserts.value.splice(index, 1);
}
function close() {
dialog.value = false;
setTimeout(() => {
editedItem.value = Object.assign({}, defaultItem.value);
editedIndex.value = -1;
}, 300);
}
function save() {
if (editedIndex.value > -1) {
Object.assign(desserts.value[editedIndex.value], editedItem.value);
} else {
desserts.value.push(editedItem.value);
}
close();
}
//Computed Property
const formTitle = computed(() => {
return editedIndex.value === -1 ? 'New Contact' : 'Edit Contact';
});
</script>
<template>
<v-row>
<v-col cols="12" lg="4" md="6">
<v-text-field density="compact" v-model="search" label="Search Contacts" hide-details variant="outlined"></v-text-field>
</v-col>
<v-col cols="12" lg="8" md="6" class="text-right">
<v-dialog v-model="dialog" max-width="500">
<template v-slot:activator="{ props }">
<v-btn color="primary" v-bind="props" flat class="ml-auto">
<v-icon class="mr-2">mdi-account-multiple-plus</v-icon>Add Contact
</v-btn>
</template>
<v-card>
<v-card-title class="pa-4 bg-primary">
<span class="title text-white">{{ formTitle }}</span>
</v-card-title>
<v-card-text>
<v-form ref="form" v-model="valid" lazy-validation>
<v-row>
<v-col cols="12" sm="6">
<v-text-field variant="outlined" hide-details v-model="editedItem.id" label="Id"></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
variant="outlined"
hide-details
v-model="editedItem.userinfo"
label="User info"
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
variant="outlined"
hide-details
v-model="editedItem.usermail"
label="User email"
type="email"
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
variant="outlined"
hide-details
v-model="editedItem.phone"
label="Phone"
type="phone"
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
variant="outlined"
hide-details
v-model="editedItem.jdate"
label="Joining Date"
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field variant="outlined" hide-details v-model="editedItem.role" label="Role"></v-text-field>
</v-col>
<v-col cols="12" sm="12">
<v-select
variant="outlined"
hide-details
:items="rolesbg"
v-model="editedItem.rolestatus"
label="Role Background"
></v-select>
</v-col>
</v-row>
</v-form>
</v-card-text>
<v-card-actions class="pa-4">
<v-spacer></v-spacer>
<v-btn color="error" variant="flat" @click="close">Cancel</v-btn>
<v-btn
color="primary"
:disabled="editedItem.userinfo == '' || editedItem.usermail == ''"
variant="flat"
@click="save"
>Save</v-btn
>
</v-card-actions>
</v-card>
</v-dialog>
</v-col>
</v-row>
<v-table class="mt-5">
<thead>
<tr>
<th class="text-body-1">Id</th>
<th class="text-body-1">UserInfo</th>
<th class="text-body-1">Phone</th>
<th class="text-body-1">Joining Date</th>
<th class="text-body-1">Role</th>
<th class="text-body-1">Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="item in filteredList" :key="item.id">
<td class="text-subtitle-1">{{ item.id }}</td>
<td>
<div class="d-flex align-center">
<div>
<v-img :src="item.avatar" width="45px" class="rounded-circle img-fluid"></v-img>
</div>
<div class="ml-5">
<h4 class="text-subtitle-1 text-no-wrap">{{ item.userinfo }}</h4>
<span class="text-subtitle-1 d-block mt-1 textSecondary">{{ item.usermail }}</span>
</div>
</div>
</td>
<td class="text-subtitle-1">{{ item.phone }}</td>
<td class="text-subtitle-1">{{ item.jdate }}</td>
<td>
<v-chip :color="item.rolestatus" size="small" rounded="sm" label>{{ item.role }}</v-chip>
</td>
<td>
<div class="d-flex align-center">
<v-tooltip text="Edit">
<template v-slot:activator="{ props }">
<v-btn icon flat @click="editItem(item)" v-bind="props"
><PencilIcon stroke-width="1.5" size="20" class="text-primary"
/></v-btn>
</template>
</v-tooltip>
<v-tooltip text="Delete">
<template v-slot:activator="{ props }">
<v-btn icon flat @click="deleteItem(item)" v-bind="props"
><TrashIcon stroke-width="1.5" size="20" class="text-error"
/></v-btn>
</template>
</v-tooltip>
</div>
</td>
</tr>
</tbody>
</v-table>
</template>

View File

@@ -0,0 +1,58 @@
<script setup lang="ts">
import {basicTableData1} from '@/_mockApis/components/table/basicTables';
</script>
<template>
<v-card class="border" elevation="0">
<v-table class="month-table">
<thead>
<tr>
<th class="text-h6 ps-6">Users</th>
<th class="text-h6">Project Name</th>
<th class="text-h6">Team</th>
<th class="text-h6">Status</th>
<th class="text-h6">Budget</th>
</tr>
</thead>
<tbody>
<tr v-for="item in basicTableData1" :key="item.name" class="month-item">
<td class="ps-6">
<div class="d-flex gap-3 align-center">
<v-avatar size="40">
<img :src="item.avatar" alt="avatar" height="40" />
</v-avatar>
<div>
<h6 class="text-h6">{{ item.name }}</h6>
<div class="textSecondary text-body-1">{{ item.post }}</div>
</div>
</div>
</td>
<td>
<p class="text-16 textPrimary">{{ item.pname }}</p>
</td>
<td>
<div class="d-flex align-center">
<div class="ml-2 d-flex flex-row-reverse">
<v-avatar
v-for="team in item.teams"
:key="team.id"
size="35"
:class="'ml-n2 avtar-border bg-' + team.color"
>
{{ team.text }}
</v-avatar>
</div>
</div>
</td>
<td>
<v-chip rounded="sm" class="font-weight-bold" :color="item.statuscolor" size="small" label>{{
item.status
}}</v-chip>
</td>
<td>
<h6 class="text-h6">{{ item.budget }}</h6>
</td>
</tr>
</tbody>
</v-table>
</v-card>
</template>

View File

@@ -0,0 +1,67 @@
<script setup lang="ts">
import {basicTableData2,tableActionData} from '@/_mockApis/components/table/basicTables';
</script>
<template>
<v-card elevation="0" class="mt-6 border">
<v-table class="month-table">
<thead>
<tr>
<th class="text-h6 ps-6">User</th>
<th class="text-h6">Project Name</th>
<th class="text-h6">Users</th>
<th class="text-h6">Status</th>
<th class="text-h6"></th>
</tr>
</thead>
<tbody>
<tr v-for="item in basicTableData2" :key="item.name" class="month-item">
<td class="ps-6">
<div class="d-flex gap-3 align-center">
<v-avatar size="40">
<img :src="item.avatar" alt="avatar" height="40" />
</v-avatar>
<h6 class="text-h6">{{ item.name }}</h6>
</div>
</td>
<td>
<div class="text-body-1 textPrimary">{{ item.post }}</div>
</td>
<td>
<div class="d-flex align-center">
<div class="ml-2 d-flex flex-row-reverse">
<v-avatar v-for="user in item.users" :key="user.id" size="40" class="ml-n2 avtar-border">
<img :src="user.icon" alt="avatar" height="40" />
</v-avatar>
</div>
</div>
</td>
<td>
<v-chip rounded="sm" class="font-weight-bold " :color="item.statuscolor" size="small">
{{ item.status }}
</v-chip>
</td>
<td>
<v-btn size="30" icon variant="flat" class="grey100">
<v-avatar size="22">
<DotsVerticalIcon size="20" color="grey100" />
</v-avatar>
<v-menu activator="parent">
<v-list>
<v-list-item value="action" v-for="list in tableActionData" :key="list.listtitle" hide-details min-height="38">
<v-list-item-title>
<v-avatar size="20" class="mr-2">
<component :is="list.icon" stroke-width="2" size="20" />
</v-avatar>
{{ list.listtitle }}
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-btn>
</td>
</tr>
</tbody>
</v-table>
</v-card>
</template>

View File

@@ -0,0 +1,92 @@
<script setup lang="ts">
import {basicTableData3,tableActionData} from '@/_mockApis/components/table/basicTables';
</script>
<template>
<v-card elevation="0" class="mt-6 border">
<v-table class="month-table">
<thead>
<tr>
<th class="text-h6 ps-6">Customer</th>
<th class="text-h6">Status</th>
<th class="text-h6">Email Address</th>
<th class="text-h6">Teams</th>
<th class="text-h6"></th>
</tr>
</thead>
<tbody>
<tr v-for="item in basicTableData3" :key="item.name" class="month-item">
<td class="ps-6">
<div class="d-flex gap-3 align-center">
<v-avatar size="40">
<img :src="item.avatar" alt="avatar" height="40" />
</v-avatar>
<div>
<h6 class="text-h6">{{ item.name }}</h6>
<div class="text-body-1 textSecondary">{{ item.handle }}</div>
</div>
</div>
</td>
<td>
<v-chip rounded="sm" v-if="item.statusoffline" class="font-weight-bold pl-1 pr-2" :color="item.statuscolor" size="small">
<ClockHour4Icon size="15" class="mr-1" />
{{ item.status }}
</v-chip>
<v-chip rounded="sm" v-else class="font-weight-bold pl-1 pr-2" :color="item.statuscolor" size="small">
<CircleIcon size="15" class="mr-1" />
{{ item.status }}
</v-chip>
</td>
<td>
<div class="text-subtitle-1 textPrimary">{{ item.email }}</div>
</td>
<td>
<div class="d-flex align-center">
<div class="d-flex">
<v-chip
v-for="team in item.teams"
:key="team.status"
rounded="sm"
:class="'font-weight-bold px-2 mr-2 bg-' + team.statuscolor"
size="small"
>
{{ team.status }}
</v-chip>
</div>
</div>
</td>
<td>
<v-btn size="30" icon variant="flat" class="grey100">
<v-avatar size="22">
<DotsIcon size="20" color="grey100" />
</v-avatar>
<v-menu activator="parent">
<v-list>
<v-list-item
value="action"
v-for="list in tableActionData"
:key="list.listtitle"
hide-details
min-height="38"
>
<v-list-item-title>
<v-avatar size="20" class="mr-2">
<component :is="list.icon" stroke-width="2" size="20" />
</v-avatar>
{{ list.listtitle }}
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-btn>
</td>
</tr>
</tbody>
</v-table>
</v-card>
</template>

View File

@@ -0,0 +1,73 @@
<script setup lang="ts">
import { basicTableData4, tableActionData } from '@/_mockApis/components/table/basicTables';
</script>
<template>
<v-card elevation="0" class="mt-6 border">
<v-table class="month-table">
<thead>
<tr>
<th class="text-h6 ps-6">Invoice</th>
<th class="text-h6">Status</th>
<th class="text-h6">Customer</th>
<th class="text-h6">Progress</th>
<th class="text-h6"></th>
</tr>
</thead>
<tbody>
<tr v-for="item in basicTableData4" :key="item.name" class="month-item">
<td class="ps-6">
<h6 class="text-subtitle-1">{{ item.invoice }}</h6>
</td>
<td>
<v-chip rounded="sm" class="font-weight-bold pl-1 pr-2" :color="item.statuscolor" size="small">
<component :is="item.statusicon" stroke-width="2" size="18" class="mr-1" />
{{ item.status }}
</v-chip>
</td>
<td>
<div class="d-flex gap-3 align-center">
<v-avatar size="40">
<img :src="item.avatar" alt="avatar" height="40" />
</v-avatar>
<div>
<h6 class="text-h6">{{ item.name }}</h6>
<div class="text-body-1 textSecondary">{{ item.handle }}</div>
</div>
</div>
</td>
<td>
<div class="d-flex align-center">
<div class="w-100">
<v-progress-linear color="primary" bg-color="light" rounded="sm"
:model-value="item.progress"></v-progress-linear>
</div>
<span class="text-subtitle-1 text-medium-emphasis ml-5">{{ item.progress }}%</span>
</div>
</td>
<td>
<v-btn size="30" icon variant="flat" class="grey100">
<v-avatar size="22">
<DotsVerticalIcon size="20" color="grey100" />
</v-avatar>
<v-menu activator="parent">
<v-list>
<v-list-item value="action" v-for="list in tableActionData" :key="list.listtitle"
hide-details min-height="38">
<v-list-item-title>
<v-avatar size="20" class="mr-2">
<component :is="list.icon" stroke-width="2" size="20" />
</v-avatar>
{{ list.listtitle }}
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-btn>
</td>
</tr>
</tbody>
</v-table>
</v-card>
</template>

View File

@@ -0,0 +1,77 @@
<script setup lang="ts">
import {basicTableData5,tableActionData} from '@/_mockApis/components/table/basicTables';
</script>
<template>
<v-card elevation="0" class="mt-6 border">
<v-table class="month-table">
<thead>
<tr>
<th class="text-h6 ps-6">Authors</th>
<th class="text-h6">Courses</th>
<th class="text-h6">Users</th>
<th class="text-h6"></th>
</tr>
</thead>
<tbody>
<tr v-for="item in basicTableData5" :key="item.name" class="month-item">
<td class="ps-6">
<div class="d-flex gap-3 align-center">
<v-avatar size="42" rounded="md">
<img :src="item.avatar" alt="avatar" height="42" />
</v-avatar>
<div>
<h6 class="text-subtitle-1">{{ item.name }}</h6>
<div class="text-body-1 textSecondary">{{ item.handle }}</div>
</div>
</div>
</td>
<td>
<div class="d-flex align-center">
<div class="d-flex">
<v-chip
v-for="course in item.courses"
:key="course.status"
rounded="sm"
class="mr-2"
:color="course.statuscolor"
size="small"
>
{{ course.status }}
</v-chip>
</div>
</div>
</td>
<td>
<div class="text-subtitle-1 text-medium-emphasis">{{ item.users }}</div>
</td>
<td>
<v-btn size="30" icon variant="flat" class="grey100">
<v-avatar size="22">
<DotsIcon size="20" color="grey100" />
</v-avatar>
<v-menu activator="parent">
<v-list>
<v-list-item
value="action"
v-for="list in tableActionData"
:key="list.listtitle"
hide-details
min-height="38"
>
<v-list-item-title>
<v-avatar size="20" class="mr-2">
<component :is="list.icon" stroke-width="2" size="20" />
</v-avatar>
{{ list.listtitle }}
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-btn>
</td>
</tr>
</tbody>
</v-table>
</v-card>
</template>

View File

@@ -0,0 +1,10 @@
<template>
<div class="d-flex flex-wrap align-center gap-3">
<v-chip closable color="primary"> Primary Deletable</v-chip>
<v-chip closable color="secondary"> Secondary Deletable</v-chip>
<v-chip closable color="warning"> Warning Deletable</v-chip>
<v-chip closable color="success"> Success Deletable</v-chip>
<v-chip closable color="error"> Error Deletable</v-chip>
<v-chip closable color="info"> Info Deletable</v-chip>
</div>
</template>

View File

@@ -0,0 +1,18 @@
<script setup lang="ts">
import { ref } from 'vue';
import { MoodSmileIcon,ChecksIcon,UserCircleIcon } from 'vue-tabler-icons';
</script>
<template>
<div class="d-flex flex-column flex-sm-row flex-wrap flex-xl-nowrap align-center gap-3">
<v-chip color="primary">
<MoodSmileIcon class="mr-2" start size="20" />
Custom Icon
<ChecksIcon class="ml-2" start size="20" />
</v-chip>
<v-chip color="secondary">
<UserCircleIcon class="mr-2" start size="20" />
Custom Icon
<ChecksIcon class="ml-2" start size="20" />
</v-chip>
</div>
</template>

View File

@@ -0,0 +1,18 @@
<script setup lang="ts">
import { ref } from 'vue';
import { MoodSmileIcon,ChecksIcon,UserCircleIcon } from 'vue-tabler-icons';
</script>
<template>
<div class="d-flex flex-column flex-sm-row flex-wrap flex-xl-nowrap align-center gap-3">
<v-chip color="primary" variant="outlined">
<MoodSmileIcon class="mr-2" start size="20" />
Custom Icon
<ChecksIcon class="ml-2" start size="20" />
</v-chip>
<v-chip color="secondary" variant="outlined">
<UserCircleIcon class="mr-2" start size="20" />
Custom Icon
<ChecksIcon class="ml-2" start size="20" />
</v-chip>
</div>
</template>

View File

@@ -0,0 +1,18 @@
<script setup lang="ts">
import { ref } from 'vue';
import { MoodSmileIcon,ChecksIcon,UserCircleIcon } from 'vue-tabler-icons';
</script>
<template>
<div class="d-flex flex-column flex-sm-row flex-wrap flex-xl-nowrap align-center gap-3">
<v-chip disabled variant="outlined">
<MoodSmileIcon class="mr-2" start size="20" />
Custom Icon
<ChecksIcon class="ml-2" start size="20" />
</v-chip>
<v-chip color="secondary" disabled variant="outlined">
<UserCircleIcon class="mr-2" start size="20" />
Custom Icon
<ChecksIcon class="ml-2" start size="20" />
</v-chip>
</div>
</template>

View File

@@ -0,0 +1,62 @@
<script setup lang="ts">
import { ref } from 'vue';
import { MoodSmileIcon, CircleXIcon } from 'vue-tabler-icons';
</script>
<template>
<div class="d-flex flex-wrap align-center gap-3">
<v-chip class="text-body-2">
<MoodSmileIcon class="mr-2" start size="20" /> Default Filled
</v-chip>
<v-chip class="text-body-2">
<MoodSmileIcon class="mr-2" start size="20" /> Default Deletable
<CircleXIcon class="ml-2" start size="20" />
</v-chip>
<v-chip color="primary" class="text-body-2">
<v-avatar start size="25">
<img src="@/assets/images/profile/user-6.jpg" width="25" />
</v-avatar> Primary Filled
</v-chip>
<v-chip color="primary" class="text-body-2">
<v-avatar start size="25">
<img src="@/assets/images/profile/user-6.jpg" width="25" />
</v-avatar> Primary Deletable
<CircleXIcon class="ml-2" start size="20" />
</v-chip>
<v-chip color="secondary" class="text-body-2">
<MoodSmileIcon class="mr-2" start size="20" /> Secondary Filled
</v-chip>
<v-chip color="secondary" class="text-body-2">
<MoodSmileIcon class="mr-2" start size="20" /> Secondary Deletable
<CircleXIcon class="ml-2" start size="20" />
</v-chip>
<v-chip color="success" class="text-body-2">
<v-avatar start size="25">
<img src="@/assets/images/profile/user-2.jpg" width="25" />
</v-avatar> Default Filled
</v-chip>
<v-chip color="success" class="text-body-2">
<v-avatar start size="25">
<img src="@/assets/images/profile/user-2.jpg" width="25" />
</v-avatar> Default Deletable
<CircleXIcon class="ml-2" start size="20" />
</v-chip>
<v-chip color="warning" class="text-body-2">
<MoodSmileIcon class="mr-2" start size="20" /> Default Filled
</v-chip>
<v-chip color="warning" class="text-body-2">
<MoodSmileIcon class="mr-2" start size="20" /> Default Deletable
<CircleXIcon class="ml-2" start size="20" />
</v-chip>
<v-chip color="error" class="text-body-2">
<v-avatar start size="25">
<img src="@/assets/images/profile/user-5.jpg" width="25" />
</v-avatar> Default Filled
</v-chip>
<v-chip color="error" class="text-body-2">
<v-avatar start size="25">
<img src="@/assets/images/profile/user-5.jpg" width="25" />
</v-avatar> Default Deletable
<CircleXIcon class="ml-2" start size="20" />
</v-chip>
</div>
</template>

View File

@@ -0,0 +1,9 @@
<template>
<div class="d-flex flex-column flex-sm-row flex-wrap flex-xl-nowrap align-center gap-3">
<v-chip label closable color="primary"> Primary </v-chip>
<v-chip label closable color="secondary"> Secondary </v-chip>
<v-chip label closable color="warning"> Warning </v-chip>
<v-chip label closable color="success"> Success </v-chip>
<v-chip label closable color="error"> Error </v-chip>
</div>
</template>

View File

@@ -0,0 +1,62 @@
<script setup lang="ts">
import { ref } from 'vue';
import { MoodSmileIcon, CircleXIcon } from 'vue-tabler-icons';
</script>
<template>
<div class="d-flex flex-wrap align-center gap-3">
<v-chip variant="outlined" class="text-body-2">
<MoodSmileIcon class="mr-2" start size="20" /> Default Filled
</v-chip>
<v-chip variant="outlined" class="text-body-2">
<MoodSmileIcon class="mr-2" start size="20" /> Default Deletable
<CircleXIcon class="ml-2" start size="20" />
</v-chip>
<v-chip variant="outlined" color="primary" class="text-body-2">
<v-avatar start size="25">
<img src="@/assets/images/profile/user-3.jpg" width="25" />
</v-avatar> Primary Filled
</v-chip>
<v-chip variant="outlined" color="primary" class="text-body-2">
<v-avatar start size="25">
<img src="@/assets/images/profile/user-3.jpg" width="25" />
</v-avatar> Primary Deletable
<CircleXIcon class="ml-2" start size="20" />
</v-chip>
<v-chip variant="outlined" color="secondary" class="text-body-2">
<MoodSmileIcon class="mr-2" start size="20" /> Secondary Filled
</v-chip>
<v-chip variant="outlined" color="secondary" class="text-body-2">
<MoodSmileIcon class="mr-2" start size="20" /> Secondary Deletable
<CircleXIcon class="ml-2" start size="20" />
</v-chip>
<v-chip variant="outlined" color="success" class="text-body-2">
<v-avatar start size="25">
<img src="@/assets/images/profile/user-2.jpg" width="25" />
</v-avatar> Default Filled
</v-chip>
<v-chip variant="outlined" color="success" class="text-body-2">
<v-avatar start size="25">
<img src="@/assets/images/profile/user-2.jpg" width="25" />
</v-avatar> Default Deletable
<CircleXIcon class="ml-2" start size="20" />
</v-chip>
<v-chip variant="outlined" color="warning" class="text-body-2">
<MoodSmileIcon class="mr-2" start size="20" /> Default Filled
</v-chip>
<v-chip variant="outlined" color="warning" class="text-body-2">
<MoodSmileIcon class="mr-2" start size="20" /> Default Deletable
<CircleXIcon class="ml-2" start size="20" />
</v-chip>
<v-chip variant="outlined" color="error" class="text-body-2">
<v-avatar start size="25">
<img src="@/assets/images/profile/user-5.jpg" width="25" />
</v-avatar> Default Filled
</v-chip>
<v-chip variant="outlined" color="error" class="text-body-2">
<v-avatar start size="25">
<img src="@/assets/images/profile/user-5.jpg" width="25" />
</v-avatar> Default Deletable
<CircleXIcon class="ml-2" start size="20" />
</v-chip>
</div>
</template>

View File

@@ -0,0 +1,9 @@
<template>
<div class="d-flex flex-column flex-sm-row flex-wrap flex-xl-nowrap align-center gap-3">
<v-chip color="primary" size="x-small"> x-small </v-chip>
<v-chip color="primary" size="small"> small </v-chip>
<v-chip color="primary"> Default </v-chip>
<v-chip color="primary" size="large"> large </v-chip>
<v-chip color="primary" size="x-large"> x-large </v-chip>
</div>
</template>

View File

@@ -0,0 +1,26 @@
<script setup lang="ts">
import { ref } from "vue";
const dialog = ref(false);
</script>
<template>
<div class="text-center mt-4 mt-sm-0">
<v-btn color="primary" class="w-100" flat>
Open Simple Dialog
<v-dialog v-model="dialog" activator="parent" class="dialog-mw">
<v-card>
<v-card-text>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
</v-card-text>
<v-card-actions>
<v-btn color="primary" @click="dialog = false" variant="tonal"
>Close Dialog</v-btn
>
</v-card-actions>
</v-card>
</v-dialog>
</v-btn>
</div>
</template>

View File

@@ -0,0 +1,92 @@
<script setup lang="ts">
import { ref } from "vue";
const dialog = ref(false);
</script>
<template>
<!-- ----------------------------------------------------------------------------- -->
<!-- Form -->
<!-- ----------------------------------------------------------------------------- -->
<div class="text-center">
<v-dialog v-model="dialog" persistent class="dialog-mw">
<template v-slot:activator="{ props }">
<v-btn color="warning" class="w-100" v-bind="props" flat> Open Form Dialog </v-btn>
</template>
<v-card style="height: 400px" class="overflow-auto">
<v-container>
<v-card-title class="pa-5">
<span class="text-h5">User Profile</span>
</v-card-title>
<v-card-text>
<v-row>
<v-col cols="12" sm="6" md="4">
<v-text-field label="Legal first name*" required></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field
label="Legal middle name"
hint="example of helper text only on focus"
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field
label="Legal last name*"
hint="example of persistent helper text"
persistent-hint
required
></v-text-field>
</v-col>
<v-col cols="12">
<v-text-field label="Email*" required></v-text-field>
</v-col>
<v-col cols="12">
<v-text-field
label="Password*"
type="password"
required
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-select
:items="['0-17', '18-29', '30-54', '54+']"
label="Age*"
required
></v-select>
</v-col>
<v-col cols="12" sm="6">
<v-autocomplete
:items="[
'Skiing',
'Ice hockey',
'Soccer',
'Basketball',
'Hockey',
'Reading',
'Writing',
'Coding',
'Basejump',
]"
label="Interests"
multiple
></v-autocomplete>
</v-col>
</v-row>
<small>*indicates required field</small>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="error" @click="dialog = false" variant="tonal" flat>
Close
</v-btn>
<v-btn color="success" @click="dialog = false" variant="tonal" flat>
Save
</v-btn>
</v-card-actions>
</v-container>
</v-card>
</v-dialog>
</div>
</template>

View File

@@ -0,0 +1,76 @@
<script setup lang="ts">
import { ref } from "vue";
import {XIcon } from "vue-tabler-icons"
const dialog = ref(false);
const notifications = ref(false);
const sound = ref(true);
const widgets = ref(false);
</script>
<template>
<div class="text-center">
<v-dialog
v-model="dialog"
fullscreen
:scrim="false"
transition="dialog-bottom-transition"
>
<template v-slot:activator="{ props }">
<v-btn color="error" class="w-100" dark v-bind="props" flat> Open Fullscreen Dialog </v-btn>
</template>
<v-card>
<v-toolbar dark color="primary" style="flex: unset">
<v-btn icon color="inherit" @click="dialog = false" flat>
<XIcon width="20" />
</v-btn>
<v-toolbar-title>Settings</v-toolbar-title>
<v-spacer></v-spacer>
<v-toolbar-items>
<v-btn dark variant="text" @click="dialog = false" flat> Save </v-btn>
</v-toolbar-items>
</v-toolbar>
<v-card-item>
<v-list lines="two" subheader>
User Controls
<v-list-item
title="Content filtering"
subtitle="Set the content filtering level to restrict apps that can be downloaded"
></v-list-item>
<v-list-item
title="Password"
subtitle="Require password for purchase or use password to restrict purchase"
></v-list-item>
</v-list>
<v-divider></v-divider>
<v-list lines="two" subheader>
General
<v-list-item
title="Notifications"
subtitle="Notify me about updates to apps or games that I downloaded"
>
<template v-slot:prepend>
<v-checkbox v-model="notifications"></v-checkbox>
</template>
</v-list-item>
<v-list-item
title="Sound"
subtitle="Auto-update apps at any time. Data charges may apply"
>
<template v-slot:prepend>
<v-checkbox v-model="sound"></v-checkbox>
</template>
</v-list-item>
<v-list-item
title="Auto-add widgets"
subtitle="Automatically add home screen widgets"
>
<template v-slot:prepend>
<v-checkbox v-model="widgets"></v-checkbox>
</template>
</v-list-item>
</v-list>
</v-card-item>
</v-card>
</v-dialog>
</div>
</template>

View File

@@ -0,0 +1,23 @@
<script setup lang="ts">
import { ref } from "vue";
const dialog = ref(false);
</script>
<template>
<div class="text-center">
<v-btn color="secondary" class="w-100" @click="dialog = true" flat> Open Dialog </v-btn>
<v-dialog v-model="dialog" class="dialog-mw">
<v-card>
<v-card-text>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
</v-card-text>
<v-card-actions>
<v-btn color="secondary" @click="dialog = false" variant="tonal"
>Close Dialog</v-btn
>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>

View File

@@ -0,0 +1,78 @@
<script setup lang="ts">
import { ref } from "vue";
const dialog = ref(false);
const dialog2 = ref(false);
const dialog3 = ref(false);
const notifications = ref(false);
const sound = ref(true);
const widgets = ref(false);
const items = ref([
{
title: "Click Me",
},
{
title: "Click Me",
},
{
title: "Click Me",
},
{
title: "Click Me 2",
},
]);
const select = ref([
{ text: "State 1" },
{ text: "State 2" },
{ text: "State 3" },
{ text: "State 4" },
{ text: "State 5" },
{ text: "State 6" },
{ text: "State 7" },
]);
</script>
<template>
<div class="text-center">
<v-btn color="secondary" class=" w-100" @click="dialog = true" flat>
Open Dialog 1
</v-btn>
<v-dialog v-model="dialog" class="dialog-mw">
<v-card class="pa-6">
<v-card-title> Dialog 1 </v-card-title>
<v-card-text>
<v-btn color="primary" class="" @click="dialog2 = true" flat>
Open Dialog 2
</v-btn>
</v-card-text>
<v-card-actions>
<v-btn color="error" variant="tonal" @click="dialog = false" flat> Close </v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-dialog v-model="dialog2" class="dialog-mw">
<v-card class="pa-6">
<v-card-title> Dialog 2 </v-card-title>
<v-card-text>
<v-btn color="secondary" @click="dialog3 = !dialog3" flat>
Open Dialog 3
</v-btn>
</v-card-text>
<v-card-actions>
<v-btn color="error" variant="tonal" @click="dialog2 = false" flat> Close </v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-dialog v-model="dialog3" class="dialog-mw">
<v-card class="pa-6">
<v-card-title>
<span>Dialog 3</span>
</v-card-title>
<v-card-actions>
<v-btn color="error" variant="tonal" @click="dialog3 = false" flat> Close </v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>

View File

@@ -0,0 +1,32 @@
<script setup lang="ts">
import { ref } from "vue";
const dialog = ref(false);
</script>
<template>
<div class="text-center">
<v-dialog v-model="dialog" persistent class="dialog-mw">
<template v-slot:activator="{ props }">
<v-btn color="primary" class="w-100" v-bind="props" flat> Open Dialog </v-btn>
</template>
<v-card class="pa-6">
<v-card-title class="text-h5">
Use Google's location service?
</v-card-title>
<v-card-text
>Let Google help apps determine location. This means sending anonymous
location data to Google, even when no apps are running.</v-card-text
>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="error" variant="tonal" @click="dialog = false" flat>
Disagree
</v-btn>
<v-btn color="success" variant="tonal" @click="dialog = false" flat>
Agree
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>

View File

@@ -0,0 +1,50 @@
<script setup lang="ts">
import { ref } from "vue";
const dialogm1 = ref("");
const dialog = ref(false);
</script>
<template>
<div class="text-center">
<v-dialog v-model="dialog" scrollable class="dialog-mw">
<template v-slot:activator="{ props }">
<v-btn color="success" class="w-100" v-bind="props" flat> Open Scrolling Dialog </v-btn>
</template>
<v-card>
<v-card-title>Select Country</v-card-title>
<v-divider></v-divider>
<v-card-text style="height: 300px" class="overflow-auto">
<v-radio-group v-model="dialogm1" column>
<v-radio label="Bahamas, The" value="bahamas"></v-radio>
<v-radio label="Bahrain" value="bahrain"></v-radio>
<v-radio label="Bangladesh" value="bangladesh"></v-radio>
<v-radio label="Barbados" value="barbados"></v-radio>
<v-radio label="Belarus" value="belarus"></v-radio>
<v-radio label="Belgium" value="belgium"></v-radio>
<v-radio label="Belize" value="belize"></v-radio>
<v-radio label="Benin" value="benin"></v-radio>
<v-radio label="Bhutan" value="bhutan"></v-radio>
<v-radio label="Bolivia" value="bolivia"></v-radio>
<v-radio label="Bosnia and Herzegovina" value="bosnia"></v-radio>
<v-radio label="Botswana" value="botswana"></v-radio>
<v-radio label="Brazil" value="brazil"></v-radio>
<v-radio label="Brunei" value="brunei"></v-radio>
<v-radio label="Bulgaria" value="bulgaria"></v-radio>
<v-radio label="Burkina Faso" value="burkina"></v-radio>
<v-radio label="Burma" value="burma"></v-radio>
<v-radio label="Burundi" value="burundi"></v-radio>
</v-radio-group>
</v-card-text>
<v-divider></v-divider>
<v-card-actions>
<v-btn color="error" variant="tonal" @click="dialog = false">
Close
</v-btn>
<v-btn color="success" variant="tonal" @click="dialog = false">
Save
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>

View File

@@ -0,0 +1,25 @@
<script setup lang="ts">
import { ref } from "vue";
const dialog = ref(false);
</script>
<template>
<div class="text-center">
<v-dialog transition="dialog-bottom-transition" class="dialog-mw">
<template v-slot:activator="{ props }">
<v-btn color="success" class="w-100" v-bind="props" flat>Open Transition Dialog</v-btn>
</template>
<template v-slot:default="{ isActive }">
<v-card>
<v-toolbar color="primary" class="px-4">Opening from the bottom</v-toolbar>
<v-card-item>
<div class="text-h2 pa-12">Hello world!</div>
</v-card-item>
<v-card-actions class="justify-end">
<v-btn variant="tonal" @click="isActive.value = false" flat>Close</v-btn>
</v-card-actions>
</v-card>
</template>
</v-dialog>
</div>
</template>

View File

@@ -0,0 +1,24 @@
<script setup lang="ts">
import { ref } from "vue";
const props = defineProps({
modelValue: {
type: Boolean,
},
});
const emit = defineEmits(["update:modelValue"]);
</script>
<template>
<div class="text-center mt-4 mt-sm-0">
<v-dialog :model-value="modelValue" activator="parent" class="dialog-mw" persistent>
<v-card>
<v-card-text>
<slot name="text"></slot>
</v-card-text>
<v-card-actions>
<slot name="actions"></slot>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>

View File

@@ -0,0 +1,33 @@
<script setup lang="ts">
import { ref } from "vue";
const props = defineProps({
modelValue: {
type: Boolean,
},
});
const emit = defineEmits(["update:modelValue"]);
</script>
<template>
<div class="text-center">
<v-dialog :model-value="modelValue" scrollable class="dialog-mw" persistent>
<v-card>
<v-card-title>
<slot name="title"></slot>
</v-card-title>
<v-divider></v-divider>
<v-card-text style="height: 300px" class="overflow-auto">
<slot name="text"></slot>
</v-card-text>
<v-divider></v-divider>
<v-card-actions>
<v-spacer></v-spacer>
<slot name="actions"></slot>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>

View File

@@ -0,0 +1,45 @@
<script setup lang="ts">
import { blogCard } from '@/_mockApis/components/widget/card';
</script>
<template>
<v-row>
<v-col cols="12" md="4" sm="4" v-for="card in blogCard" :key="card.title">
<v-card elevation="10" rounded="md" class="card-hover">
<div>
<v-img :src="card.coveravatar" height="250px" cover class="rounded-t-md align-end text-right">
<v-card-item
><v-chip class="bg-surface text-body-2 font-weight-medium" size="small" rounded="sm" v-text="card.read"></v-chip
></v-card-item>
</v-img>
<v-avatar size="40" class="mt-n7 mx-6">
<img :src="card.avatar" alt="icon" height="40" />
</v-avatar>
<v-card-item class="pt-4">
<v-chip class="text-body-2 font-weight-medium bg-light" size="small" rounded="sm" v-text="card.category"></v-chip>
<h5 class="text-h5 text-13 my-6 custom-text-primary">
<RouterLink class="text-decoration-none color-inherits custom-title" :to="card.link">{{ card.title }}</RouterLink>
</h5>
<div class="d-flex align-center justify-space-between">
<div>
<v-avatar class="" size="18">
<EyeIcon size="18" class="text-textPrimary" />
</v-avatar>
<span class="text-subtitle-1 ml-2 textSecondary" v-text="card.view"></span>
<v-avatar class="ml-4" size="18">
<Message2Icon size="18" class="text-textPrimary" />
</v-avatar>
<span class="text-subtitle-1 ml-2 textSecondary" v-text="card.comments"></span>
</div>
<div>
<v-avatar size="10">
<CircleIcon size="10" class="text-textPrimary" />
</v-avatar>
<span class="text-subtitle-2 ml-2 textSecondary" v-text="card.time"></span>
</div>
</div>
</v-card-item>
</div>
</v-card>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,23 @@
<script setup lang="ts">
import {followerCard} from '@/_mockApis/components/widget/card';
</script>
<template>
<v-row class="pt-3">
<v-col cols="12" md="4" v-for="card in followerCard" :key="card.title">
<v-card elevation="10" rounded="md">
<v-card-item>
<div class="d-flex align-center">
<v-avatar size="40" >
<img :src="card.avatar" :alt="card.avatar" width="40"/>
</v-avatar>
<div class="pl-4 mt-n1">
<h5 class="text-h5" v-text="card.title"></h5>
<p class="text-body-1 textSecondary d-flex align-center"><MapPinIcon size="15" class="mr-1"/>{{card.location}}</p>
</div>
<v-btn class="ml-auto" color="primary" flat>Follow</v-btn>
</div>
</v-card-item>
</v-card>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,39 @@
<script setup lang="ts">
import { ref } from 'vue';
import img1 from '@/assets/images/products/s1.jpg';
import img2 from '@/assets/images/products/s2.jpg';
/*import tabler icons*/
import { GiftIcon } from 'vue-tabler-icons';
const gift = [
{
title: 'Andrew Grant',
avatar: img1
},
{
title: 'Leo Pratt',
avatar: img2
}
];
</script>
<template>
<v-row>
<v-col cols="12" md="6" v-for="card in gift" :key="card.title">
<v-card elevation="10" rounded="md">
<v-card-item>
<div class="d-flex align-center justify-space-between">
<h5 class="text-h6" v-text="card.title"></h5>
<v-btn size="30" icon variant="flat" class="mx-1">
<v-avatar size="25" >
<GiftIcon class="text-secondary" size="20" />
</v-avatar>
</v-btn>
</div>
<v-avatar rounded="lg" class="w-100 mt-2 mb-6" size="160" cla>
<img :src="card.avatar" :alt="card.avatar" class="w-100"/>
</v-avatar>
<v-btn color="primary" block flat>Gift to Friend ($50.00)</v-btn>
</v-card-item>
</v-card>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,40 @@
<script setup lang="ts">
import {musicCard} from '@/_mockApis/components/widget/card';
</script>
<template>
<v-row>
<v-col cols="12" md="4" v-for="card in musicCard" :key="card.title">
<v-card elevation="10" class="overflow-visible">
<v-row class="mt-md-0 mt-sm-3 mt-3">
<v-col cols="6" sm="6">
<v-card-item class="pb-3">
<h5 class="text-h5" v-text="card.title"></h5>
<div class="text-body-1 textSecondary mt-1" v-text="card.subheader"></div>
<div class="d-flex align-center justify-center mt-8 ">
<v-btn size="20" icon variant="flat" class="grey100">
<v-avatar size="20">
<PlayerSkipBackIcon size="15" color="grey100" />
</v-avatar>
</v-btn>
<v-btn size="20" icon variant="flat" class="mx-6 text-error">
<v-avatar size="20">
<PlayerPlayIcon size="15" class="text-error" />
</v-avatar>
</v-btn>
<v-btn size="20" icon variant="flat" class="grey100">
<v-avatar size="20">
<PlayerSkipForwardIcon size="15" />
</v-avatar>
</v-btn>
</div>
</v-card-item>
</v-col>
<v-col cols="6" sm="6" class="py-0 pl-0">
<img :src="card.img" class="rounded-e-md w-100 h-100 obj-cover"></img>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,24 @@
<script setup lang="ts">
import { paymentGateways } from '@/_mockApis/components/widget/card';
</script>
<template>
<v-card elevation="10" >
<v-card-item>
<v-card-title class="text-h5">Payment Gateways</v-card-title>
<v-card-subtitle class="text-subtitle-1 ">Platform For Income</v-card-subtitle>
<div class="mt-sm-10 mt-5">
<div class="d-flex gap-3 align-center mt-6" v-for="list in paymentGateways" :key="list.title">
<v-avatar :class="'rounded-md bg-light' + list.bgcolor" size="45">
<img :src="list.img" :alt="list.img" width="25" />
</v-avatar>
<div>
<h5 class="text-h6 mb-1">{{ list.title }}</h5>
<p class="text-subtitle-1 textSecondary">{{ list.subtitle }}</p>
</div>
<div :class="'ml-auto font-weight-semibold text-subtitle-1 text-medium-' + list.disable">{{ list.rank }}</div>
</div>
<v-btn class="mt-10" block flat color="primary">View all transactions</v-btn>
</div>
</v-card-item>
</v-card>
</template>

View File

@@ -0,0 +1,36 @@
<script setup lang="ts">
import { productsCard } from '@/_mockApis/components/widget/card';
</script>
<template>
<v-row>
<v-col cols="12" lg="3" sm="6" v-for="card in productsCard" :key="card.title">
<v-card elevation="10" rounded="md" class="card-hover overflow-hidden">
<RouterLink :to="card.link" >
<v-img :src="card.photo" height="100%" class="rounded-t-md"></v-img>
</RouterLink>
<div class="d-flex justify-end mr-3 mt-n4">
<v-btn size="30" icon variant="flat" class="bg-primary d-flex">
<v-avatar size="30" class="text-white">
<BasketIcon size="17" />
</v-avatar>
<v-tooltip
activator="parent"
location="bottom"
>Add To Cart
</v-tooltip>
</v-btn>
</div>
<v-card-item class="pa-6 pt-1">
<h6 class="text-h6" v-text="card.title"></h6>
<div class="d-flex align-center justify-space-between mt-1">
<div>
<span class="text-h6" v-text="'$'+ card.price"></span>
<span class="text-body-1 ml-2 text-medium-emphasis text-decoration-line-through" v-text="'$'+ card.salesPrice"></span>
</div>
<v-rating density="compact" color="warning" size="small" v-model="card.rating" readonly></v-rating>
</div>
</v-card-item>
</v-card>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,28 @@
<script setup lang="ts">
import {profileCards, socialiconCard} from '@/_mockApis/components/widget/card';
</script>
<template>
<v-row>
<v-col cols="12" md="4" v-for="card in profileCards" :key="card.title">
<v-card elevation="10" class=" text-center" rounded="md">
<v-card-item>
<v-avatar size="80">
<img :src="card.avatar" :alt="card.avatar" width="80"/>
</v-avatar>
<div class="mt-4">
<h5 class="text-h5" v-text="card.title"></h5>
<p class="text-body-2 mt-1 textSecondary " v-text="card.subtitle"></p>
</div>
</v-card-item>
<v-divider class="mt-1"></v-divider>
<div class="text-center d-flex justify-center pa-3">
<v-btn size="30" icon variant="flat" v-for="icon in socialiconCard" :key="icon.name">
<v-avatar size="22">
<component :is="icon.icon" :class="'text-'+ icon.color" stroke-width="2" size="18" />
</v-avatar>
</v-btn>
</div>
</v-card>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,46 @@
<script setup lang="ts">
import { ref } from 'vue';
/*import tabler icons*/
import { VolumeIcon,MessageIcon } from 'vue-tabler-icons';
const slider = ref(50);
const model = ref(false);
</script>
<template>
<v-card elevation="10" rounded="md">
<v-card-item>
<v-card-title class="text-h5">Settings</v-card-title>
<div class="d-flex mt-5">
<v-avatar class="rounded-md bg-primary" size="48">
<VolumeIcon size="22" />
</v-avatar>
<div class="pl-4 w-100">
<div class="d-flex align-center justify-space-between">
<h6 class="text-h6">Sound</h6>
<p class="text-subtitle-1 textSecondary">45%</p>
</div>
<v-slider v-model="slider" hide-details class="ml-0" color="primary"></v-slider>
</div>
</div>
<v-divider class="mt-4"></v-divider>
<div class="d-flex mt-4">
<v-avatar class="rounded-md bg-secondary" size="48">
<MessageIcon size="22" class="text-surface"/>
</v-avatar>
<div class="pl-4 w-100 d-flex align-center">
<div class="">
<h6 class="text-h6 mb-1">Chat</h6>
<p class="text-subtitle-1 textSecondary">Turn on chat during call</p>
</div>
<div class="ml-auto">
<v-switch v-model="model" hide-details color="primary" inset ></v-switch>
</div>
</div>
</div>
<v-divider class="mt-4"></v-divider>
<div class="d-flex justify-end mt-4 gap-3">
<v-btn color="error" variant="tonal">Cancel</v-btn>
<v-btn color="primary">save</v-btn>
</div>
</v-card-item>
</v-card>
</template>

View File

@@ -0,0 +1,23 @@
<script setup lang="ts">
import {upcommingCards} from '@/_mockApis/components/widget/card';
</script>
<template>
<v-card elevation="10" >
<v-card-item class="pb-sm-8 pb-6">
<v-card-title class="text-h5">Upcoming Activity</v-card-title>
<v-card-subtitle class="text-subtitle-1 ">In New year</v-card-subtitle>
<div class="">
<div class="d-flex align-center mt-6" v-for="list in upcommingCards" :key="list.title">
<v-avatar :class="'rounded-md bg-light'+ list.bgcolor" size="45">
<component :is="list.icon" :class="'text-'+ list.bgcolor" stroke-width="2" size="20" />
</v-avatar>
<div class="pl-4 ">
<h5 class="text-h6 mb-1" v-text="list.title"></h5>
<p class="text-subtitle-1 textSecondary" v-text="list.subtitle"></p>
</div>
<div class="ml-auto font-weight-medium text-subtitle-1 textSecondary" v-text="list.rank"></div>
</div>
</div>
</v-card-item>
</v-card>
</template>

View File

@@ -0,0 +1,31 @@
<script setup lang="ts">
import { userCards } from '@/_mockApis/components/widget/card';
</script>
<template>
<v-row>
<v-col cols="12" md="3" sm="6" v-for="card in userCards" :key="card.title">
<v-card elevation="10" rounded="md">
<v-card-item>
<v-avatar size="80" >
<img :src="card.avatar" :alt="card.avatar" width="80"/>
</v-avatar>
<div class="mt-6">
<h5 class="text-h5 mb-2" v-text="card.title"></h5>
<div class="d-flex align-center justify-space-between">
<div class="ml-2 d-flex ">
<v-avatar size="32" class="ml-n2 avtar-border" v-for="user in card.userGroup" :key="user.icon">
<img :src="user.icon" alt="avatar" height="32"/>
</v-avatar>
</div>
<p class="text-subtitle-1 textSecondary">{{card.subtitle}}</p>
</div>
</div>
<div class="mt-6">
<v-btn color="primary" variant="tonal" block >Add friend</v-btn>
<v-btn color="secondary" variant="tonal" class="mt-3" block >Remove</v-btn>
</div>
</v-card-item>
</v-card>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,36 @@
<script setup lang="ts">
// import {followerCard} from '@/_mockApis/components/widget/card';
const props = defineProps({
data:{
type: Array,
default: () => []
}
})
const followerCard: any = computed(() => {
return props.data
});
</script>
<template>
<v-row class="pt-3">
<v-col cols="12" md="4" v-for="card in followerCard" :key="card.title">
<v-card elevation="10" rounded="md">
<v-card-item>
<div class="d-flex align-center">
<v-avatar size="40" >
<slot name="avatar" :prop="card"></slot>
</v-avatar>
<div class="pl-4 mt-n1">
<h5 class="text-h5" >
<slot name="title" :prop="card"></slot>
</h5>
<p class="text-body-1 textSecondary d-flex align-center">
<slot name="content" :prop="card"></slot>
</p>
</div>
<slot name="actions" :prop="card"></slot>
</div>
</v-card-item>
</v-card>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,39 @@
<script setup lang="ts">
// import {profileCards, socialiconCard} from '@/_mockApis/components/widget/card';
const props = defineProps({
data:{
type: Array,
default: () => []
}
})
const profileCards: any = computed(() => {
return props.data
});
</script>
<template>
<v-row>
<v-col cols="12" md="4" v-for="card in profileCards" :key="card.title">
<v-card elevation="10" class=" text-center" rounded="md">
<v-card-item>
<v-avatar size="80">
<slot name="avatar" :prop="card"></slot>
</v-avatar>
<div class="mt-4">
<!-- <h5 class="text-h5" v-text="card.title"></h5>
<p class="text-body-2 mt-1 textSecondary " v-text="card.subtitle"></p> -->
<slot name="content" :prop="card"></slot>
</div>
</v-card-item>
<v-divider class="mt-1"></v-divider>
<div class="text-center d-flex justify-center pa-3">
<slot name="actions" :prop="card"></slot>
<!-- <v-btn size="30" icon variant="flat" v-for="icon in socialiconCard" :key="icon.name">
<v-avatar size="22">
<component :is="icon.icon" :class="'text-'+ icon.color" stroke-width="2" size="18" />
</v-avatar>
</v-btn> -->
</div>
</v-card>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,32 @@
<script setup lang="ts">
import {upcommingCards} from '@/_mockApis/components/widget/card';
</script>
<template>
<v-card elevation="10" >
<v-card-item class="pb-sm-8 pb-6">
<v-card-title class="text-h5">Upcoming Activity</v-card-title>
<v-card-subtitle class="text-subtitle-1 ">In New year</v-card-subtitle>
<div class="">
<div class="d-flex align-center mt-6" v-for="list in upcommingCards" :key="list.title">
<v-avatar :class="'rounded-md bg-light'+ list.bgcolor" size="45">
<slot name="avatar" :prop="list"></slot>
<!-- <component :is="list.icon" :class="'text-'+ list.bgcolor" stroke-width="2" size="20" /> -->
</v-avatar>
<div class="pl-4 ">
<h5 class="text-h6 mb-1" >
<slot name="title" :prop="list"></slot>
</h5>
<p class="text-subtitle-1 textSecondary" >
<slot name="content" :prop="list"></slot>
</p>
<!-- <h5 class="text-h6 mb-1" v-text="list.title"></h5>
<p class="text-subtitle-1 textSecondary" v-text="list.subtitle"></p> -->
</div>
<div class="ml-auto font-weight-medium text-subtitle-1 textSecondary" >
<slot name="left-side-content" :prop="list"></slot>
</div>
</div>
</div>
</v-card-item>
</v-card>
</template>

View File

@@ -0,0 +1,41 @@
<script setup lang="ts">
// import { userCards } from '@/_mockApis/components/widget/card';
const props = defineProps({
data:{
type: Array,
default: () => []
}
})
const userCards: any = computed(() => {
return props.data
});
</script>
<template>
<v-row>
<v-col cols="12" md="3" sm="6" v-for="card in userCards" :key="card.title">
<v-card elevation="10" rounded="md">
<v-card-item>
<v-avatar size="80" >
<slot name="avatar" :prop="card"></slot>
</v-avatar>
<div class="mt-6">
<h5 class="text-h5 mb-2">
<slot name="title" :prop="card"></slot>
</h5>
<div class="d-flex align-center justify-space-between">
<div class="ml-2 d-flex ">
<slot name="left-side-content" :prop="card"></slot>
</div>
<slot name="right-side-content" :prop="card"></slot>
</div>
</div>
<div class="mt-6">
<slot name="actions" :prop="card"></slot>
</div>
</v-card-item>
</v-card>
</v-col>
</v-row>
</template>

18
composable/index.ts Normal file
View File

@@ -0,0 +1,18 @@
import { toast } from "vue3-toastify";
// export function deleteItem (data:any, index:number) {
// try {
// data.splice(index,1)
// } catch (error) {
// }
// }
// export function delete(){
// }
export function toastAlert(msg:string,type:any){
toast(msg, {
type: type,
dangerouslyHTMLString: true,
autoClose: 2000,
})
}

View File

@@ -0,0 +1,141 @@
[
{
"id": "1",
"typeUser": "Super Admin",
"roleMenu": [
{
"permission": "0",
"menu": [
{
"Module": "module1",
"create": "true",
"update": "false",
"delete": "false",
"show": "false"
},
{
"Module": "module2",
"create": "true",
"update": "true",
"delete": "false",
"show": "false"
}
]
},
{
"permission": "1",
"menu": [
{
"Module": "module1",
"create": "true",
"update": "false",
"delete": "true",
"show": "false"
},
{
"Module": "module2",
"create": "true",
"update": "true",
"delete": "false",
"show": "false"
}
]
},
{
"permission": "2",
"menu": [
{
"Module": "module2",
"create": "true",
"update": "false",
"delete": "true",
"show": "false"
},
{
"Module": "module3",
"create": "true",
"update": "false",
"delete": "true",
"show": "false"
},
{
"Module": "module4",
"create": "true",
"update": "true",
"delete": "false",
"show": "false"
}
]
}
]
},
{
"id": "2",
"typeUser": "Admin",
"roleMenu": [
{
"permission": "0",
"menu": [
{
"Module": "module1",
"create": "true",
"update": "false",
"delete": "false",
"show": "false"
},
{
"Module": "module2",
"create": "true",
"update": "true",
"delete": "false",
"show": "false"
}
]
},
{
"permission": "1",
"menu": [
{
"Module": "module1",
"create": "true",
"update": "false",
"delete": "true",
"show": "false"
},
{
"Module": "module2",
"create": "true",
"update": "true",
"delete": "false",
"show": "false"
}
]
}
]
},
{
"id": "3",
"typeUser": "Staf",
"roleMenu": [
{
"permission": "0",
"menu": [
{
"Module": "module1",
"create": "true",
"update": "false",
"delete": "false",
"show": "false"
},
{
"Module": "module2",
"create": "true",
"update": "true",
"delete": "false",
"show": "false"
}
]
}
]
}
]

90
data/dummy/ticket.json Normal file
View File

@@ -0,0 +1,90 @@
[
{
"Id": 1,
"ticketTitle": "Sed ut perspiciatis unde omnis iste",
"ticketDescription":
"ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos",
"Status": "Closed",
"Label": "error",
"thumb": "user10",
"AgentName": "Liam",
"Date": "2020-01-01"
},
{
"Id": 2,
"ticketTitle": "Consequuntur magni dolores eos qui ratione",
"ticketDescription":
"ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos",
"Status": "Pending",
"Label": "warning",
"thumb": "user1",
"AgentName": "Steve",
"Date": "2020-01-01"
},
{
"Id": 3,
"ticketTitle": "Exercitationem ullam corporis",
"ticketDescription":
"ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos",
"Status": "Open",
"Label": "success",
"thumb": "user2",
"AgentName": "Jack",
"Date": "2020-01-01"
},
{
"Id": 4,
"ticketTitle": "Sed ut perspiciatis unde omnis iste",
"ticketDescription":
"ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos",
"Status": "Closed",
"Label": "error",
"thumb": "user3",
"AgentName": "Steve",
"Date": "2020-01-01"
},
{
"Id": 5,
"ticketTitle": "Exercitationem ullam corporis",
"ticketDescription":
"ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos",
"Status": "Closed",
"Label": "error",
"thumb": "user4",
"AgentName": "Liam",
"Date": "2020-01-01"
},
{
"Id": 6,
"ticketTitle": "Consequuntur magni dolores eos qui ratione",
"ticketDescription":
"ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos",
"Status": "Pending",
"Label": "warning",
"thumb": "user5",
"AgentName": "Jack",
"Date": "2020-01-01"
},
{
"Id": 7,
"ticketTitle": "Sed ut perspiciatis unde omnis iste",
"ticketDescription":
"ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos",
"Status": "Open",
"Label": "success",
"thumb": "user6",
"AgentName": "Steve",
"Date": "2020-01-01"
},
{
"Id": 8,
"ticketTitle": "Consequuntur magni dolores eos qui ratione",
"ticketDescription":
"ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos",
"Status": "Closed",
"Label": "error",
"thumb": "user7",
"AgentName": "John",
"Date": "2020-01-01"
}
]

View File

@@ -28,6 +28,7 @@ export default defineNuxtConfig({
* Integrasi dengan ecosystem Nuxt.js
*/
modules: [
'@vueform/nuxt',
"@pinia/nuxt", // State management dengan Pinia
[
"@sidebase/nuxt-auth",

201
package-lock.json generated
View File

@@ -13,6 +13,8 @@
"@mdi/font": "7.4.47",
"@pinia/nuxt": "^0.11.1",
"@sidebase/nuxt-auth": "^0.10.1",
"@vueform/nuxt": "^1.12.0",
"@vueform/vueform": "^1.12.10",
"@vueuse/i18n": "^4.0.0-beta.12",
"apexcharts": "4.5.0",
"axios": "^1.9.0",
@@ -29,6 +31,7 @@
"vue-tabler-icons": "2.21.0",
"vue3-apexcharts": "1.5.2",
"vue3-perfect-scrollbar": "1.6.1",
"vue3-toastify": "^0.2.8",
"vuetify": "3.7.18"
},
"devDependencies": {
@@ -2513,6 +2516,16 @@
"dev": true,
"license": "MIT"
},
"node_modules/@popperjs/core": {
"version": "2.11.8",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@poppinss/colors": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/@poppinss/colors/-/colors-4.1.4.tgz",
@@ -3195,6 +3208,13 @@
"integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==",
"license": "MIT"
},
"node_modules/@types/trusted-types": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
"license": "MIT",
"optional": true
},
"node_modules/@types/yauzl": {
"version": "2.10.3",
"resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",
@@ -3604,6 +3624,121 @@
"integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==",
"license": "MIT"
},
"node_modules/@vueform/country-phones": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@vueform/country-phones/-/country-phones-1.0.3.tgz",
"integrity": "sha512-IGDHQFuPwL7j9MgH2UtXFPfWPQlyPCxDPso92y5QuXNMEnjBPK8fvrcLgj/2pGVO1ASS+E+05AGCrKtYyfeNsg==",
"license": "SEE LICENSE IN LICENSE"
},
"node_modules/@vueform/multiselect": {
"version": "2.6.11",
"resolved": "https://registry.npmjs.org/@vueform/multiselect/-/multiselect-2.6.11.tgz",
"integrity": "sha512-iG4TGfqE3baftbSGF0PhoS+xZOCnV0ChkDo9rwhJ/Qi2YlCdb6tyQCjvyug3jnzncga8+d85kx0WvG7rDYFqiA==",
"license": "MIT"
},
"node_modules/@vueform/nuxt": {
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/@vueform/nuxt/-/nuxt-1.16.0.tgz",
"integrity": "sha512-tyra0wOyeGmTXZLJJzhzGd7TURGjJXsNajzDqXy4juP9AC5fmZ935dctlcRpZGIBy6sGZnw+r755Li5mXiI1vw==",
"license": "MIT",
"dependencies": {
"@nuxt/kit": "^3.8.1",
"@vueform/vueform": "^1.12.10",
"pathe": "^1.1.1"
}
},
"node_modules/@vueform/nuxt/node_modules/pathe": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
"integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
"license": "MIT"
},
"node_modules/@vueform/slider": {
"version": "2.1.10",
"resolved": "https://registry.npmjs.org/@vueform/slider/-/slider-2.1.10.tgz",
"integrity": "sha512-L2G3Ju51Yq6yWF2wzYYsicUUaH56kL1QKGVtimUVHT1K1ADcRT94xVyIeJpS0klliVEeF6iMZFbdXtHq8AsDHw==",
"license": "MIT"
},
"node_modules/@vueform/toggle": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@vueform/toggle/-/toggle-2.1.4.tgz",
"integrity": "sha512-tEITFf5wlqIWoCYZXJdoXvCnrc97weOu2csR/BEoROVvFu1zRsoK0wY1pJG7BR+g5zpGJneGSdLhMUsbx8y1yw==",
"license": "MIT"
},
"node_modules/@vueform/vueform": {
"version": "1.12.10",
"resolved": "https://registry.npmjs.org/@vueform/vueform/-/vueform-1.12.10.tgz",
"integrity": "sha512-/B+rrfBIMRzEZJTckptgfqF1kXu0P5qQoecuD/Ps6PdXpiP33UdkMsMF5pCZ7fFlwr1huxmUnP/EkQi7jyBz7w==",
"license": "MIT",
"dependencies": {
"@popperjs/core": "^2.11.8",
"@vueform/country-phones": "^1.0.3",
"@vueform/multiselect": "^2.6.11",
"@vueform/slider": "^2.1.10",
"@vueform/toggle": "^2.1.4",
"axios": "^1.8.4",
"color": "^4.2.3",
"dompurify": "^3.2.4",
"lodash": "^4.17.21",
"mini-svg-data-uri": "^1.4.4",
"moment": "^2.30.1",
"nouislider": "^15.8.1",
"sass": "^1.86.2",
"trix": "^2.1.14",
"wnumb": "^1.2.0"
}
},
"node_modules/@vueform/vueform/node_modules/color": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
"integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1",
"color-string": "^1.9.0"
},
"engines": {
"node": ">=12.5.0"
}
},
"node_modules/@vueform/vueform/node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/@vueform/vueform/node_modules/immutable": {
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.3.tgz",
"integrity": "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==",
"license": "MIT"
},
"node_modules/@vueform/vueform/node_modules/sass": {
"version": "1.89.2",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.89.2.tgz",
"integrity": "sha512-xCmtksBKd/jdJ9Bt9p7nPKiuqrlBMBuuGkQlkhZjjQk3Ty48lv93k5Dq6OPkKt4XwxDJ7tvlfrTa1MPA9bf+QA==",
"license": "MIT",
"dependencies": {
"chokidar": "^4.0.0",
"immutable": "^5.0.2",
"source-map-js": ">=0.6.2 <2.0.0"
},
"bin": {
"sass": "sass.js"
},
"engines": {
"node": ">=14.0.0"
},
"optionalDependencies": {
"@parcel/watcher": "^2.4.1"
}
},
"node_modules/@vueuse/i18n": {
"version": "4.0.0-beta.12",
"resolved": "https://registry.npmjs.org/@vueuse/i18n/-/i18n-4.0.0-beta.12.tgz",
@@ -5284,6 +5419,15 @@
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/dompurify": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.6.tgz",
"integrity": "sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==",
"license": "(MPL-2.0 OR Apache-2.0)",
"optionalDependencies": {
"@types/trusted-types": "^2.0.7"
}
},
"node_modules/domutils": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
@@ -7497,6 +7641,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/mini-svg-data-uri": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz",
"integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==",
"license": "MIT",
"bin": {
"mini-svg-data-uri": "cli.js"
}
},
"node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
@@ -7615,6 +7768,15 @@
"node": ">=18"
}
},
"node_modules/moment": {
"version": "2.30.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
"license": "MIT",
"engines": {
"node": "*"
}
},
"node_modules/mrmime": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
@@ -8098,6 +8260,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/nouislider": {
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/nouislider/-/nouislider-15.8.1.tgz",
"integrity": "sha512-93TweAi8kqntHJSPiSWQ1o/uZ29VWOmal9YKb6KKGGlCkugaNfAupT7o1qTHqdJvNQ7S0su5rO6qRFCjP8fxtw==",
"license": "MIT"
},
"node_modules/npm-run-path": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
@@ -11100,6 +11268,15 @@
"node": ">= 14.0.0"
}
},
"node_modules/trix": {
"version": "2.1.15",
"resolved": "https://registry.npmjs.org/trix/-/trix-2.1.15.tgz",
"integrity": "sha512-LoaXWczdTUV8+3Box92B9b1iaDVbxD14dYemZRxi3PwY+AuDm97BUJV2aHLBUFPuDABhxp0wzcbf0CxHCVmXiw==",
"license": "MIT",
"dependencies": {
"dompurify": "^3.2.5"
}
},
"node_modules/ts-api-utils": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
@@ -12730,6 +12907,24 @@
"node": ">= 6"
}
},
"node_modules/vue3-toastify": {
"version": "0.2.8",
"resolved": "https://registry.npmjs.org/vue3-toastify/-/vue3-toastify-0.2.8.tgz",
"integrity": "sha512-8jDOqsJaBZEbGpCbhWDETJc11D1lZefvgFPq/IPdM+U7+qyXoVPDvK6uq/FIgyV7qV0NcNzvGBMEzjsLQqGROw==",
"license": "MIT",
"engines": {
"node": ">=20",
"npm": ">=9.0.0"
},
"peerDependencies": {
"vue": ">=3.2.0"
},
"peerDependenciesMeta": {
"vue": {
"optional": true
}
}
},
"node_modules/vuetify": {
"version": "3.7.18",
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.7.18.tgz",
@@ -12897,6 +13092,12 @@
"node": ">= 6"
}
},
"node_modules/wnumb": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/wnumb/-/wnumb-1.2.0.tgz",
"integrity": "sha512-eYut5K/dW7usfk/Mwm6nxBNoTPp/uP7PlXld+hhg7lDtHLdHFnNclywGYM9BRC7Ohd4JhwuHg+vmOUGfd3NhVA==",
"license": "MIT"
},
"node_modules/wrap-ansi": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",

View File

@@ -31,7 +31,10 @@
"vue-tabler-icons": "2.21.0",
"vue3-apexcharts": "1.5.2",
"vue3-perfect-scrollbar": "1.6.1",
"vuetify": "3.7.18"
"vue3-toastify": "^0.2.8",
"vuetify": "3.7.18",
"@vueform/nuxt": "^1.12.0",
"@vueform/vueform": "^1.12.10"
},
"devDependencies": {
"nuxt": "^3.17.5"

View File

@@ -0,0 +1,38 @@
<script setup lang="ts">
import { ref } from 'vue';
// common components
import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue';
import UiParentCard from '@/components/shared/UiParentCard.vue';
//Table
import Table from '@/components/Setting/TipePengguna/TableViewPermission.vue';
// template breadcrumb
const page = ref({ title: 'Basic Table' });
const breadcrumbs = ref([
{
text: 'Dashboard',
disabled: false,
href: '#'
},
{
text: 'View Permission',
disabled: true,
href: '#'
}
]);
</script>
<template>
<!-- ---------------------------------------------------- -->
<!-- Table Basic -->
<!-- ---------------------------------------------------- -->
<BaseBreadcrumb :title="page.title" :breadcrumbs="breadcrumbs"></BaseBreadcrumb>
<v-row>
<v-col cols="12">
<UiParentCard title="View Permission">
<Table/>
</UiParentCard>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,39 @@
<script setup lang="ts">
import { ref } from 'vue';
// common components
import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue';
import UiParentCard from '@/components/shared/UiParentCard.vue';
//card list
import CardList from '@/components/setting/ViewPermission/CrudCardList.vue';
// template breadcrumb
const page = ref({ title: 'Card List' });
const breadcrumbs = ref([
{
text: 'Dashboard',
disabled: false,
href: '#'
},
{
text: 'card list',
disabled: true,
href: '#'
}
]);
</script>
<template>
<!-- ---------------------------------------------------- -->
<!-- Table Basic -->
<!-- ---------------------------------------------------- -->
<BaseBreadcrumb :title="page.title" :breadcrumbs="breadcrumbs"></BaseBreadcrumb>
<v-row>
<v-col cols="12">
<!-- <UiParentCard title="Social Media Contacts"> -->
<CardList/>
<!-- </UiParentCard> -->
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,39 @@
<script setup lang="ts">
import { ref } from 'vue';
// common components
import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue';
import UiParentCard from '@/components/shared/UiParentCard.vue';
//card list
import CardList from '@/components/app/cardList/CrudCardList.vue';
// template breadcrumb
const page = ref({ title: 'Card List' });
const breadcrumbs = ref([
{
text: 'Dashboard',
disabled: false,
href: '#'
},
{
text: 'card list',
disabled: true,
href: '#'
}
]);
</script>
<template>
<!-- ---------------------------------------------------- -->
<!-- Table Basic -->
<!-- ---------------------------------------------------- -->
<BaseBreadcrumb :title="page.title" :breadcrumbs="breadcrumbs"></BaseBreadcrumb>
<v-row>
<v-col cols="12">
<!-- <UiParentCard title="Social Media Contacts"> -->
<CardList/>
<!-- </UiParentCard> -->
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,35 @@
<script setup lang="ts">
import { ref } from "vue";
// common components
import BaseBreadcrumb from "@/components/shared/BaseBreadcrumb.vue";
import UiParentCard from "@/components/shared/UiParentCard.vue";
//Table
import Table from "@/components/app/table/StepTable.vue";
// template breadcrumb
const page = ref({ title: "Basic Table" });
const breadcrumbs = ref([
{
text: "Dashboard",
disabled: false,
href: "#",
},
{
text: "list",
disabled: true,
href: "#",
},
]);
</script>
<template>
<!-- ---------------------------------------------------- -->
<!-- Table Basic -->
<!-- ---------------------------------------------------- -->
<BaseBreadcrumb
:title="page.title"
:breadcrumbs="breadcrumbs"
></BaseBreadcrumb>
<Table />
</template>

View File

@@ -0,0 +1,35 @@
<script setup lang="ts">
import { ref } from 'vue';
// common components
import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue';
//Table
import Table from "@/components/app/table/StepTable2.vue";
const page = ref({ title: "Tickets App" });
const breadcrumbs = ref([
{
text: "Dashboard",
disabled: false,
href: "#",
},
{
text: "Tickets App",
disabled: true,
href: "#",
},
]);
</script>
<template>
<!-- ---------------------------------------------------- -->
<!-- Table Basic -->
<!-- ---------------------------------------------------- -->
<BaseBreadcrumb :title="page.title" :breadcrumbs="breadcrumbs"></BaseBreadcrumb>
<Table/>
</template>

38
pages/app/table/index.vue Normal file
View File

@@ -0,0 +1,38 @@
<script setup lang="ts">
import { ref } from 'vue';
// common components
import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue';
import UiParentCard from '@/components/shared/UiParentCard.vue';
//Table
import Table from '@/components/app/table/CrudTable.vue';
// template breadcrumb
const page = ref({ title: 'Basic Table' });
const breadcrumbs = ref([
{
text: 'Dashboard',
disabled: false,
href: '#'
},
{
text: 'list',
disabled: true,
href: '#'
}
]);
</script>
<template>
<!-- ---------------------------------------------------- -->
<!-- Table Basic -->
<!-- ---------------------------------------------------- -->
<BaseBreadcrumb :title="page.title" :breadcrumbs="breadcrumbs"></BaseBreadcrumb>
<v-row>
<v-col cols="12">
<UiParentCard title="list">
<Table/>
</UiParentCard>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,51 @@
<script setup lang="ts">
import { ref } from 'vue';
// common components
import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue';
import UiParentCard from '@/components/shared/UiParentCard.vue';
//Table
import Table1 from '@/components/table/Table1.vue';
import Table2 from '@/components/table/Table2.vue';
import Table3 from '@/components/table/Table3.vue';
import Table4 from '@/components/table/Table4.vue';
import Table5 from '@/components/table/Table5.vue';
// template breadcrumb
const page = ref({ title: 'Basic Table' });
const breadcrumbs = ref([
{
text: 'Dashboard',
disabled: false,
href: '#'
},
{
text: 'Basic Table',
disabled: true,
href: '#'
}
]);
</script>
<template>
<!-- ---------------------------------------------------- -->
<!-- Table Basic -->
<!-- ---------------------------------------------------- -->
<BaseBreadcrumb :title="page.title" :breadcrumbs="breadcrumbs"></BaseBreadcrumb>
<v-row>
<v-col cols="12">
<UiParentCard title="Basic Table">
<!--Basic Table 1-->
<Table1/>
<!--Basic Table 2-->
<Table2/>
<!--Basic Table 3-->
<Table3/>
<!--Basic Table 4-->
<Table4/>
<!--Basic Table 5-->
<Table5/>
</UiParentCard>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,84 @@
<script setup lang="ts">
import { ref } from 'vue';
// common components
import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue';
import UiParentCard from '@/components/shared/UiParentCard.vue';
import { darkTableData } from '@/_mockApis/components/table/basicTables';
// template breadcrumb
const page = ref({ title: 'Dark Table' });
const breadcrumbs = ref([
{
text: 'Dashboard',
disabled: false,
href: '#'
},
{
text: 'Dark Table',
disabled: true,
href: '#'
}
]);
</script>
<template>
<!-- ---------------------------------------------------- -->
<!-- Table Dark -->
<!-- ---------------------------------------------------- -->
<BaseBreadcrumb :title="page.title" :breadcrumbs="breadcrumbs"></BaseBreadcrumb>
<v-row>
<v-col cols="12">
<UiParentCard title="Dark Table">
<v-card class="border" elevation="0">
<v-table theme="dark" class="month-table dark-table">
<thead>
<tr>
<th class="text-h6 ps-6">Users</th>
<th class="text-h6">Project Name</th>
<th class="text-h6">Team</th>
<th class="text-h6">Status</th>
<th class="text-h6">Budget</th>
</tr>
</thead>
<tbody>
<tr v-for="item in darkTableData" :key="item.name" class="month-item">
<td class="ps-6">
<div class="d-flex gap-3 align-center">
<v-avatar size="40">
<img :src="item.avatar" alt="avatar" height="40" />
</v-avatar>
<div>
<h6 class="text-h6">{{ item.name }}</h6>
<div class="text-body-1 textSecondary">{{ item.post }}</div>
</div>
</div>
</td>
<td>
<h6 class="text-h6 font-weight-medium text-medium-emphasis">{{ item.pname }}</h6>
</td>
<td>
<div class="d-flex align-center">
<div class="ml-2 d-flex flex-row-reverse">
<v-avatar v-for="team in item.teams" :key="team.id" size="35"
:class="'ml-n2 avtar-border bg-' + team.color">
{{ team.text }}
</v-avatar>
</div>
</div>
</td>
<td>
<v-chip rounded="sm" :color="item.statuscolor" size="small"
label>{{
item.status
}}</v-chip>
</td>
<td>
<h6 class="text-h6">{{ item.budget }}</h6>
</td>
</tr>
</tbody>
</v-table>
</v-card>
</UiParentCard>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,79 @@
<script setup lang="ts">
import { ref } from 'vue';
// common components
import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue';
import UiParentCard from '@/components/shared/UiParentCard.vue';
import { tableDensityData } from '@/_mockApis/components/table/basicTables';
// template breadcrumb
const page = ref({ title: 'Density Table' });
const breadcrumbs = ref([
{
text: 'Dashboard',
disabled: false,
href: '#'
},
{
text: 'Density Table',
disabled: true,
href: '#'
}
]);
</script>
<template>
<!-- ---------------------------------------------------- -->
<!-- Table Density -->
<!-- ---------------------------------------------------- -->
<BaseBreadcrumb :title="page.title" :breadcrumbs="breadcrumbs"></BaseBreadcrumb>
<v-row>
<v-col cols="12">
<UiParentCard title="Density Table">
<!-- <v-table > -->
<v-card class="border" elevation="0">
<v-table class="month-table" density="compact">
<thead>
<tr>
<th class="text-h6 ps-6">User</th>
<th class="text-h6">Project Name</th>
<th class="text-h6">Users</th>
<th class="text-h6">Status</th>
</tr>
</thead>
<tbody>
<tr v-for="item in tableDensityData" :key="item.name" class="month-item">
<td class="ps-6">
<div class="d-flex align-center">
<v-avatar size="40">
<img :src="item.avatar" alt="avatar" height="40" />
</v-avatar>
<div class="ml-4">
<h6 class="text-h6">{{ item.name }}</h6>
</div>
</div>
</td>
<td>
<div class="text-subtitle-1 text-medium-emphasis">{{ item.post }}</div>
</td>
<td>
<div class="d-flex align-center">
<div class="ml-2 d-flex flex-row-reverse">
<v-avatar v-for="user in item.users" :key="user.id" size="40" class="ml-n2 avtar-border">
<img :src="user.icon" alt="avatar" height="40" />
</v-avatar>
</div>
</div>
</td>
<td>
<v-chip rounded="sm" class="font-weight-bold " :color="item.statuscolor" size="small">
{{ item.status }}
</v-chip>
</td>
</tr>
</tbody>
</v-table>
</v-card>
</UiParentCard>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,38 @@
<script setup lang="ts">
import { ref } from 'vue';
// common components
import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue';
import UiParentCard from '@/components/shared/UiParentCard.vue';
//Table
import EditableTable from '@/components/table/EditableTable.vue';
// template breadcrumb
const page = ref({ title: 'Editable Table' });
const breadcrumbs = ref([
{
text: 'Dashboard',
disabled: false,
href: '#'
},
{
text: 'Editable Table',
disabled: true,
href: '#'
}
]);
</script>
<template>
<!-- ---------------------------------------------------- -->
<!-- Table Editable -->
<!-- ---------------------------------------------------- -->
<BaseBreadcrumb :title="page.title" :breadcrumbs="breadcrumbs"></BaseBreadcrumb>
<v-row>
<v-col cols="12">
<UiParentCard title="Editable Table">
<EditableTable />
</UiParentCard>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,90 @@
<script setup lang="ts">
import { ref } from 'vue';
// common components
import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue';
import UiParentCard from '@/components/shared/UiParentCard.vue';
import {tableFixedHeaderData} from '@/_mockApis/components/table/basicTables';
// template breadcrumb
const page = ref({ title: 'Fixed Header Table' });
const breadcrumbs = ref([
{
text: 'Dashboard',
disabled: false,
href: '#'
},
{
text: 'Fixed Header Table',
disabled: true,
href: '#'
}
]);
</script>
<template>
<!-- ---------------------------------------------------- -->
<!-- Table Header Fixed -->
<!-- ---------------------------------------------------- -->
<BaseBreadcrumb :title="page.title" :breadcrumbs="breadcrumbs"></BaseBreadcrumb>
<v-row>
<v-col cols="12">
<UiParentCard title="Header Fixed Table">
<v-card class="border" elevation="0">
<v-table class="month-table" fixed-header height="400px">
<thead>
<tr>
<th class="text-h6 ps-6">Customer</th>
<th class="text-h6">Status</th>
<th class="text-h6">Email Address</th>
<th class="text-h6">Teams</th>
</tr>
</thead>
<tbody>
<tr v-for="item in tableFixedHeaderData" :key="item.name" class="month-item">
<td class=" ps-6">
<div class="d-flex gap-3 align-center">
<v-avatar size="40">
<img :src="item.avatar" alt="avatar" height="40" />
</v-avatar>
<div>
<h6 class="text-h6">{{ item.name }}</h6>
<div class="text-body-1 textSecondary">{{ item.handle }}</div>
</div>
</div>
</td>
<td>
<v-chip rounded="sm" v-if="item.statusoffline" class="font-weight-bold " :color="item.statuscolor" size="small">
<ClockHour4Icon size="15" class="mr-1" />
{{ item.status }}
</v-chip>
<v-chip rounded="sm" v-else class="font-weight-bold " :color="item.statuscolor" size="small">
<CircleIcon size="15" class="mr-1" />
{{ item.status }}
</v-chip>
</td>
<td>
<div class="text-subtitle-1 text-medium-emphasis">{{ item.email }}</div>
</td>
<td>
<div class="d-flex align-center">
<div class="d-flex gap-2">
<v-chip
v-for="team in item.teams"
:key="team.status"
rounded="sm"
:class="'font-weight-bold bg-' + team.statuscolor"
size="small"
>
{{ team.status }}
</v-chip>
</div>
</div>
</td>
</tr>
</tbody>
</v-table>
</v-card>
</UiParentCard>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,95 @@
<script setup lang="ts">
import { ref } from 'vue';
// common components
import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue';
import UiParentCard from '@/components/shared/UiParentCard.vue';
import { heightTableData, tableActionData} from '@/_mockApis/components/table/basicTables';
// template breadcrumb
const page = ref({ title: 'Height Table' });
const breadcrumbs = ref([
{
text: 'Dashboard',
disabled: false,
href: '#'
},
{
text: 'Height Table',
disabled: true,
href: '#'
}
]);
</script>
<template>
<!-- ---------------------------------------------------- -->
<!-- Table Height -->
<!-- ---------------------------------------------------- -->
<BaseBreadcrumb :title="page.title" :breadcrumbs="breadcrumbs"></BaseBreadcrumb>
<v-row>
<v-col cols="12">
<UiParentCard title="Height Table">
<v-card class="border" elevation="0">
<v-table class="month-table" height="400px">
<thead>
<tr>
<th class="text-h6 ps-6">Authors</th>
<th class="text-h6">Courses</th>
<th class="text-h6">Users</th>
<th class="text-h6"></th>
</tr>
</thead>
<tbody>
<tr v-for="item in heightTableData" :key="item.name" class="month-item">
<td class="ps-6">
<div class="d-flex gap-3 align-center">
<v-avatar size="42" rounded="md">
<img :src="item.avatar" alt="avatar" height="42" />
</v-avatar>
<div>
<h6 class="text-subtitle-1 font-weight-bold">{{ item.name }}</h6>
<div class="text-body-1 textSecondary mt-1">{{ item.handle }}
</div>
</div>
</div>
</td>
<td>
<div class="d-flex align-center">
<div class="d-flex">
<v-chip v-for="course in item.courses" :key="course.status" rounded="sm"
class="mr-2" :color="course.statuscolor" size="small">
{{ course.status }}
</v-chip>
</div>
</div>
</td>
<td>
<div class="text-subtitle-1 text-medium-emphasis">{{ item.users }}</div>
</td>
<td>
<v-btn size="30" icon variant="flat" class="grey100">
<v-avatar size="22">
<DotsIcon size="20" color="grey100" />
</v-avatar>
<v-menu activator="parent">
<v-list>
<v-list-item value="action" v-for="list in tableActionData" :key="list.listtitle"
hide-details min-height="38">
<v-list-item-title>
<v-avatar size="20" class="mr-2">
<component :is="list.icon" stroke-width="2" size="20" />
</v-avatar>
{{ list.listtitle }}
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-btn>
</td>
</tr>
</tbody>
</v-table>
</v-card>
</UiParentCard>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,99 @@
<script setup lang="ts">
import { ref } from 'vue';
import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue';
import UiParentCard from '@/components/shared/UiParentCard.vue';
import { BasicDatatables } from '@/_mockApis/components/datatable/dataTable';
const page = ref({ title: 'Basic Data Tables' });
const breadcrumbs = ref([
{
text: 'Dashboard',
disabled: false,
href: '#'
},
{
text: 'Basic Data Tables',
disabled: true,
href: '#'
}
]);
/*Header Data*/
const headers :any = ref([
{ title: 'Name', align: 'start', key: 'name' },
{ title: 'Project Name', align: 'start', key: 'project' },
{ title: 'Post', align: 'start', key: 'post' },
{ title: 'Status', align: 'start', key: 'status' },
{ title: 'Budget', align: 'end', key: 'budget' },
])
const expanded = ref();
const headersExpand :any = ref([
{ title: 'Name', align: 'start', key: 'name', sortable: false, },
{ title: 'Project Name', align: 'start', key: 'project' },
{ title: 'Post', align: 'start', key: 'post' },
{ title: 'Status', align: 'start', key: 'status' },
{ title: 'Budget', align: 'end', key: 'budget' },
{ title: '', key: 'data-table-expand' },
])
/*for status color*/
function getColor(status: string) {
if (status == 'Active') return '#13DEB9'
else if (status == 'Cancel') return '#FA896B'
else if (status == 'Completed') return '#5D87FF'
else return '#FFAE1F'
}
</script>
<template>
<BaseBreadcrumb :title="page.title" :breadcrumbs="breadcrumbs"></BaseBreadcrumb>
<v-row>
<v-col cols="12">
<UiParentCard title="Basic Table">
<v-data-table items-per-page="5" :headers="headers" :items="BasicDatatables" item-value="name"
class="border rounded-md datatabels">
</v-data-table>
</UiParentCard>
<UiParentCard title="Selection" class="mt-6 pb-0">
<v-data-table items-per-page="5" :headers="headers" :items="BasicDatatables" item-value="name" show-select
class="border rounded-md datatabels">
</v-data-table>
</UiParentCard>
<UiParentCard title="Density" class="mt-6">
<v-data-table items-per-page="5" :headers="headers" :items="BasicDatatables" item-value="name"
density="compact" class="border rounded-md datatabels">
</v-data-table>
</UiParentCard>
<UiParentCard title="Item" class="mt-6">
<v-data-table items-per-page="5" :headers="headers" :items="BasicDatatables" item-value="name"
class="border rounded-md datatabels">
<template v-slot:item.status="{ item }">
<v-chip :color="getColor(item.status)">
{{ item.status }}
</v-chip>
</template>
</v-data-table>
</UiParentCard>
<UiParentCard title="Expandable Rows" class="mt-6">
<v-data-table v-model:expanded="expanded" :headers="headersExpand" :items="BasicDatatables"
item-value="name" show-expand class="border rounded-md datatabels">
<template v-slot:expanded-row="{ columns, item }">
<tr>
<td :colspan="columns.length">
More info about {{ item.name }}
</td>
</tr>
</template>
</v-data-table>
</UiParentCard>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,272 @@
<script setup>
import { computed, nextTick, ref, watch } from 'vue';
import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue';
import UiParentCard from '@/components/shared/UiParentCard.vue';
import { Icon } from '@iconify/vue';
const page = ref({ title: 'CRUD Table' });
const breadcrumbs = ref([
{
text: 'Dashboard',
disabled: false,
href: '#'
},
{
text: 'CRUD Table',
disabled: true,
href: '#'
}
]);
const dialog = ref(false)
const dialogDelete = ref(false)
const headers = ref([
{
title: 'Dessert (100g serving)',
align: 'start',
sortable: false,
key: 'name',
},
{ title: 'Calories', key: 'calories' },
{ title: 'Fat (g)', key: 'fat' },
{ title: 'Carbs (g)', key: 'carbs' },
{ title: 'Protein (g)', key: 'protein' },
{ title: 'Actions', key: 'actions', sortable: false },
])
const desserts = ref([])
const editedIndex = ref(-1)
const editedItem = ref({
name: '',
calories: 0,
fat: 0,
carbs: 0,
protein: 0,
})
const defaultItem = ref({
name: '',
calories: 0,
fat: 0,
carbs: 0,
protein: 0,
})
const formTitle = computed(() => {
return editedIndex.value === -1 ? 'New Item' : 'Edit Item'
})
function initialize() {
desserts.value = [
{
name: 'Frozen Yogurt',
calories: 159,
fat: 6,
carbs: 24,
protein: 4,
},
{
name: 'Ice cream sandwich',
calories: 237,
fat: 9,
carbs: 37,
protein: 4.3,
},
{
name: 'Eclair',
calories: 262,
fat: 16,
carbs: 23,
protein: 6,
},
{
name: 'Cupcake',
calories: 305,
fat: 3.7,
carbs: 67,
protein: 4.3,
},
{
name: 'Gingerbread',
calories: 356,
fat: 16,
carbs: 49,
protein: 3.9,
},
{
name: 'Jelly bean',
calories: 375,
fat: 0,
carbs: 94,
protein: 0,
},
{
name: 'Lollipop',
calories: 392,
fat: 0.2,
carbs: 98,
protein: 0,
},
{
name: 'Honeycomb',
calories: 408,
fat: 3.2,
carbs: 87,
protein: 6.5,
},
{
name: 'Donut',
calories: 452,
fat: 25,
carbs: 51,
protein: 4.9,
},
{
name: 'KitKat',
calories: 518,
fat: 26,
carbs: 65,
protein: 7,
},
]
}
function editItem(item) {
editedIndex.value = desserts.value.indexOf(item)
editedItem.value = Object.assign({}, item)
dialog.value = true
}
function deleteItem(item) {
editedIndex.value = desserts.value.indexOf(item)
editedItem.value = Object.assign({}, item)
dialogDelete.value = true
}
function deleteItemConfirm() {
desserts.value.splice(editedIndex.value, 1)
closeDelete()
}
function close() {
dialog.value = false
nextTick(() => {
editedItem.value = Object.assign({}, defaultItem.value)
editedIndex.value = -1
})
}
function closeDelete() {
dialogDelete.value = false
nextTick(() => {
editedItem.value = Object.assign({}, defaultItem.value)
editedIndex.value = -1
})
}
function save() {
if (editedIndex.value > -1) {
Object.assign(desserts.value[editedIndex.value], editedItem.value)
} else {
desserts.value.push(editedItem.value)
}
close()
}
watch(dialog, val => {
val || close()
})
watch(dialogDelete, val => {
val || closeDelete()
})
initialize()
</script>
<template>
<BaseBreadcrumb :title="page.title" :breadcrumbs="breadcrumbs"></BaseBreadcrumb>
<v-row>
<v-col cols="12">
<UiParentCard title="Crud Table">
<v-data-table class="border rounded-md datatabels" :headers="headers" :items="desserts" :sort-by="[{ key: 'calories', order: 'asc' }]">
<template v-slot:top>
<v-toolbar class="bg-lightprimary" flat>
<v-toolbar-title>My Crud Table</v-toolbar-title>
<v-divider class="mx-4" inset vertical></v-divider>
<v-spacer></v-spacer>
<v-dialog v-model="dialog" max-width="500px">
<template v-slot:activator="{ props }">
<v-btn color="primary" variant="flat" dark v-bind="props" >Add New Item</v-btn>
</template>
<v-card>
<v-card-title class="pa-4 bg-primary">
<span class="text-h5">{{ formTitle }}</span>
</v-card-title>
<v-card-text>
<v-container class="px-0">
<v-row>
<v-col cols="12" sm="6" md="4">
<v-text-field v-model="editedItem.name"
label="Dessert name"></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field v-model="editedItem.calories"
label="Calories"></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field v-model="editedItem.fat" label="Fat (g)"></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field v-model="editedItem.carbs"
label="Carbs (g)"></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field v-model="editedItem.protein"
label="Protein (g)"></v-text-field>
</v-col>
</v-row>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="error" variant="flat" dark @click="close">
Cancel
</v-btn>
<v-btn color="primary" variant="flat" dark @click="save">
Save
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-dialog v-model="dialogDelete" max-width="500px">
<v-card>
<v-card-title class="text-h5 text-center py-6">Are you sure you want to delete this item?</v-card-title>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="error" variant="flat" dark @click="closeDelete">Cancel</v-btn>
<v-btn color="primary" variant="flat" dark @click="deleteItemConfirm">OK</v-btn>
<v-spacer></v-spacer>
</v-card-actions>
</v-card>
</v-dialog>
</v-toolbar>
</template>
<template v-slot:item.actions="{ item }">
<div class="d-flex gap-3">
<Icon
icon="solar:pen-new-square-broken"
height="20"
class="text-primary cursor-pointer"
size="small"
@click="editItem(item)"
/>
<Icon
icon="solar:trash-bin-minimalistic-linear"
height="20"
class="text-error cursor-pointer"
size="small"
@click="deleteItem(item)"
/>
</div>
</template>
<template v-slot:no-data>
<v-btn color="primary" @click="initialize">
Reset
</v-btn>
</template>
</v-data-table>
</UiParentCard>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,109 @@
<script setup lang="ts">
import { ref } from 'vue';
import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue';
import UiParentCard from '@/components/shared/UiParentCard.vue';
import { BasicDatatables, UppercaseFilter,Filtrable } from '@/_mockApis/components/datatable/dataTable';
const page = ref({ title: 'Data Table Filtering' });
const breadcrumbs = ref([
{
text: 'Dashboard',
disabled: false,
href: '#'
},
{
text: 'Data Table Filtering',
disabled: true,
href: '#'
}
]);
/*Header Data*/
const search = ref();
const customsearch = ref();
const headers : any = ref([
{ title: 'Name', align: 'start', key: 'name' },
{ title: 'Project Name', align: 'start', key: 'project' },
{ title: 'Post', align: 'start', key: 'post' },
{ title: 'Status', align: 'start', key: 'status' },
{ title: 'Budget', align: 'end', key: 'budget' },
])
const filtrable = ref('')
function filterOnlyCapsText(value: { toString: () => string; } | null, query: string | null, item: any) {
return value != null &&
query != null &&
typeof value === 'string' &&
value.toString().toLocaleUpperCase().indexOf(query) !== -1
}
</script>
<template>
<BaseBreadcrumb :title="page.title" :breadcrumbs="breadcrumbs"></BaseBreadcrumb>
<v-row>
<v-col cols="12">
<UiParentCard title="Basic Filter">
<v-text-field v-model="search" append-inner-icon="mdi-magnify" label="Search" single-line hide-details
class="mb-5" />
<v-data-table items-per-page="5" :headers="headers" :items="BasicDatatables" :search="search"
class="border rounded-md datatabels">
</v-data-table>
</UiParentCard>
<UiParentCard title="Custom Filter" class="mt-6">
<v-text-field v-model="customsearch" append-inner-icon="mdi-magnify" label="Search (UPPER CASE ONLY)"
single-line hide-details class="mb-5" />
<v-data-table items-per-page="5" :headers="headers" :items="UppercaseFilter" :search="customsearch"
:custom-filter="filterOnlyCapsText" class="border rounded-md datatabels">
</v-data-table>
</UiParentCard>
<UiParentCard title="Filterable" class="mt-6">
<v-card flat>
<v-card-title class="d-flex align-center px-0 pb-3">
My Table
<v-spacer></v-spacer>
<v-text-field v-model="filtrable" prepend-inner-icon="mdi-magnify" density="compact" label="Search"
single-line flat hide-details variant="solo-filled"></v-text-field>
</v-card-title>
<v-divider></v-divider>
<v-data-table v-model:search="filtrable" :items="Filtrable">
<template v-slot:header.stock>
<div class="text-end">Stock</div>
</template>
<template v-slot:item.image="{ item }">
<v-card class="my-2" elevation="2">
<v-img :src="`${item.image}`"
height="80" class="rounded-md" cover></v-img>
</v-card>
</template>
<template v-slot:item.rating="{ item }">
<v-rating :model-value="item.rating" color="warning" density="compact" size="small"
readonly></v-rating>
</template>
<template v-slot:item.stock="{ item }">
<div class="text-end">
<v-chip :color="item.stock ? 'success' : 'error'"
:text="item.stock ? 'In stock' : 'Out of stock'" class="text-uppercase" label
size="small"></v-chip>
</div>
</template>
</v-data-table>
</v-card>
</UiParentCard>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,43 @@
<script setup lang="ts">
import { ref } from 'vue';
import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue';
import UiParentCard from '@/components/shared/UiParentCard.vue';
import {BasicDatatables} from '@/_mockApis/components/datatable/dataTable';
const page = ref({ title: 'Data Tables Grouping' });
const breadcrumbs = ref([
{
text: 'Dashboard',
disabled: false,
href: '#'
},
{
text: 'Data Tables Grouping',
disabled: true,
href: '#'
}
]);
/*Header Data*/
const sortBy : any = ref([
{ key: 'name', order: 'asc' }
])
const groupBy : any = ref([
{ key: 'status', order: 'asc' }
])
</script>
<template>
<BaseBreadcrumb :title="page.title" :breadcrumbs="breadcrumbs"></BaseBreadcrumb>
<v-row>
<v-col cols="12">
<UiParentCard title="Grouping">
<v-data-table items-per-page="5" :items="BasicDatatables" item-value="name"
:group-by="groupBy" :sort-by="sortBy"
class="border rounded-md datatabels">
</v-data-table>
</UiParentCard>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,40 @@
<script setup>
import { ref } from 'vue';
import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue';
import UiParentCard from '@/components/shared/UiParentCard.vue';
import { BasicDatatables } from '@/_mockApis/components/datatable/dataTable';
const page = ref({ title: 'Data Table Headers' });
const breadcrumbs = ref([
{
text: 'Dashboard',
disabled: false,
href: '#'
},
{
text: 'Data Table Headers',
disabled: true,
href: '#'
}
]);
</script>
<template>
<BaseBreadcrumb :title="page.title" :breadcrumbs="breadcrumbs"></BaseBreadcrumb>
<v-row>
<v-col cols="12">
<UiParentCard title="Column Slot">
<v-data-table items-per-page="5" :items="BasicDatatables" item-value="name"
class="border rounded-md datatabels">
<template v-slot:column.name="{ column }">
{{ column.title.toUpperCase() }}
</template>
</v-data-table>
</UiParentCard>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,58 @@
<script setup lang="ts">
import { ref,computed } from 'vue';
import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue';
import UiParentCard from '@/components/shared/UiParentCard.vue';
import { BasicDatatables } from '@/_mockApis/components/datatable/dataTable';
const page = ref({ title: 'Data Table Pagination' });
const breadcrumbs = ref([
{
text: 'Dashboard',
disabled: false,
href: '#'
},
{
text: 'Data Table Pagination',
disabled: true,
href: '#'
}
]);
/*Header Data*/
const pagination = ref(1);
const itemsPerPage = ref(5);
const headers : any = ref([
{ title: 'Name', align: 'start', key: 'name' },
{ title: 'Project Name', align: 'start', key: 'project' },
{ title: 'Post', align: 'start', key: 'post' },
{ title: 'Status', align: 'start', key: 'status' },
{ title: 'Budget', align: 'end', key: 'budget' },
])
/*page count*/
const pageCount = Math.ceil(BasicDatatables.length / itemsPerPage.value)
</script>
<template>
<BaseBreadcrumb :title="page.title" :breadcrumbs="breadcrumbs"></BaseBreadcrumb>
<v-row>
<v-col cols="12">
<UiParentCard title="External Pagination">
<v-data-table :items-per-page="itemsPerPage" :headers="headers" :items="BasicDatatables" v-model:page="pagination"
hide-default-footer class="border rounded-md datatabels">
<template v-slot:bottom>
<div class="text-center pt-2 mb-3 px-3">
<v-pagination v-model="pagination" :length="pageCount"></v-pagination>
<v-text-field :model-value="itemsPerPage" class="pa-2" label="Items per page" type="number"
min="-1" max="15" hide-details
@update:model-value="itemsPerPage = parseInt($event, 10)"></v-text-field>
</div>
</template>
</v-data-table>
</UiParentCard>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,60 @@
<script setup lang="ts">
import { ref } from 'vue';
import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue';
import UiParentCard from '@/components/shared/UiParentCard.vue';
import { SelectedRow, BasicDatatables } from '@/_mockApis/components/datatable/dataTable';
const page = ref({ title: 'Data Tables Selection' });
const selected = ref();
const breadcrumbs = ref([
{
text: 'Dashboard',
disabled: false,
href: '#'
},
{
text: 'Data Tables Selection',
disabled: true,
href: '#'
}
]);
/*Header Data*/
const headers :any = ref([
{ title: 'Name', align: 'start', key: 'name' },
{ title: 'Project Name', align: 'start', key: 'project' },
{ title: 'Post', align: 'start', key: 'post' },
{ title: 'Status', align: 'start', key: 'status' },
{ title: 'Budget', align: 'end', key: 'budget' },
])
</script>
<template>
<BaseBreadcrumb :title="page.title" :breadcrumbs="breadcrumbs"></BaseBreadcrumb>
<v-row>
<v-col cols="12">
<UiParentCard title="Basic Selection" class="">
<v-data-table items-per-page="5" :headers="headers" :items="BasicDatatables" item-value="name" show-select
class="border rounded-md datatabels">
</v-data-table>
</UiParentCard>
<UiParentCard title="Selected Values" class="mt-6">
<v-data-table items-per-page="5" :headers="headers" :items="BasicDatatables" item-value="name"
v-model="selected" return-object show-select class="border rounded-md datatabels">
</v-data-table>
<v-card class="elevation-0 border mt-3 pa-4">
<pre>{{ selected }}</pre>
</v-card>
</UiParentCard>
<UiParentCard title="Selectable Rows" class="mt-6">
<v-data-table items-per-page="5" :headers="headers" :items="SelectedRow" item-value="name"
item-selectable="selectable" show-select class="border rounded-md datatabels">
</v-data-table>
</UiParentCard>
<UiParentCard title="Select Strategies" class="mt-6">
<v-data-table items-per-page="5" :headers="headers" :items="BasicDatatables" item-value="name"
select-strategy="single" show-select class="border rounded-md datatabels">
</v-data-table>
</UiParentCard>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,50 @@
<script setup >
import { computed, ref } from 'vue';
import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue';
import UiParentCard from '@/components/shared/UiParentCard.vue';
import { BasicDatatables } from '@/_mockApis/components/datatable/dataTable';
const page = ref({ title: 'Data Table Slots' });
const breadcrumbs = ref([
{
text: 'Dashboard',
disabled: false,
href: '#'
},
{
text: 'Data Table Slots',
disabled: true,
href: '#'
}
]);
/*Header Data*/
const headers = ref([
{ title: 'Name', align: 'start', key: 'name', sortable: false, },
{ title: 'Project Name', align: 'start', key: 'project' },
{ title: 'Post', align: 'start', key: 'post' },
{ title: 'Status', align: 'start', key: 'status' },
{ title: 'Budget', align: 'end', key: 'budget' },
])
</script>
<template>
<BaseBreadcrumb :title="page.title" :breadcrumbs="breadcrumbs"></BaseBreadcrumb>
<v-row>
<v-col cols="12">
<UiParentCard title="Item Slot">
<v-data-table :headers="headers" :items="BasicDatatables" item-value="name" class="border rounded-md datatabels">
<template v-slot:header.id="{ item }">
<tr>
<td class="text-subtitle-1">{{ item.columns.name }}</td>
<td class="text-subtitle-1">{{ item.columns.project }}</td>
<td class="text-subtitle-1">{{ item.columns.post }}</td>
<td class="text-subtitle-1">{{ item.columns.status }}</td>
<td class="d-flex justify-end align-center text-subtitle-1">{{ item.columns.budget }}</td>
</tr>
</template>
</v-data-table>
</UiParentCard>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,53 @@
<script setup lang="ts">
import { ref } from 'vue';
import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue';
import UiParentCard from '@/components/shared/UiParentCard.vue';
import { BasicDatatables } from '@/_mockApis/components/datatable/dataTable';
const page = ref({ title: 'Data Table Sorting' });
const breadcrumbs = ref([
{
text: 'Dashboard',
disabled: false,
href: '#'
},
{
text: 'Data Table Sorting',
disabled: true,
href: '#'
}
]);
/*Header Data*/
const sortBy:any = ref([
{ key: 'name', order: 'desc' }
])
const headers : any = ref([
{ title: 'Name', align: 'start', key: 'name', sortable: false },
{ title: 'Project Name', align: 'start', key: 'project' },
{ title: 'Post', align: 'start', key: 'post' },
{ title: 'Status', align: 'start', key: 'status' },
{ title: 'Budget', align: 'end', key: 'budget' },
])
</script>
<template>
<BaseBreadcrumb :title="page.title" :breadcrumbs="breadcrumbs"></BaseBreadcrumb>
<v-row>
<v-col cols="12">
<UiParentCard title="Basic Sorting">
<v-data-table items-per-page="5" :headers="headers" :items="BasicDatatables" item-value="name"
v-model:sort-by="sortBy" class="border rounded-md datatabels">
</v-data-table>
<v-card class="mt-4 elevation-0 border mt-3 pa-4">
<pre>{{ sortBy }}</pre>
</v-card>
</UiParentCard>
<UiParentCard title="Multi Sorting" class="mt-6">
<v-data-table items-per-page="5" :headers="headers" :items="BasicDatatables"
:sort-by="[{ key: 'project', order: 'asc' }, { key: 'post', order: 'desc' }]" multi-sort
class="border rounded-md datatabels">
</v-data-table>
</UiParentCard>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,84 @@
<script setup lang="ts">
import { ref } from 'vue';
// common components
import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue';
import UiParentCard from '@/components/shared/UiParentCard.vue';
import UiChildCard from '@/components/shared/UiChildCard.vue';
import FilledColor from '@/components/ui-components/chip/FilledColor.vue';
import Outlined from '@/components/ui-components/chip/Outlined.vue';
import CustomIcon from '@/components/ui-components/chip/CustomIcon.vue';
import CustomIconOutlined from '@/components/ui-components/chip/CustomIconOutlined.vue';
import Disabled from '@/components/ui-components/chip/Disabled.vue';
import Sizes from '@/components/ui-components/chip/Sizes.vue';
import Closable from '@/components/ui-components/chip/Closable.vue';
// template breadcrumb
const page = ref({ title: 'Chip' });
const breadcrumbs = ref([
{
text: 'Dashboard',
disabled: false,
href: '#'
},
{
text: 'Chip',
disabled: true,
href: '#'
}
]);
</script>
<template>
<BaseBreadcrumb :title="page.title" :breadcrumbs="breadcrumbs"></BaseBreadcrumb>
<v-row>
<v-col cols="12">
<UiParentCard title="Chip">
<v-row>
<!-- Filled Color -->
<v-col cols="12" >
<UiChildCard title="Filled">
<FilledColor/>
</UiChildCard>
</v-col>
<!-- Outlined -->
<v-col cols="12" >
<UiChildCard title="Outlined">
<Outlined/>
</UiChildCard>
</v-col>
<!-- Label with Icon -->
<v-col cols="12" lg="6">
<UiChildCard title="Custom Icon">
<CustomIcon/>
</UiChildCard>
</v-col>
<!-- Outlined Color -->
<v-col cols="12" lg="6">
<UiChildCard title="Custom Outlined Icon">
<CustomIconOutlined/>
</UiChildCard>
</v-col>
<!-- Disabled -->
<v-col cols="12" lg="6">
<UiChildCard title="Disabled">
<Disabled/>
</UiChildCard>
</v-col>
<!-- Sizes -->
<v-col cols="12" lg="6">
<UiChildCard title="Sizes">
<Sizes/>
</UiChildCard>
</v-col>
<!-- Closable -->
<v-col cols="12" >
<UiChildCard title="Closable">
<Closable/>
</UiChildCard>
</v-col>
</v-row>
</UiParentCard>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,84 @@
<script setup lang="ts">
import { ref } from 'vue';
// common components
import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue';
import UiParentCard from '@/components/shared/UiParentCard.vue';
import UiChildCard from '@/components/shared/UiChildCard.vue';
import DialogsActivator from '@/components/ui-components/dialogs/DialogsActivator.vue';
import DialogsModel from '@/components/ui-components/dialogs/DialogsModel.vue';
import DialogsFullscreen from '@/components/ui-components/dialogs/DialogsFullscreen.vue';
import DialogsTransitions from '@/components/ui-components/dialogs/DialogsTransitions.vue';
import DialogsPersistent from '@/components/ui-components/dialogs/DialogsPersistent.vue';
import DialogsScrollable from '@/components/ui-components/dialogs/DialogsScrollable.vue';
import DialogsForm from '@/components/ui-components/dialogs/DialogsForm.vue';
import DialogsNested from '@/components/ui-components/dialogs/DialogsNested.vue';
// template breadcrumb
const page = ref({ title: 'Dialog' });
const breadcrumbs = ref([
{
text: 'Dashboard',
disabled: false,
href: '#'
},
{
text: 'Dialog',
disabled: true,
href: '#'
}
]);
</script>
<template>
<BaseBreadcrumb :title="page.title" :breadcrumbs="breadcrumbs"></BaseBreadcrumb>
<v-row>
<v-col cols="12">
<UiParentCard title="Dialog">
<v-row>
<v-col cols="12" sm="12" lg="4">
<UiChildCard title="Simple">
<DialogsActivator />
</UiChildCard>
</v-col>
<v-col cols="12" sm="12" lg="4">
<UiChildCard title="V-model">
<DialogsModel />
</UiChildCard>
</v-col>
<v-col cols="12" sm="12" lg="4" class="d-flex align-items-stretch">
<UiChildCard title="Transition">
<DialogsTransitions />
</UiChildCard>
</v-col>
<v-col cols="12" sm="12" lg="4" class="d-flex align-items-stretch">
<UiChildCard title="Form">
<DialogsForm />
</UiChildCard>
</v-col>
<v-col cols="12" sm="12" lg="4" class="d-flex align-items-stretch">
<UiChildCard title="Full screen">
<DialogsFullscreen />
</UiChildCard>
</v-col>
<v-col cols="12" sm="12" lg="4" class="d-flex align-items-stretch">
<UiChildCard title="Persistent">
<DialogsPersistent />
</UiChildCard>
</v-col>
<v-col cols="12" sm="12" lg="4" class="d-flex align-items-stretch">
<UiChildCard title="Scrollable">
<DialogsScrollable />
</UiChildCard>
</v-col>
<v-col cols="12" sm="12" lg="4" class="d-flex align-items-stretch">
<UiChildCard title="Nested Dialog">
<DialogsNested />
</UiChildCard>
</v-col>
</v-row>
</UiParentCard>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,80 @@
<script setup lang="ts">
import { ref } from 'vue';
/* Breadcrumb component */
import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue';
import BlogCards from "@/components/widgets/cards/BlogCards.vue";
import ProductCards from "@/components/widgets/cards/ProductCards.vue";
import MusicCards from "@/components/widgets/cards/MusicCards.vue";
import FollowerCards from "@/components/widgets/cards/FollowerCards.vue";
import UserCards from "@/components/widgets/cards/UserCards.vue";
import ProfileCards from "@/components/widgets/cards/ProfileCards.vue";
import Settings from "@/components/widgets/cards/Settings.vue";
import GiftCards from "@/components/widgets/cards/GiftCards.vue";
import UpcommingActivityCard from "@/components/widgets/cards/UpcommingActivityCard.vue";
// import DailyActivities from '@/components/dashboards/dashboard2/DailyActivities.vue';
import PaymentGateways from '@/components/widgets/cards/PaymentGateways.vue';
// template breadcrumb
const page = ref({ title: 'Cards Widgets' });
const breadcrumbs = ref([
{
text: 'Home',
disabled: false,
href: '#'
},
{
text: 'Cards Widgets',
disabled: true,
href: '#'
}
]);
</script>
<template>
<BaseBreadcrumb :title="page.title" :breadcrumbs="breadcrumbs"></BaseBreadcrumb>
<v-row>
<!-- Blog cards -->
<v-col cols="12">
<BlogCards/>
</v-col>
<!-- Product cards -->
<v-col cols="12">
<ProductCards/>
</v-col>
<!-- Music cards -->
<v-col cols="12">
<MusicCards/>
</v-col>
<!-- Follower cards -->
<v-col cols="12">
<FollowerCards/>
</v-col>
<!-- User cards -->
<v-col cols="12">
<UserCards/>
</v-col>
<!-- Profile cards -->
<v-col cols="12">
<ProfileCards/>
</v-col>
<!-- Settings cards -->
<v-col cols="12" md="4">
<Settings/>
</v-col>
<!-- Gift cards -->
<v-col cols="12" md="8">
<GiftCards/>
</v-col>
<!-- Payment Gateways card -->
<v-col cols="12" md="4">
<PaymentGateways/>
</v-col>
<!-- Upcomming Activity card -->
<v-col cols="12" md="4">
<UpcommingActivityCard/>
</v-col>
<!-- Recent Transactions -->
<v-col cols="12" md="4">
<DailyActivities/>
</v-col>
</v-row>
</template>

View File

@@ -0,0 +1,12 @@
import { defineStore } from "pinia"
export const useSettingStore = defineStore('setting',{
state:(): any => ({
typeUser:[],
}),
actions:{
async getTypeUser(body:Record<string,any>){
// console.log("ini di pinia:",body)
this.typeUser = body
}
}
})

15
vueform.config.js Normal file
View File

@@ -0,0 +1,15 @@
// vueform.config.(js|ts)
import en from '@vueform/vueform/locales/en'
import vueform from '@vueform/vueform/dist/vueform'
import { defineConfig } from '@vueform/vueform'
// You might place these anywhere else in your project
import '@vueform/vueform/dist/vueform.css';
export default defineConfig({
theme: vueform,
locales: { en },
locale: 'en',
})