first commit

This commit is contained in:
Yusron alamsyah
2026-03-26 09:11:29 +07:00
commit 1f94c60e71
582 changed files with 46459 additions and 0 deletions
+119
View File
@@ -0,0 +1,119 @@
<script setup lang="ts">
import { ref } from "vue";
// import { useAuthStore } from '@/store/auth';
import { Form } from "vee-validate";
/*Social icons*/
import google from "@/assets/images/svgs/google-icon.svg";
import facebook from "@/assets/images/svgs/facebook-icon.svg";
const checkbox = ref(false);
const valid = ref(false);
const show1 = ref(false);
const password = ref("admin123");
const username = ref("info@wrappixel.com");
const passwordRules = ref([
(v: string) => !!v || "Password is required",
(v: string) =>
(v && v.length <= 10) || "Password must be less than 10 characters"
]);
const emailRules = ref([
(v: string) => !!v || "E-mail is required",
(v: string) => /.+@.+\..+/.test(v) || "E-mail must be valid"
]);
function validate(values: any, { setErrors }: any) {
// const authStore = useAuthStore();
// return authStore.login(username.value, password.value).catch((error) => setErrors({ apiError: error }));
}
</script>
<template>
<v-row class="d-flex mb-3">
<v-col cols="6" sm="6" class="pr-2">
<v-btn
variant="outlined"
size="large"
class="border text-subtitle-1 font-weight-semibold hover-link-primary"
block
>
<img :src="facebook" width="20" class="mr-1" alt="facebook" />
<span class="d-md-flex d-none mr-1">Sign in with</span> Facebook
</v-btn>
</v-col>
<v-col cols="6" sm="6" class="pl-2">
<v-btn
variant="outlined"
size="large"
class="border text-subtitle-1 font-weight-semibold hover-link-primary"
blocks
>
<img :src="google" height="16" class="mr-2" alt="google" />
<span class="d-md-flex d-none mr-1">Sign in with</span> Google
</v-btn>
</v-col>
</v-row>
<div class="d-flex align-center text-center mb-6">
<div
class="text-h6 w-100 px-5 font-weight-regular auth-divider position-relative"
>
<span class="bg-surface px-5 py-3 position-relative textSecondary"
>Or sign in with email</span
>
</div>
</div>
<Form @submit="validate" v-slot="{ errors, isSubmitting }" class="mt-5">
<v-label class="font-weight-semibold pb-2">Username</v-label>
<VTextField
v-model="username"
:rules="emailRules"
class="mb-8"
required
hide-details="auto"
></VTextField>
<div class="d-flex justify-space-between align-center pb-2">
<v-label class="font-weight-semibold">Password</v-label>
<RouterLink
to="/auth/forgot-password2"
class="text-primary text-decoration-none font-weight-medium"
>Forgot Password ?</RouterLink
>
</div>
<VTextField
v-model="password"
:rules="passwordRules"
required
hide-details="auto"
type="password"
class="pwdInput"
></VTextField>
<div class="d-flex flex-wrap align-center my-3 ml-n2">
<v-checkbox
class="pe-2"
v-model="checkbox"
:rules="[(v: any) => !!v || 'You must agree to continue!']"
required
hide-details
color="primary"
>
<template v-slot:label class="font-weight-medium"
>Keep me logged in</template
>
</v-checkbox>
</div>
<v-btn
size="large"
:loading="isSubmitting"
color="darkgray"
:disabled="valid"
block
type="submit"
flat
>Sign In</v-btn
>
<div v-if="errors.apiError" class="mt-2">
<v-alert color="error">{{ errors.apiError }}</v-alert>
</div>
</Form>
</template>
+61
View File
@@ -0,0 +1,61 @@
<script setup lang="ts">
import { ref } from 'vue';
import Logo from '@/layouts/full/logo/Logo.vue';
/*Social icons*/
import google from '@/assets/images/svgs/google-icon.svg';
import facebook from '@/assets/images/svgs/facebook-icon.svg';
const checkbox = ref(false);
const valid = ref(true);
const show1 = ref(false);
const password = ref('');
const email = ref('');
const passwordRules = ref([
(v: string) => !!v || 'Password is required',
(v: string) => (v && v.length <= 10) || 'Password must be less than 10 characters'
]);
const emailRules = ref([(v: string) => !!v || 'E-mail is required', (v: string) => /.+@.+\..+/.test(v) || 'E-mail must be valid']);
const fname = ref('');
const fnameRules = ref([
(v: string) => !!v || 'Name is required',
(v: string) => (v && v.length <= 10) || 'Name must be less than 10 characters'
]);
</script>
<template>
<v-row class="d-flex mb-6">
<v-col cols="6" sm="6" class="pr-2">
<v-btn variant="outlined" size="large" class="border text-subtitle-1 font-weight-semibold hover-link-primary" block>
<img :src="facebook" width="20" class="mr-1" alt="facebook" />
<span class="d-md-flex d-none mr-1">Sign in with</span> Facebook
</v-btn>
</v-col>
<v-col cols="6" sm="6" class="pl-2">
<v-btn variant="outlined" size="large" class="border text-subtitle-1 font-weight-semibold hover-link-primary" block>
<img :src="google" height="16" class="mr-2" alt="google" />
<span class="d-md-flex d-none mr-1">Sign in with</span> Google
</v-btn>
</v-col>
</v-row>
<div class="d-flex align-center text-center mb-6">
<div class="text-h6 w-100 px-5 font-weight-regular auth-divider position-relative">
<span class="bg-surface px-5 py-3 position-relative">Or sign up with email</span>
</div>
</div>
<v-form ref="form" v-model="valid" lazy-validation action="/pages/boxedlogin" class="mt-5">
<v-label class="font-weight-medium pb-2">Name</v-label>
<VTextField v-model="fname" :rules="fnameRules" required ></VTextField>
<v-label class="font-weight-medium pb-2">Email Adddress</v-label>
<VTextField v-model="email" :rules="emailRules" required ></VTextField>
<v-label class="font-weight-medium pb-2">Password</v-label>
<VTextField
v-model="password"
:counter="10"
:rules="passwordRules"
required
variant="outlined"
type="password"
color="primary"
></VTextField>
<v-btn size="large" class="mt-2" color="darkgray" block submit flat>Sign Up</v-btn>
</v-form>
</template>
+75
View File
@@ -0,0 +1,75 @@
<script setup lang="ts">
import { ref } from 'vue';
import { Form } from 'vee-validate';
/*Social icons*/
import google from '@/assets/images/svgs/google-icon.svg';
import facebook from '@/assets/images/svgs/facebook-icon.svg';
const checkbox = ref(false);
const valid = ref(false);
const show1 = ref(false);
const password = ref('admin123');
const username = ref('info@wrappixel.com');
const passwordRules = ref([
(v: string) => !!v || 'Password is required',
(v: string) => (v && v.length <= 10) || 'Password must be less than 10 characters'
]);
const emailRules = ref([(v: string) => !!v || 'E-mail is required', (v: string) => /.+@.+\..+/.test(v) || 'E-mail must be valid']);
</script>
<template>
<v-row class="d-flex mb-3">
<v-col cols="6" sm="6" class="pr-2">
<v-btn variant="outlined" size="large" class="border text-subtitle-1 hover-link-primary" block>
<img :src="google" height="16" class="mr-2" alt="google" />
Google
</v-btn>
</v-col>
<v-col cols="6" sm="6" class="pl-2">
<v-btn variant="outlined" size="large" class="border text-subtitle-1 hover-link-primary" block>
<img :src="facebook" width="20" class="mr-1" alt="facebook" />
Facebook
</v-btn>
</v-col>
</v-row>
<div class="d-flex align-center text-center mb-6">
<div class="text-h6 w-100 px-5 font-weight-regular auth-divider position-relative">
<span class="bg-surface px-5 py-3 position-relative">or sign in with</span>
</div>
</div>
<Form class="mt-5">
<v-label class="font-weight-semibold pb-2 ">Username</v-label>
<VTextField
v-model="username"
:rules="emailRules"
class="mb-8"
required
hide-details="auto"
></VTextField>
<v-label class="font-weight-semibold pb-2 ">Password</v-label>
<VTextField
v-model="password"
:rules="passwordRules"
required
hide-details="auto"
type="password"
class="pwdInput"
></VTextField>
<div class="d-flex flex-wrap align-center my-3 ml-n2">
<v-checkbox class="pe-2" v-model="checkbox" :rules="[(v:any) => !!v || 'You must agree to continue!']" required hide-details color="primary">
<template v-slot:label class="font-weight-medium">Remeber this Device</template>
</v-checkbox>
<div class="ml-sm-auto">
<RouterLink to="" class="text-primary text-decoration-none font-weight-medium"
>Forgot Password ?</RouterLink
>
</div>
</div>
<v-btn size="large" color="primary" :disabled="valid" block type="submit" flat>Sign In</v-btn>
<div class="mt-2">
<v-alert color="error"></v-alert>
</div>
</Form>
</template>
+61
View File
@@ -0,0 +1,61 @@
<script setup lang="ts">
import { ref } from 'vue';
import Logo from '~/components/layout/full/logo/Logo.vue';
/*Social icons*/
import google from '~/assets/images/svgs/google-icon.svg';
import facebook from '~/assets/images/svgs/facebook-icon.svg';
const checkbox = ref(false);
const valid = ref(true);
const show1 = ref(false);
const password = ref('');
const email = ref('');
const passwordRules = ref([
(v: string) => !!v || 'Password is required',
(v: string) => (v && v.length <= 10) || 'Password must be less than 10 characters'
]);
const emailRules = ref([(v: string) => !!v || 'E-mail is required', (v: string) => /.+@.+\..+/.test(v) || 'E-mail must be valid']);
const fname = ref('');
const fnameRules = ref([
(v: string) => !!v || 'Name is required',
(v: string) => (v && v.length <= 10) || 'Name must be less than 10 characters'
]);
</script>
<template>
<v-row class="d-flex mb-6">
<v-col cols="6" sm="6" class="pr-2">
<v-btn variant="outlined" size="large" class="border text-subtitle-1 hover-link-primary" block>
<img :src="google" height="16" class="mr-2" alt="google" />
Google
</v-btn>
</v-col>
<v-col cols="6" sm="6" class="pl-2">
<v-btn variant="outlined" size="large" class="border text-subtitle-1 hover-link-primary" block>
<img :src="facebook" width="20" class="mr-1" alt="facebook" />
Facebook
</v-btn>
</v-col>
</v-row>
<div class="d-flex align-center text-center mb-6">
<div class="text-h6 w-100 px-5 font-weight-regular auth-divider position-relative">
<span class="bg-surface px-5 py-3 position-relative">or sign in with</span>
</div>
</div>
<v-form ref="form" v-model="valid" lazy-validation action="/pages/boxedlogin" class="mt-5">
<v-label class=" font-weight-medium pb-2">Name</v-label>
<VTextField v-model="fname" :rules="fnameRules" required ></VTextField>
<v-label class=" font-weight-medium pb-2">Email Adddress</v-label>
<VTextField v-model="email" :rules="emailRules" required ></VTextField>
<v-label class=" font-weight-medium pb-2">Password</v-label>
<VTextField
v-model="password"
:counter="10"
:rules="passwordRules"
required
variant="outlined"
type="password"
color="primary"
></VTextField>
<v-btn size="large" class="mt-2" color="primary" block submit flat>Sign Up</v-btn>
</v-form>
</template>
+15
View File
@@ -0,0 +1,15 @@
<script setup lang="ts">
import { ref } from 'vue';
import Logo from '@/layouts/full/logo/Logo.vue';
const valid = ref(true);
const show1 = ref(false);
const email = ref('');
const emailRules = ref([(v: string) => !!v || 'E-mail is required', (v: string) => /.+@.+\..+/.test(v) || 'E-mail must be valid']);
</script>
<template>
<v-form ref="form" v-model="valid" lazy-validation action="/dashboards/analytical" class="mt-6">
<v-label class="font-weight-semibold pb-2">Email Address</v-label>
<VTextField v-model="email" :rules="emailRules" required ></VTextField>
<v-btn size="large" color="darkgray" to="/" block submit flat>Forgot Password</v-btn>
</v-form>
</template>
+18
View File
@@ -0,0 +1,18 @@
<template>
<div class="mt-6">
<v-label class="text-subtitle-1 font-weight-semibold pb-2 text-lightText">Type your 6 digits security code</v-label>
<div class="d-flex justify-space-between gap-3 mb-2 verification">
<VTextField></VTextField>
<VTextField></VTextField>
<VTextField></VTextField>
<VTextField></VTextField>
<VTextField></VTextField>
<VTextField></VTextField>
</div>
<v-btn color="darkgray" size="large" block flat>Verify My Account</v-btn>
<h6 class="text-16 text-medium-emphasis d-flex align-center mt-6" >
Didn't get the code?
<RouterLink to="/" class="pl-0 text-primary text-16 opacity-1 pl-2 text-decoration-none"> Resend</RouterLink>
</h6>
</div>
</template>
+45
View File
@@ -0,0 +1,45 @@
<script setup lang="ts">
import { BlogCardData } from '@/data/dashboard/dashboardData';
</script>
<template>
<v-row>
<v-col cols="12" lg="4" v-for="card in BlogCardData" :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-grey100" size="small" rounded="sm" v-text="card.category"></v-chip>
<h5 class="text-h5 text-13 my-6 custom-text-primary">
<NuxtLink class="text-decoration-none color-inherits custom-title" :to="card.link">{{ card.title }}</NuxtLink>
</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 text-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 text-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 text-textSecondary" v-text="card.time"></span>
</div>
</div>
</v-card-item>
</div>
</v-card>
</v-col>
</v-row>
</template>
+35
View File
@@ -0,0 +1,35 @@
<script setup lang="ts">
import { DailyActivitiesData } from '@/data/dashboard/dashboardData';
import { Icon } from '@iconify/vue';
</script>
<template>
<v-card elevation="10">
<v-card-item>
<v-card-title class="text-h5">Daily activities</v-card-title>
<div class="daily-activities mt-8 px-3">
<div v-for="list in DailyActivitiesData" :key="list.title">
<v-row class="d-flex mb-1">
<v-col cols="4" lg="3" md="auto" sm="auto" class="px-0 pt-0 pb-0 d-flex align-start">
<p class="text-body-1 text-textSecondary text-no-wrap">{{ list.title }}</p>
</v-col>
<v-col cols="1" sm="1" class="px-0 text-center pt-0 pb-0 mt-1">
<Icon icon="tabler:circle-filled" size="13" :class="'text-' + list.textcolor" />
<div v-if="list.line" class="line mx-auto bg-grey100"></div>
</v-col>
<v-col cols="7" sm="8" class="pt-0 pb-0">
<h6 v-if="list.boldtext" class="text-body-1 text-textPrimary">{{ list.subtitle }}</h6>
<p v-else class="text-body-1 text-textPrimary">{{ list.subtitle }}</p>
<div class="mt-n1">
<NuxtLink :to="list.url" class="text-body-1 text-primary text-decoration-none" v-if="list.link">{{
list.link
}}</NuxtLink>
</div>
</v-col>
</v-row>
</div>
</div>
</v-card-item>
</v-card>
</template>
+21
View File
@@ -0,0 +1,21 @@
<script setup lang="ts">
import { Icon } from '@iconify/vue';
</script>
<template>
<v-card elevation="10">
<v-card-item>
<div class="d-flex ga-3 align-center">
<v-avatar size="48" class="rounded-md bg-lightsecondary">
<Icon icon="solar:football-outline" class="text-secondary" height="25" />
</v-avatar>
<h6 class="text-h6 heading">New Customers</h6>
</div>
<div class="d-flex align-center justify-space-between mb-3 mt-12">
<h5 class="text-textPrimary text-subtitle-1 font-weight-medium">New Goals</h5>
<div class="text-textPrimary text-subtitle-1 font-weight-medium">83%</div>
</div>
<v-progress-linear model-value="83" height="7" color="secondary" bg-color="lightsecondary" rounded></v-progress-linear>
</v-card-item>
</v-card>
</template>
+115
View File
@@ -0,0 +1,115 @@
<script setup lang="ts">
import { ref } from 'vue';
import { computed } from 'vue';
import { Icon } from '@iconify/vue';
const select = ref('Sept 2025');
const items = ref(['Sept 2025', 'Oct 2025', 'Nov 2025']);
/* Chart */
const chartOptions = computed(() => {
return {
chart: {
toolbar: {
show: false
},
type: 'bar',
fontFamily: 'inherit',
foreColor: '#adb0bb',
height: 285,
stacked: true,
offsetX: -15
},
colors: ['rgba(var(--v-theme-primary))', 'rgba(var(--v-theme-error))'],
plotOptions: {
bar: {
horizontal: false,
barHeight: '60%',
columnWidth: '15%',
borderRadius: [6],
borderRadiusApplication: 'end',
borderRadiusWhenStacked: 'all'
}
},
dataLabels: {
enabled: false
},
legend: {
show: false
},
grid: {
show: true,
padding: {
top: 0,
bottom: 0,
right: 0
},
borderColor: 'rgba(0,0,0,0.05)',
xaxis: {
lines: {
show: true
}
},
yaxis: {
lines: {
show: true
}
}
},
yaxis: {
min: -5,
max: 5,
tickAmount: 4
},
xaxis: {
axisBorder: {
show: false
},
axisTicks: {
show: false
},
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'July', 'Aug', 'Sep'],
labels: {
style: { fontSize: '13px', colors: '#adb0bb', fontWeight: '400' }
}
},
tooltip: {
theme: 'dark'
}
};
});
const Chart = {
series: [
{
name: '2025',
data: [1.2, 2.7, 1, 3.6, 2.1, 2.7, 2.2, 1.3, 2.5]
},
{
name: '2023',
data: [-2.8, -1.1, -2.5, -1.5, -2.3, -1.9, -1, -2.1, -1.3]
}
]
};
</script>
<template>
<v-card elevation="10">
<v-card-item>
<div class="d-md-flex justify-space-between mb-mb-0 mb-3">
<v-card-title class="text-h5">Revenue Forecast</v-card-title>
<div>
<v-select
v-model="select"
:items="items"
variant="outlined"
density="compact"
class="text-body-1"
hide-details
></v-select>
</div>
</div>
<div class="mx-n1 mt-4 pt-2">
<apexchart type="bar" height="285" class="rounded-bars" :options="chartOptions" :series="Chart.series"> </apexchart>
</div>
</v-card-item>
</v-card>
</template>
+54
View File
@@ -0,0 +1,54 @@
<script setup lang="ts">
import { ref } from 'vue';
import { Icon } from '@iconify/vue';
import { RevenueProjectsData } from '@/data/dashboard/dashboardData';
</script>
<template>
<v-card elevation="10" class="revenue-products">
<v-card-item class="pb-4">
<div class="d-flex ga-3 align-center justify-space-between">
<v-card-title class="text-h5">Revenue by Product</v-card-title>
</div>
<div class="mt-4">
<v-table class="revenue-table">
<template v-slot:default>
<thead>
<tr>
<th class="text-body-1">Assigned</th>
<th class="text-body-1">Progress</th>
<th class="text-body-1">Priority</th>
<th class="text-body-1">Budget</th>
</tr>
</thead>
<tbody>
<tr v-for="item in RevenueProjectsData" :key="item.leadname" class="month-item">
<td>
<div class="d-flex align-center">
<v-avatar size="48" rounded="md"> <img :src="item.img" :alt="item.img" width="48" /></v-avatar>
<div class="mx-3">
<h6 class="text-subtitle-1 text-no-wrap font-weight-medium">{{ item.leadname }}</h6>
<span class="text-body-1 text-no-wrap text-textSecondary">{{ item.designation }}</span>
</div>
</div>
</td>
<td>
<p class="text-no-wrap text-body-1 text-textSecondary">
{{ item.projectname }}
</p>
</td>
<td>
<v-chip rounded="sm" class="font-weight-semibold" :color="item.statuscolor" size="small" label>{{
item.statustext
}}</v-chip>
</td>
<td>
<p class="text-body-1">{{ item.money }}</p>
</td>
</tr>
</tbody>
</template>
</v-table>
</div>
</v-card-item>
</v-card>
</template>
+68
View File
@@ -0,0 +1,68 @@
<script setup lang="ts">
import { computed } from 'vue';
import { Icon } from '@iconify/vue';
/* Chart */
const chartOptions = computed(() => {
return {
chart: {
type: 'line',
fontFamily: 'inherit',
foreColor: '#adb0bb',
height: 60,
sparkline: {
enabled: true
},
group: 'sparklines'
},
colors:['rgba(var(--v-theme-error))'],
stroke: {
curve: 'smooth',
width: 2
},
markers: {
size: 0
},
tooltip: {
theme: 'dark',
fixed: {
enabled: true,
position: 'right'
},
x: {
show: false
}
}
};
});
const Chart = {
series: [
{
name: 'Income',
data: [30, 25, 35, 20, 30, 40]
}
]
};
</script>
<template>
<v-card elevation="10">
<v-card-item>
<div class="d-flex ga-3 align-center">
<v-avatar size="48" class="rounded-md bg-lighterror">
<Icon icon="solar:box-linear" class="text-error" height="25" />
</v-avatar>
<h6 class="text-h6 heading">Total Income</h6>
</div>
<v-row class="mt-6">
<v-col cols="6">
<h3 class="text-h3 heading">$680</h3>
<div class="text-success text-subtitle-2 font-weight-medium mt-2">+18%</div>
</v-col>
<v-col cols="6">
<apexchart type="line" height="60" :options="chartOptions" :series="Chart.series"> </apexchart>
</v-col>
</v-row>
</v-card-item>
</v-card>
</template>
+65
View File
@@ -0,0 +1,65 @@
<script setup lang="ts">
import { onMounted, ref, shallowRef, watch } from "vue";
import { useDisplay } from "vuetify";
import sidebarItems from "~/components/layout/full/vertical-sidebar/sidebarItem";
import { Menu2Icon } from "vue-tabler-icons";
import { useCustomizerStore } from "~/store/customizer";
const sidebarMenu = shallowRef(sidebarItems);
const customizer = useCustomizerStore();
const { mdAndDown } = useDisplay();
const sDrawer = ref(true);
onMounted(() => {
sDrawer.value = !mdAndDown.value; // hide on mobile, show on desktop
});
watch(mdAndDown, (val) => {
sDrawer.value = !val;
});
</script>
<template>
<!------Sidebar-------->
<v-locale-provider>
<v-app
:theme="customizer.actTheme"
class="bg-containerBg"
:class="[
customizer.actTheme,
customizer.mini_sidebar ? 'mini-sidebar' : '',
customizer.setHorizontalLayout ? 'horizontalLayout' : 'verticalLayout',
customizer.setBorderCard ? 'cardBordered' : ''
]"
>
<!---Customizer location left side--->
<v-navigation-drawer
app
temporary
elevation="10"
location="left"
v-model="customizer.Customizer_drawer"
width="320"
class="left-customizer"
>
<Customizer />
</v-navigation-drawer>
<LazyLayoutFullVerticalSidebar v-if="!customizer.setHorizontalLayout" />
<div :class="customizer.boxed ? 'maxWidth' : 'full-header'">
<LazyLayoutFullVerticalHeader v-if="!customizer.setHorizontalLayout" />
</div>
<v-main class="ml-md-4">
<div class="rtl-lyt mb-3 hr-layout bg-containerBg">
<v-container
fluid
class="page-wrapper bg-background pt-md-8 rounded-xl"
>
<div>
<div class="">
<NuxtPage />
</div>
</div>
</v-container>
</div>
</v-main>
</v-app>
</v-locale-provider>
</template>
@@ -0,0 +1,154 @@
<script setup lang="ts">
import { ref } from 'vue';
import { useTheme } from 'vuetify';
import { useCustomizerStore } from '~/store/customizer';
import {
CheckIcon,
LayoutColumnsIcon,
LayoutDistributeHorizontalIcon,
LayoutDistributeVerticalIcon,
LayoutNavbarIcon,
LayoutSidebarLeftCollapseIcon,
TextDirectionLtrIcon,
TextDirectionRtlIcon
} from 'vue-tabler-icons';
const theme = useTheme();
const customizer = useCustomizerStore();
// template skin color options
const themeColors = ref([
{
name: 'BLUE_THEME',
bg: 'themeBlue'
},
{
name: 'AQUA_THEME',
bg: 'themeAqua'
},
{
name: 'PURPLE_THEME',
bg: 'themePurple'
},
{
name: 'GREEN_THEME',
bg: 'themeGreen'
},
{
name: 'CYAN_THEME',
bg: 'themeCyan'
},
{
name: 'ORANGE_THEME',
bg: 'themeOrange'
}
]);
// Dark Theme Colors
const DarkthemeColors = ref([
{ name: 'DARK_BLUE_THEME', bg: 'themeDarkBlue' },
{ name: 'DARK_AQUA_THEME', bg: 'themeDarkAqua' },
{ name: 'DARK_PURPLE_THEME', bg: 'themeDarkPurple' },
{ name: 'DARK_GREEN_THEME', bg: 'themeDarkGreen' },
{ name: 'DARK_CYAN_THEME', bg: 'themeDarkCyan' },
{ name: 'DARK_ORANGE_THEME', bg: 'themeDarkOrange' }
]);
</script>
<!------------------------------------->
<!-- Customizer -->
<!------------------------------------->
<template>
<div class="pa-6">
<h5 class="text-h5">Settings</h5>
</div>
<v-divider></v-divider>
<perfect-scrollbar style="height: calc(100vh - 90px)">
<div class="pa-6">
<h6 class="text-h6 mb-2">Sidebar Layout</h6>
<v-btn-toggle v-model="customizer.setHorizontalLayout" color="primary" class="my-2 btn-group-custom gap-3" rounded="0" group>
<v-btn :value="false" variant="text" elevation="9" class="rounded-md">
<LayoutColumnsIcon stroke-width="1.5" size="21" class="mr-2 icon" /> Vertical
</v-btn>
<v-btn :value="true" variant="text" elevation="9" class="rounded-md">
<LayoutNavbarIcon stroke-width="1.5" size="21" class="mr-2 icon" /> Horizontal
</v-btn>
</v-btn-toggle>
<!------Template Direction------>
<h6 class="text-h6 mt-8 mb-5">Template Color</h6>
<v-item-group mandatory v-model="customizer.actTheme" class="ml-n2 v-row">
<v-col cols="4" v-for="theme in themeColors" :key="theme.name" class="pa-2">
<v-item v-slot="{ isSelected, toggle }" :value="theme.name">
<v-sheet
rounded="md"
class="border cursor-pointer d-block text-center px-5 py-4 hover-btns"
elevation="9"
@click="toggle"
>
<v-avatar :class="theme.bg" size="25" variant="text">
<CheckIcon color="white" size="18" v-if="isSelected" />
</v-avatar>
</v-sheet>
</v-item>
</v-col>
</v-item-group>
<h6 class="text-h6 mt-11 mb-5">Template Dark Color</h6>
<v-item-group mandatory v-model="customizer.actTheme" class="ml-n2 v-row">
<v-col cols="4" v-for="theme in DarkthemeColors" :key="theme.name" class="pa-2">
<v-item v-slot="{ isSelected, toggle }" :value="theme.name">
<v-sheet
rounded="md"
class="border cursor-pointer d-block text-center px-5 py-4 hover-btns"
elevation="9"
@click="toggle"
>
<v-avatar :class="theme.bg" size="25">
<CheckIcon color="white" size="18" v-if="isSelected" />
</v-avatar>
</v-sheet>
</v-item>
</v-col>
</v-item-group>
<h6 class="text-h6 mt-11 mb-2">Container Option</h6>
<v-btn-toggle v-model="customizer.boxed" color="primary" class="my-2 btn-group-custom gap-3" rounded="0" group>
<v-btn :value="true" variant="text" elevation="9" class="rounded-md">
<LayoutDistributeVerticalIcon stroke-width="1.5" size="21" class="mr-2 icon" />
Boxed
</v-btn>
<v-btn :value="false" variant="text" elevation="9" class="rounded-md ">
<LayoutDistributeHorizontalIcon stroke-width="1.5" size="21" class="mr-2 icon" />
Full
</v-btn>
</v-btn-toggle>
<!---Horizontal demo hide this option --->
<v-sheet v-if="customizer.setHorizontalLayout != true">
<h6 class="text-h6 mt-11 mb-2">Sidebar Type</h6>
<v-btn-toggle v-model="customizer.mini_sidebar" color="primary" class="my-2 btn-group-custom gap-3" rounded="0" group>
<v-btn :value="false" variant="text" elevation="9" class="rounded-md">
<LayoutSidebarIcon stroke-width="1.5" size="21" class="mr-2 icon" />
Full
</v-btn>
<v-btn :value="true" variant="text" elevation="9" class="rounded-md">
<LayoutSidebarLeftCollapseIcon stroke-width="1.5" size="21" class="mr-2 icon" />
Collapse
</v-btn>
</v-btn-toggle>
</v-sheet>
<h6 class="text-h6 mt-11 mb-2">Card with</h6>
<v-btn-toggle v-model="customizer.setBorderCard" color="primary" class="my-2 btn-group-custom gap-3" rounded="0" group>
<v-btn :value="false" variant="text" elevation="9" class="rounded-md">
<LayoutSidebarLeftCollapseIcon stroke-width="1.5" size="21" class="mr-2 icon" />
Shadow
</v-btn>
<v-btn :value="true" variant="text" elevation="9" class="rounded-md">
<LayoutSidebarIcon stroke-width="1.5" size="21" class="mr-2 icon" />
Border
</v-btn>
</v-btn-toggle>
</div>
</perfect-scrollbar>
</template>
<style lang="scss"></style>
+26
View File
@@ -0,0 +1,26 @@
<script setup>
import { computed } from 'vue';
import { useCustomizerStore } from '~/store/customizer';
const customizer = useCustomizerStore();
//const dark = ref(false);
const dark = computed(() => {
if (
customizer.actTheme === 'DARK_BLUE_THEME' ||
customizer.actTheme === 'DARK_AQUA_THEME' ||
customizer.actTheme === 'DARK_ORANGE_THEME' ||
customizer.actTheme === 'DARK_PURPLE_THEME' ||
customizer.actTheme === 'DARK_GREEN_THEME' ||
customizer.actTheme === 'DARK_CYAN_THEME'
) {
return true;
} else {
return false;
}
});
</script>
<template>
<LayoutFullLogoLight v-if="dark" />
<LayoutFullLogoDark v-else />
</template>
+10
View File
@@ -0,0 +1,10 @@
<script setup lang="ts">
import Logoimg from "/images/logos/logo-antrean-new.svg";
</script>
<template>
<div class="logo">
<NuxtLink to="/">
<img :src="Logoimg" alt="home" />
</NuxtLink>
</div>
</template>
+10
View File
@@ -0,0 +1,10 @@
<script setup lang="ts">
import Logoimg from "/images/logos/logo-antrean-new.svg";
</script>
<template>
<div class="logo">
<NuxtLink to="/">
<img :src="Logoimg" alt="home" />
</NuxtLink>
</div>
</template>
@@ -0,0 +1,24 @@
<script setup lang="ts">
import {appsLink} from '~/_mockApis/headerData';
import { Icon } from '@iconify/vue';
</script>
<template>
<!-- ---------------------------------------------- -->
<!-- apps link -->
<!-- ---------------------------------------------- -->
<v-row>
<v-col cols="12" md="6" v-for="(item, i) in appsLink" :key="i">
<router-link :to="item.href" class="text-decoration-none custom-text-primary">
<div class="d-flex align-center">
<v-avatar size="45" :color=" 'light' + item.color" rounded="md">
<Icon :icon="'solar:' + item.avatar" height="24" :class="'text-' + item.color"/>
</v-avatar>
<div class="ml-3">
<h6 class="text-subtitle-1 mb-1 heading custom-title">{{ item.title }}</h6>
<p class="text-subtitle-2 textSecondary">{{ item.subtext }}</p>
</div>
</div>
</router-link>
</v-col>
</v-row>
</template>
@@ -0,0 +1,47 @@
<script setup lang="ts">
import { ref } from 'vue';
import { languageDD } from '@/_mockApis/headerData';
import flag1 from '~/assets/images/flag/icon-flag-en.svg';
import flag2 from '~/assets/images/flag/icon-flag-ro.svg';
import flag3 from '~/assets/images/flag/icon-flag-zh.svg';
import flag4 from '~/assets/images/flag/icon-flag-fr.svg';
</script>
<template>
<!-- ---------------------------------------------- -->
<!-- language DD -->
<!-- ---------------------------------------------- -->
<v-menu open-on-hover open-on-click>
<template v-slot:activator="{ props }">
<v-btn icon class="custom-hover-primary" size="small" variant="text" color="primary" v-bind="props">
<v-avatar size="20">
<img v-if="$i18n.locale === 'en'" :src="flag1" :alt="$i18n.locale" width="22" height="22" class="obj-cover" />
<img v-if="$i18n.locale === 'fr'" :src="flag4" :alt="$i18n.locale" width="22" height="22" class="obj-cover" />
<img v-if="$i18n.locale === 'ro'" :src="flag2" :alt="$i18n.locale" width="22" height="22" class="obj-cover" />
<img v-if="$i18n.locale === 'zh'" :src="flag3" :alt="$i18n.locale" width="22" height="22" class="obj-cover" />
</v-avatar>
</v-btn>
</template>
<v-sheet rounded="md" width="200" elevation="10">
<v-list class="theme-list">
<v-list-item
v-for="(item, index) in languageDD"
:key="index"
color="primary"
:active="$i18n.locale == item.value"
class="d-flex align-center"
@click="() => ($i18n.locale = item.value)"
>
<template v-slot:prepend>
<v-avatar size="22">
<img :src="item.avatar" :alt="item.avatar" width="22" height="22" class="obj-cover" />
</v-avatar>
</template>
<v-list-item-title class="text-subtitle-1 font-weight-regular">
{{ item.title }}
<span class="text-disabled text-subtitle-1 pl-2">({{ item.subtext }})</span>
</v-list-item-title>
</v-list-item>
</v-list>
</v-sheet>
</v-menu>
</template>
@@ -0,0 +1,30 @@
<script setup lang="ts">
import { ref } from 'vue';
import { Icon } from '@iconify/vue';
</script>
<template>
<!-- ---------------------------------------------- -->
<!-- mega menu DD -->
<!-- ---------------------------------------------- -->
<v-menu open-on-hover open-on-click >
<template v-slot:activator="{ props }">
<v-btn class="hidden-sm-and-down custom-hover-primary" size="small" variant="text" icon color="primary" v-bind="props"> <Icon icon="solar:widget-3-line-duotone" height="20" /> </v-btn>
</template>
<v-sheet width="900" height="300" elevation="10" rounded="md" class="pa-0 overflow-hidden">
<div>
<v-row>
<v-col cols="12" md="8" class="d-flex">
<div class="pa-6">
<LazyLayoutFullVerticalHeaderAppsLink />
</div>
</v-col>
<v-col cols="12" md="4" class="pa-0">
<img src="@/assets/images/backgrounds/mega-dd-bg.jpg" alt="matdash-img" height="320" class="w-100" />
</v-col>
</v-row>
</div>
</v-sheet>
</v-menu>
</template>
s
@@ -0,0 +1,43 @@
<script setup lang="ts">
import {notifications} from '~/_mockApis/headerData';
import { Icon } from '@iconify/vue';
</script>
<template>
<!-- ---------------------------------------------- -->
<!-- notifications DD -->
<!-- ---------------------------------------------- -->
<v-menu open-on-hover open-on-click >
<template v-slot:activator="{ props }">
<v-btn icon class="custom-hover-primary" size="small" variant="text" color="primary" v-bind="props">
<Icon icon="solar:bell-bing-line-duotone" height="22" />
</v-btn>
</template>
<v-sheet rounded="md" width="360" elevation="10">
<div class="px-6 pt-6 pb-4">
<div class="d-flex align-center justify-space-between">
<h6 class="text-h5">Notifications</h6>
<v-chip color="primary" variant="flat" size="small" class="text-white rounded-sm">5 New</v-chip>
</div>
</div>
<perfect-scrollbar style="height: 350px">
<v-list class="py-0 theme-list" lines="two">
<v-list-item v-for="item in notifications" :key="item.title" :value="item" color="primary" class="py-3 px-6">
<template v-slot:prepend>
<v-avatar size="45" :color=" 'light' + item.color" rounded="circle">
<Icon :icon="'solar:' + item.avatar" height="20" :class="'text-' + item.color"/>
</v-avatar>
</template>
<div class="d-flex justify-space-between">
<h6 class="text-subtitle-1 heading mb-1">{{ item.title }}</h6>
<span class="text-subtitle-2 textSecondary">{{ item.time }}</span>
</div>
<p class="text-subtitle-2 font-weight-regular textSecondary">{{ item.subtitle }}</p>
</v-list-item>
</v-list>
</perfect-scrollbar>
<div class="py-4 px-6 text-center">
<v-btn color="primary" variant="flat" size="large" block>See all Notifications</v-btn>
</div>
</v-sheet>
</v-menu>
</template>
@@ -0,0 +1,227 @@
<!-- components/layout/ProfileDD.vue -->
<script setup lang="ts">
import { MailIcon } from "vue-tabler-icons";
import { profileDD } from "~/_mockApis/headerData";
import { PerfectScrollbar } from "vue3-perfect-scrollbar";
import { useUserInfo } from "~/composables/useUserInfo";
import { computed } from "vue";
const userInfo = useUserInfo();
// Enhanced logout with proper error handling
const logout = async () => {
try {
// Use the updated logout method from useUserInfo that handles Keycloak logout and session clearing
await userInfo.logout({
reason: "idle",
confirmDialog: false // Show confirmation dialog
});
} catch (error) {
console.error("Logout from profile failed:", error);
}
};
// **TAMBAHAN: Full logout function dengan konfirmasi**
const fullLogout = async () => {
try {
// Tampilkan konfirmasi sebelum full logout
const confirmed = confirm(
"Apakah Anda yakin ingin keluar dari semua sesi? Ini akan menghapus semua data lokal dan sesi Keycloak."
);
if (!confirmed) return;
console.log("Initiating full logout from ProfileDD...");
// Gunakan fullLogout dari useUserInfo composable
await userInfo.fullLogout();
} catch (error) {
console.error("Full logout from profile failed:", error);
// Fallback jika fullLogout gagal
try {
console.log("Attempting fallback logout...");
await userInfo.logout({
reason: "manual",
clearStorage: true
});
} catch (fallbackError) {
console.error("Fallback logout also failed:", fallbackError);
// Last resort - force redirect
if (process.client) {
localStorage.clear();
sessionStorage.clear();
window.location.href = "/auth/login?reason=force";
}
}
}
};
// **TAMBAHAN: Logout dengan konfirmasi untuk UX yang lebih baik**
const logoutWithConfirmation = async () => {
try {
const confirmed = confirm("Apakah Anda yakin ingin keluar?");
if (!confirmed) return;
await logout();
} catch (error) {
console.error("Logout with confirmation failed:", error);
}
};
// Get user display info from session
const getUserDisplayInfo = () => {
if (!userInfo.user.value && !userInfo.data.value?.user)
return {
name: "Guest User",
email: "guest@example.com",
role: "Guest"
};
const user = userInfo.user.value || userInfo.data.value?.user || {};
return {
name: user.name || user.given_name || user.preferred_username || "User",
email: user.email || "No email",
role: userInfo.userRoles.value[0] || "User"
};
};
const displayInfo = computed(() => getUserDisplayInfo());
// Computed properties for decodedToken and clientScopes
// const decodedToken = computed(() => userInfo.decodedToken.value);
// const clientScopes = computed(() => userInfo.clientScopes.value);
// **TAMBAHAN: Computed property untuk menampilkan status session**
const sessionInfo = computed(() => {
return {
isAuthenticated: userInfo.isAuthenticated.value,
sessionExpires: userInfo.sessionExpires.value,
hasValidToken: !!userInfo.idToken.value
};
});
</script>
<template>
<v-menu :close-on-content-click="false">
<template v-slot:activator="{ props }">
<v-btn class="custom-hover-primary" variant="text" v-bind="props" icon>
<v-avatar size="35">
<img
src="~/assets/images/profile/user-1.jpg"
width="35"
alt="User Avatar"
/>
</v-avatar>
</v-btn>
</template>
<v-sheet rounded="md" width="360" elevation="10">
<div class="px-8 pt-6">
<h6 class="text-h5 font-weight-medium">User Profile</h6>
<div class="d-flex align-center mt-4 pb-6">
<v-avatar size="80">
<img src="~/assets/images/profile/user-1.jpg" width="80" />
</v-avatar>
<div class="ml-3">
<h6 class="text-h6 mb-n1">{{ displayInfo.name }}</h6>
<span class="text-subtitle-1 font-weight-regular textSecondary">
{{ displayInfo.role }}
</span>
<div class="d-flex align-center mt-1">
<MailIcon size="18" stroke-width="1.5" />
<span
class="text-subtitle-1 font-weight-regular textSecondary ml-2"
>
{{ displayInfo.email }}
</span>
</div>
<!-- **TAMBAHAN: Tampilkan status session** -->
<div class="mt-2">
<v-chip
:color="sessionInfo.isAuthenticated ? 'success' : 'error'"
size="small"
variant="outlined"
>
{{ sessionInfo.isAuthenticated ? "Active" : "Inactive" }}
</v-chip>
</div>
</div>
</div>
<v-divider></v-divider>
</div>
<PerfectScrollbar style="height: calc(100vh - 240px); max-height: 240px">
<v-list class="py-0 theme-list" lines="two">
<v-list-item
v-for="item in profileDD"
:key="item.title"
class="py-4 px-8 custom-text-primary"
:to="item.href"
>
<template v-slot:prepend>
<v-avatar
size="48"
color="lightprimary"
class="mr-3"
rounded="md"
>
<img
:src="item.avatar"
width="24"
height="24"
:alt="item.avatar"
/>
</v-avatar>
</template>
<div>
<h6 class="text-subtitle-1 font-weight-bold mb-2 custom-title">
{{ item.title }}
</h6>
</div>
<p class="text-subtitle-1 font-weight-regular textSecondary">
{{ item.subtitle }}
</p>
</v-list-item>
</v-list>
</PerfectScrollbar>
<!-- **DIPERBAIKI: Logout buttons section dengan multiple options** -->
<div class="pt-4 pb-6 px-8">
<!-- Regular Logout Button -->
<v-btn
color="primary"
variant="outlined"
block
@click="logoutWithConfirmation"
prepend-icon="mdi-logout"
class="mb-2"
>
Logout
</v-btn>
<!-- **TAMBAHAN: Full Logout Button** -->
<v-btn
color="error"
variant="outlined"
block
@click="fullLogout"
prepend-icon="mdi-logout-variant"
class="mb-2"
>
Full Logout
</v-btn>
<!-- **TAMBAHAN: Quick info text** -->
<div class="text-center mt-2">
<span class="text-caption textSecondary">
Full logout akan menghapus semua sesi dan data lokal
</span>
</div>
</div>
</v-sheet>
</v-menu>
</template>
@@ -0,0 +1,23 @@
<script setup lang="ts">
import { ref } from 'vue';
import { Icon } from '@iconify/vue';
</script>
<template>
<v-menu open-on-hover open-on-click >
<template v-slot:activator="{ props }">
<v-btn icon class="custom-hover-primary" size="small" variant="text" color="primary" v-bind="props">
<Icon icon="solar:widget-line-duotone" height="22" />
</v-btn>
</template>
<v-sheet rounded="md" width="360" elevation="10">
<perfect-scrollbar style="height: 370px">
<div class="pa-6">
<LazyLayoutFullVerticalHeaderAppsLink />
</div>
</perfect-scrollbar>
</v-sheet>
</v-menu>
</template>
@@ -0,0 +1,39 @@
<script setup>
import { Icon } from '@iconify/vue';
import { searchSugg } from '~/_mockApis/headerData';
</script>
<template>
<!-- ---------------------------------------------- -->
<!-- search1 -->
<!-- ------------------------------------------------>
<v-menu :close-on-content-click="false">
<template v-slot:activator="{ props }">
<v-btn icon class="custom-hover-primary" size="small" variant="text" color="primary" v-bind="props">
<Icon icon="solar:magnifer-linear" height="20" />
</v-btn>
</template>
<v-sheet width="360" elevation="10" rounded="md">
<div class="d-flex align-center justify-space-between pa-5">
<v-text-field placeholder="Search" color="primary" density="compact" variant="outlined" hide-details></v-text-field>
</div>
<v-divider></v-divider>
<h5 class="text-h5 mt-4 px-5 pb-4">Quick Page Links</h5>
<perfect-scrollbar style="height: 380px">
<v-list class="pt-0 pb-5" lines="two">
<v-list-item
:value="item"
v-for="(item, index) in searchSugg"
:key="index"
:to="item.href"
color="primary"
class="px-5 py-2"
>
<h6 class="text-subtitle-1 heading mb-1">{{ item.title }}</h6>
<p class="text-subtitle-2 textSecondary">{{ item.href }}</p>
</v-list-item>
</v-list>
</perfect-scrollbar>
</v-sheet>
</v-menu>
</template>
@@ -0,0 +1,38 @@
<script setup lang="ts">
import { ref } from 'vue';
import { useTheme } from 'vuetify';
import { useCustomizerStore } from '~/store/customizer';
import { Icon } from '@iconify/vue';
const theme = useTheme();
const customizer = useCustomizerStore();
// template skin color options
const themeColors = ref([
{
name: 'BLUE_THEME',
bg: 'togglethemeBlue'
},
{
name: 'DARK_BLUE_THEME',
bg: 'togglethemeDarkBlue'
}
]);
</script>
<template>
<div class="position-relative">
<v-item-group mandatory v-model="customizer.actTheme" class="d-flex">
<div v-for="theme in themeColors" :key="theme.name">
<v-item v-slot="{ toggle }" :value="theme.name">
<v-sheet rounded="circle" class="cursor-pointer text-center hover-btns" elevation="0" @click="toggle">
<v-btn icon :class="theme.bg" class="custom-hover-primary" size="small" variant="text" color="primary">
<SunIcon v-if="theme.bg == 'togglethemeBlue'" :class="theme.bg" height="22" />
<MoonIcon v-if="theme.bg == 'togglethemeDarkBlue'" :class="theme.bg" height="22" />
</v-btn>
</v-sheet>
</v-item>
</div>
</v-item-group>
</div>
</template>
@@ -0,0 +1,120 @@
<script setup lang="ts">
import { ref, watch, computed } from 'vue';
import { useCustomizerStore } from '~/store/customizer';
// import { useEcomStore } from '@/stores/apps/eCommerce';
// import LanguageDD from './LanguageDD.vue';
import NotificationDD from './NotificationDD.vue';
import ProfileDD from './ProfileDD.vue';
import Searchbar from './Searchbar.vue';
import RightMobileSidebar from './RightMobileSidebar.vue';
import Navigations from './Navigations.vue';
import { Icon } from '@iconify/vue';
import Logo from '../logo/Logo.vue';
import ThemeToggler from './ThemeToggler.vue';
const customizer = useCustomizerStore();
const showSearch = ref(false);
const priority = ref(customizer.setHorizontalLayout ? 0 : 0);
function searchbox() {
showSearch.value = !showSearch.value;
}
watch(priority, (newPriority) => {
priority.value = newPriority;
});
// count items
// const store = useEcomStore();
// const getCart = computed(() => {
// return store.cart;
// });
</script>
<template>
<v-app-bar elevation="0" :priority="priority" height="70" id="top" class="main-head">
<v-btn
class="hidden-lg-and-up custom-hover-primary"
size="small"
variant="text"
color="primary"
icon
@click.stop="customizer.SET_SIDEBAR_DRAWER"
>
<Icon icon="solar:hamburger-menu-line-duotone" height="22" />
</v-btn>
<!-- ---------------------------------------------- -->
<!-- Search part -->
<!-- ---------------------------------------------- -->
<Searchbar />
<!-- ---------------------------------------------- -->
<!-- Mega menu -->
<!-- ---------------------------------------------- -->
<div class="hidden-sm-and-down">
<Navigations />
</div>
<v-spacer class="hidden-sm-and-down" />
<!-- ---------------------------------------------- -->
<!-- Mobile Logo -->
<!-- ---------------------------------------------- -->
<div class="hidden-md-and-up">
<Logo />
</div>
<ThemeToggler />
<!-- ---------------------------------------------- -->
<!-- translate -->
<!-- ---------------------------------------------- -->
<div class="hidden-sm-and-down">
<LanguageDD />
</div>
<!-- ---------------------------------------------- -->
<!-- ShoppingCart -->
<!-- ---------------------------------------------- -->
<!-- <v-btn icon class="custom-hover-primary hidden-sm-and-down" size="small" variant="text" color="primary" to="/ecommerce/checkout">
<v-badge color="error" :content="getCart?.length">
<Icon icon="solar:cart-large-2-outline" height="22" />
</v-badge>
</v-btn> -->
<!-- ---------------------------------------------- -->
<!-- Notification -->
<!-- ---------------------------------------------- -->
<div class="hidden-sm-and-down">
<NotificationDD />
</div>
<!-- ---------------------------------------------- -->
<!-- User Profile -->
<!-- ---------------------------------------------- -->
<div class="hidden-sm-and-down">
<ProfileDD />
</div>
<!----Mobile ----->
<v-menu :close-on-content-click="true" class="mobile_popup">
<template v-slot:activator="{ props }">
<v-btn icon class="hidden-md-and-up custom-hover-primary" color="primary" variant="text" v-bind="props" size="small">
<Icon icon="solar:menu-dots-bold-duotone" height="22" />
</v-btn>
</template>
<v-sheet rounded="lg" elevation="10" class="mt-4 dropdown-box px-4 py-3">
<div class="d-flex justify-space-between align-center">
<RightMobileSidebar />
<!-- <LanguageDD /> -->
<!-- <v-btn icon variant="text" class="mr-sm-3 mr-2 custom-hover-primary" to="/ecommerce/checkout" size="small">
<v-badge color="primary" :content="getCart?.length" offset-x="-4" offset-y="-6">
<Icon icon="solar:cart-large-2-outline" height="22" />
</v-badge>
</v-btn> -->
<NotificationDD />
<ProfileDD />
</div>
</v-sheet>
</v-menu>
</v-app-bar>
</template>
@@ -0,0 +1,53 @@
<script setup>
const props = defineProps({ item: Object, level: Number });
</script>
<template>
<div class="mb-0">
<!---Single Item-->
<v-list-item
:href="item.external ? item.to : undefined"
:to="!item.external ? item.to : undefined"
rounded="lg"
class=""
color=""
:ripple="false"
:disabled="item.disabled"
:target="item.external === true ? '_blank' : undefined"
>
<!---If icon-->
<template v-slot:prepend>
<Icon
:icon="'solar:' + item.icon"
height="18"
width="18"
:level="level"
class="dot"
:class="'text-' + item.BgColor"
/>
</template>
<v-list-item-title class="text-body-1 text-darkText">{{
item.title
}}</v-list-item-title>
<!---If Caption-->
<v-list-item-subtitle
v-if="item.subCaption"
class="text-caption mt-n1 hide-menu"
>
{{ item.subCaption }}
</v-list-item-subtitle>
<!---If any chip or label-->
<template v-slot:append v-if="item.chip">
<v-chip
color="secondary"
class="font-weight-bold"
size="x-small"
rounded="sm"
>
{{ item.chip }}
</v-chip>
</template>
</v-list-item>
</div>
</template>
@@ -0,0 +1,23 @@
<script setup>
const props = defineProps({ item: Object, level: Number });
</script>
<template>
<template v-if="level > 0">
<component
:is="item"
size="5"
fill="currentColor"
stroke-width="1.5"
class="iconClass"
></component>
</template>
<template v-else>
<component
:is="item"
size="20"
stroke-width="1.5"
class="iconClass"
></component>
</template>
</template>
@@ -0,0 +1,25 @@
export interface minisidebar {
icon?: string;
id?:number;
tooltip?:string
}
const MiniSideIcons: minisidebar[] = [
{
icon: 'layers-line-duotone',
tooltip:'Modules',
id: 1
},
{
icon: 'palette-round-line-duotone',
tooltip:'UI Elements',
id: 3
},
{
icon: 'layers-line-duotone',
tooltip:'Widgets',
id: 2,
},
]
export default MiniSideIcons;
@@ -0,0 +1,42 @@
<script setup>
import NavItem from '../NavItem/NavItem.vue';
import { Icon } from '@iconify/vue';
const props = defineProps({ item: Object, level: Number });
</script>
<template>
<!-- ---------------------------------------------- -->
<!---Item Childern -->
<!-- ---------------------------------------------- -->
<v-list-group no-action>
<!-- ---------------------------------------------- -->
<!---Dropdown -->
<!-- ---------------------------------------------- -->
<template v-slot:activator="{ props }">
<v-list-item v-bind="props" :value="item.title" rounded>
<!---Icon -->
<template v-slot:prepend>
<!-- <span class="dot"></span> -->
<Icon :icon="'solar:' + item.icon" height="18" width="18" :level="level" class="dot" :class="'text-' + item.BgColor" />
</template>
<!---Title -->
<v-list-item-title class="mr-auto">{{ $t(item.title) }}</v-list-item-title>
<!---If Caption-->
<v-list-item-subtitle v-if="item.subCaption" class="text-caption mt-n1 hide-menu">
{{ item.subCaption }}
</v-list-item-subtitle>
</v-list-item>
</template>
<!-- ---------------------------------------------- -->
<!---Sub Item-->
<!-- ---------------------------------------------- -->
<template v-for="(subitem, i) in item.children" :key="i" v-if="item.children">
<NavCollapse :item="subitem" v-if="subitem.children" :level="level + 1" />
<NavItem :item="subitem" :level="level + 1" v-else></NavItem>
</template>
</v-list-group>
<!-- ---------------------------------------------- -->
<!---End Item Sub Header -->
<!-- ---------------------------------------------- -->
</template>
@@ -0,0 +1,14 @@
<script setup>
const props = defineProps({ item: Object });
</script>
<template>
<v-list-subheader
class="smallCap text-uppercase text-subtitle-2 mt-3 font-weight-bold d-flex align-items-center"
>
<span class="mini-icon"
><DotsIcon size="16" stroke-width="1.5" class="iconClass"
/></span>
<span class="mini-text">{{ $t(props.item.header) }}</span>
</v-list-subheader>
</template>
@@ -0,0 +1,49 @@
<script setup>
import { Icon } from "@iconify/vue";
const props = defineProps({ item: Object, level: Number });
</script>
<template>
<!---Single Item-->
<v-list-item
:to="item.type === 'external' ? '' : item.to"
:href="item.type === 'external' ? item.to : ''"
rounded
:disabled="item.disabled"
:target="item.type === 'external' ? '_blank' : ''"
v-scroll-to="{ el: '#top' }"
>
<!---If icon-->
<template v-slot:prepend>
<Icon
:icon="'solar:' + item.icon"
height="18"
width="18"
:level="level"
class="dot"
:class="'text-' + item.BgColor"
/>
</template>
<v-list-item-title>{{ $t(item.title) }}</v-list-item-title>
<!---If Caption-->
<v-list-item-subtitle
v-if="item.subCaption"
class="text-caption mt-n1 hide-menu"
>
{{ item.subCaption }}
</v-list-item-subtitle>
<!---If any chip or label-->
<template v-slot:append v-if="item.chip">
<v-chip
:color="item.chipColor"
:class="'sidebarchip hide-menu bg-' + item.chipBgColor"
:size="item.chipIcon ? 'small' : 'small'"
:variant="item.chipVariant"
:prepend-icon="item.chipIcon"
>
{{ item.chip }}
</v-chip>
</template>
</v-list-item>
</template>
@@ -0,0 +1,159 @@
<script setup lang="ts">
import { ref, shallowRef } from "vue";
import { useCustomizerStore } from "~/store/customizer";
import sidebarItems from "./sidebarItem";
import Logo from "../logo/Logo.vue";
import { Icon } from "@iconify/vue";
import { useRoute } from "vue-router";
// MiniSidebar Icons
import MiniSideIcons from "./MinIconItems";
const route = useRoute();
const findTitleByPath = (items: any, path: any) => {
let title = "";
for (const item of items) {
if (item.to === path) {
title = item.id;
break;
} else if (item.children) {
for (const child of item.children) {
if (child.to === path) {
title = item.id;
break;
} else if (child.children) {
for (const grandChild of child.children) {
if (grandChild.to === path) {
title = item.id;
break;
}
}
}
}
}
}
return title;
};
const foundId = findTitleByPath(sidebarItems, route.path);
const getCurrent = foundId ? foundId : 1;
const currentMenu = ref<any>(getCurrent);
function showData(data: any) {
currentMenu.value = data;
//customizer.SET_MINI_SIDEBAR(!customizer.mini_sidebar)
}
// MiniSidebar Icons End
const customizer = useCustomizerStore();
const sidebarMenu = shallowRef(sidebarItems);
</script>
<template>
<!-- Minisidebar Icons -->
<v-navigation-drawer
class="bg-light"
v-model="customizer.Sidebar_drawer"
top="0"
rail
rail-width="80"
>
<!-- <perfect-scrollbar class="miniscrollnavbar"> -->
<v-list-item class="px-0">
<!-- Toggle Sidebar Button -->
<div class="px-4 mb-3">
<v-btn
class="hidden-md-and-down my-2"
icon
rounded="md"
variant="plain"
@click.stop="customizer.SET_MINI_SIDEBAR(!customizer.mini_sidebar)"
>
<Icon icon="solar:hamburger-menu-line-duotone" height="25" />
</v-btn>
</div>
<div class="miniicons mt-lg-0 mt-4">
<!-- MiniSidebar Icons -->
<div class="d-flex flex-column gap-2">
<div
class="miniicons-list px-4"
v-for="menu in MiniSideIcons"
:key="menu.icon"
>
<v-btn
rounded="md"
flat
icon
variant="plain"
@click="showData(menu.id)"
:class="{ 'bg-primary opacity-1': currentMenu === menu.id }"
>
<Icon :icon="'solar:' + menu.icon" width="25" />
<!-- Tooltip on Hover -->
<v-tooltip
activator="parent"
location="end"
class="custom-tooltip"
>{{ menu.tooltip }}</v-tooltip
>
</v-btn>
</div>
</div>
</div>
</v-list-item>
<!-- </perfect-scrollbar> -->
</v-navigation-drawer>
<!-- LeftSidebar Items -->
<v-navigation-drawer
v-model="customizer.Sidebar_drawer"
elevation="0"
rail-width="1"
app
top="0"
class="leftSidebar"
:rail="customizer.mini_sidebar"
width="240"
>
<!---Logo part -->
<div class="pa-4 pb-0">
<Logo />
</div>
<!-- ---------------------------------------------- -->
<!---Navigation -->
<!-- ---------------------------------------------- -->
<perfect-scrollbar class="scrollnavbar">
<div class="px-4 py-0 sidebar-menus">
<v-list class="py-1">
<template v-for="(item, i) in sidebarMenu">
<template v-if="currentMenu == item.id">
<!---Item Sub Header -->
<LazyLayoutFullVerticalSidebarNavGroup
:item="item"
v-if="item.header"
:key="item.title"
/>
<!---If Has Child -->
<template v-for="sItem in item.children">
<LazyLayoutFullVerticalSidebarNavCollapse
class="leftPadding"
:item="sItem"
:level="0"
v-if="sItem.children"
/>
<LazyLayoutFullVerticalSidebarNavItem
:item="sItem"
class="leftPadding"
v-else
/>
</template>
</template>
</template>
</v-list>
</div>
</perfect-scrollbar>
</v-navigation-drawer>
</template>
@@ -0,0 +1,365 @@
export interface menu {
header?: string;
title?: string;
icon?: any;
id?: number;
to?: string;
chip?: string;
BgColor?: string;
chipBgColor?: string;
chipColor?: string;
chipVariant?: string;
chipIcon?: string;
children?: menu[];
disabled?: boolean;
type?: string;
subCaption?: string;
}
const sidebarItem: menu[] = [
{
header: 'dashboards',
id: 1,
children: [
{
title: 'Dashboard1',
icon: 'widget-add-line-duotone',
to: '/dashboards/dashboard1'
},
{
title: 'Dashboard2',
icon: 'chart-line-duotone',
to: '/dashboards/dashboard2'
},
{
title: 'Dashboard3',
icon: 'screencast-2-line-duotone',
to: '/dashboards/dashboard3'
},
{
title: 'Front Pages',
icon: 'home-angle-linear',
to: '/',
children: [
{
title: 'Homepage',
to: '/front-page/homepage'
},
{
title: 'About Us',
to: '/front-page/about-us'
},
{
title: 'Blog',
to: '/front-page/blog/posts'
},
{
title: 'Blog Details',
to: '/front-page/blog/early-black-friday-amazon-deals-cheap-tvs-headphones'
},
{
title: 'Contact Us',
to: '/front-page/contact-us'
},
{
title: 'Portfolio',
to: '/front-page/portfolio'
},
{
title: 'Pricing',
to: '/front-page/pricing'
}
]
},
]
},
{
header: 'apps',
id: 1,
children: [
{
title: 'ECommerce',
icon: 'cart-3-line-duotone',
to: '/ecommerce/',
children: [
{
title: 'Shop',
to: '/ecommerce/products'
},
{
title: 'Detail',
to: '/ecommerce/product/detail/1'
},
{
title: 'List',
to: '/ecommerce/productlist'
},
{
title: 'Checkout',
to: '/ecommerce/checkout'
},
{
title: 'Add Product',
to: '/ecommerce/add-product'
},
{
title: 'Edit Product',
to: '/ecommerce/edit-product'
}
]
},
{
title: 'Blog',
icon: 'widget-4-line-duotone',
to: '/',
children: [
{
title: 'Blog Posts',
to: '/apps/blog/posts'
},
{
title: 'Blog Details',
to: '/apps/blog/early-black-friday-amazon-deals-cheap-tvs-headphones'
}
]
},
{
title: 'User Profile',
icon: 'shield-user-line-duotone',
to: '/',
children: [
{
title: 'Profile',
to: '/apps/user/profile'
},
{
title: 'Followers',
to: '/apps/user/profile/followers'
},
{
title: 'Friends',
to: '/apps/user/profile/friends'
},
{
title: 'Gallery',
to: '/apps/user/profile/gallery'
}
]
},
{
title: 'Invoice',
icon: 'bill-check-outline',
to: '/',
children: [
{
title: 'List',
to: '/apps/invoice'
},
{
title: 'Details',
to: '/apps/invoice/details/102'
},
{
title: 'Create',
to: '/apps/invoice/create'
},
{
title: 'Edit',
to: '/apps/invoice/edit/102'
}
]
},
{
title: 'Calendar',
icon: 'calendar-mark-line-duotone',
to: '/apps/calendar'
},
{
title: 'Email',
icon: 'letter-linear',
to: '/apps/email'
},
{
title: 'Chats',
icon: 'chat-round-line-line-duotone',
to: '/apps/chats'
},
{
title: 'Notes',
icon: 'document-text-line-duotone',
to: '/apps/notes'
},
{
title: 'Kanban',
icon: 'airbuds-case-minimalistic-line-duotone',
to: '/apps/kanban'
},
{
title: 'Contact',
icon: 'iphone-line-duotone',
to: '/apps/contacts'
},
{
title: 'Tickets',
icon: 'ticker-star-outline',
to: '/apps/tickets'
},
]
},
{
header: 'Widgets',
id: 2,
children: [
{
title: 'Banners',
icon: 'gallery-wide-line-duotone',
to: '/widgets/banners'
},
{
title: 'Cards',
icon: 'layers-minimalistic-line-duotone',
to: '/widgets/cards'
},
{
title: 'Charts',
icon: 'chart-line-duotone',
to: '/widgets/charts'
},
]
},
{
header: 'UI Components',
id: 3,
children: [
{
title: 'Alerts',
icon: 'danger-triangle-line-duotone',
to: '/ui-components/alerts'
},
{
title: 'Avatar',
icon: 'user-circle-line-duotone',
to: '/ui-components/avatar'
},
{
title: 'Buttons',
icon: 'ghost-line-duotone',
to: '/ui-components/buttons'
},
{
title: 'Cards',
icon: 'layers-minimalistic-line-duotone',
to: '/ui-components/cards'
},
{
title: 'Chip',
icon: 'tag-horizontal-line-duotone',
to: '/ui-components/chip'
},
{
title: 'Dialogs',
icon: 'window-frame-line-duotone',
to: '/ui-components/dialogs'
},
{
title: 'Expansion Panel',
icon: 'hamburger-menu-line-duotone',
to: '/ui-components/expansionPanel'
},
{
title: 'List',
icon: 'list-line-duotone',
to: '/ui-components/list'
},
{
title: 'Menus',
icon: 'menu-dots-line-duotone',
to: '/ui-components/menus'
},
{
title: 'Ratting',
icon: 'star-line-duotone',
to: '/ui-components/ratting'
},
{
title: 'Tables',
icon: 'tablet-line-duotone',
to: '/ui-components/tables'
},
{
title: 'Tabs',
icon: 'notebook-line-duotone',
to: '/ui-components/tabs'
},
{
title: 'Tooltip',
icon: 'chat-round-dots-line-duotone',
to: '/ui-components/tooltip'
}
]
},
{
header: 'Style Components',
id: 3,
children: [
{
title: 'Shadow',
icon: 'copy-line-duotone',
to: '/style-components/shadow'
},
{
title: 'Typography',
icon: 'text-bold-circle-line-duotone',
to: '/style-components/typography'
}
]
},
{
header: 'Shared Components',
id: 3,
children: [
{
title: 'Overview',
icon: 'widget-5-line-duotone',
to: '/shared-components'
},
{
title: 'UiParentCard & UiChildCard',
icon: 'layers-minimalistic-line-duotone',
to: '/shared-components/UiParentCard'
},
{
title: 'WidgetCard & WidgetCardv2',
icon: 'chart-square-line-duotone',
to: '/shared-components/WidgetCards'
},
{
title: 'Card Components',
icon: 'card-2-line-duotone',
to: '/shared-components/CardComponents'
},
{
title: 'BaseBreadcrumb',
icon: 'route-line-duotone',
to: '/shared-components/BaseBreadcrumb'
},
{
title: 'UiTextfieldPrimary',
icon: 'text-field-line-duotone',
to: '/shared-components/UiTextfieldPrimary'
},
{
title: 'AppBaseCard',
icon: 'sidebar-minimalistic-line-duotone',
to: '/shared-components/AppBaseCard'
},
]
},
];
export default sidebarItem;
+68
View File
@@ -0,0 +1,68 @@
<script setup lang="ts">
import { ref } from 'vue';
import { useDisplay } from 'vuetify';
const { xs, lgAndUp } = useDisplay();
const sDrawer = ref(false);
</script>
<template>
<!---/Left chat list -->
<div class="d-flex mainbox rounded-md">
<div class="left-part" v-if="lgAndUp">
<!-- <perfect-scrollbar style="height: calc(100vh - 290px)"> -->
<slot name="leftpart"></slot>
<!-- </perfect-scrollbar> -->
</div>
<!---right chat conversation -->
<div class="right-part">
<!---Toggle Button For mobile-->
<v-btn block @click="sDrawer = !sDrawer" variant="text" class="d-lg-none d-md-flex d-sm-flex">
<Menu2Icon size="20" class="mr-2" /> Menu
</v-btn>
<v-divider class="d-lg-none d-block" />
<slot name="rightpart"></slot>
</div>
<!---right chat conversation -->
</div>
<v-navigation-drawer temporary v-model="sDrawer" width="320" top v-if="!lgAndUp">
<v-card-text class="pa-0">
<slot name="mobileLeftContent"></slot>
</v-card-text>
</v-navigation-drawer>
</template>
<style lang="scss">
.mainbox {
position: relative;
overflow: hidden;
}
.left-part {
width: 320px;
border-inline-end-width: thin !important;
border-inline-end-style: solid !important;
border-inline-end-color: rgba(var(--v-border-color), var(--v-border-opacity)) !important;
min-height: 500px;
transition: 0.1s ease-in;
flex-shrink: 0;
}
.v-theme--light {
.left-part {
background: white;
}
}
.v-theme--dark {
.left-part {
background: #2b2b2b;
}
}
.right-part{
width: 100%;
}
</style>
+62
View File
@@ -0,0 +1,62 @@
<script setup lang="ts">
import { ref } from "vue";
import { useDisplay } from "vuetify";
const { xs, lgAndUp } = useDisplay();
const sDrawer = ref(false); // Sidebar drawer for mobile
const eDrawer = ref(false); // Email details drawer
const selectedEmail = ref(null); // To store the selected email details
// Method to select an email and open the email details drawer
const openEmailDetails = (email:any) => {
selectedEmail.value = email; // Store the selected email
eDrawer.value = true; // Open the email details drawer
};
</script>
<template>
<div class="d-flex mainbox">
<div class="compose pa-6 " v-if="lgAndUp">
<slot name="mailCompose"></slot>
</div>
<div class="mail-list">
<v-divider class="d-lg-none d-block" />
<slot name="mailList" :openEmailDetails="openEmailDetails"></slot> <!-- Pass the method as a slot prop -->
</div>
<div class="mail-details pa-6 d-md-block d-none">
<slot name="mailDetail"></slot>
</div>
</div>
</template>
<style lang="scss">
.compose {
max-width: 235px;
width: 100%;
}
.mail-list {
max-width: 340px;
width: 100%;
}
.mail-details {
width: 100%;
}
@media screen and (max-width: 991px) {
.mail-list {
max-width: 100%;
}
}
@media screen and (min-width: 991px) {
.compose,.mail-list{
border-inline-end-width: thin !important;
border-inline-end-style: solid !important;
border-inline-end-color: rgba(var(--v-border-color), var(--v-border-opacity)) !important;
}
}
</style>
+43
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>
+24
View File
@@ -0,0 +1,24 @@
<script setup lang="ts">
const props = defineProps({
title: String
});
</script>
<template>
<!-- -------------------------------------------------------------------- -->
<!-- Card with Header & Footer -->
<!-- -------------------------------------------------------------------- -->
<v-card variant="outlined" elevation="0" >
<v-card-item>
<v-card-title class="text-18">{{ title }}</v-card-title>
</v-card-item>
<v-divider></v-divider>
<v-card-text>
<slot />
</v-card-text>
<v-divider></v-divider>
<v-card-actions>
<slot name="footer" />
</v-card-actions>
</v-card>
</template>
+17
View File
@@ -0,0 +1,17 @@
<script setup lang="ts">
const props = defineProps({
title: String
});
</script>
<template>
<v-card variant="outlined">
<v-card-item class="py-4 px-6">
<v-card-title class="text-h5 mb-0">{{ title }}</v-card-title>
</v-card-item>
<v-divider />
<v-card-text>
<slot />
</v-card-text>
</v-card>
</template>
+22
View File
@@ -0,0 +1,22 @@
<script setup lang="ts">
const props = defineProps({
title: String
});
</script>
// ===============================|| Ui Parent Card||=============================== //
<template>
<v-card elevation="10" >
<v-card-item class="py-4 px-6">
<div class="d-sm-flex align-center justify-space-between">
<v-card-title class="text-h5 mb-0">{{ title }}</v-card-title>
<slot name="action"></slot>
<!-- </template> -->
</div>
</v-card-item>
<v-divider></v-divider>
<v-card-text>
<slot />
</v-card-text>
</v-card>
</template>
+22
View File
@@ -0,0 +1,22 @@
<script setup lang="ts">
import { ref } from 'vue';
import Logo from "@/components/layout/full/logo/Logo.vue";
</script>
// ===============================|| Ui Parent Card||=============================== //
<template>
<v-card elevation="10" >
<v-card-item>
<div class="d-sm-flex align-center justify-space-between">
<v-card-title class="text-h5"><Logo/></v-card-title>
<!-- <template v-slot:append> -->
<slot name="action"></slot>
<!-- </template> -->
</div>
</v-card-item>
<v-divider></v-divider>
<v-card-text>
<slot />
</v-card-text>
</v-card>
</template>
+19
View File
@@ -0,0 +1,19 @@
<script setup lang="ts">
const props = defineProps({
title: String
});
</script>
<template>
<!-- ---------------------------------------------------- -->
<!-- Table Card -->
<!-- ---------------------------------------------------- -->
<v-card variant="outlined" elevation="0" >
<v-card-item>
<v-card-title class="text-18">{{ title }}</v-card-title>
</v-card-item>
<v-divider></v-divider>
<slot />
</v-card>
</template>
+9
View File
@@ -0,0 +1,9 @@
<script setup lang="ts">
// const props = defineProps({
// title: String,
// });
</script>
<template>
<v-text-field color="primary"><slot /></v-text-field>
</template>
+20
View File
@@ -0,0 +1,20 @@
<script setup lang="ts">
const props = defineProps({
title: String
});
</script>
<template>
<!-- -------------------------------------------------------------------- -->
<!-- Card with Header & Footer -->
<!-- -------------------------------------------------------------------- -->
<v-card variant="outlined" elevation="0" class=" mb-6 overflow-hidden">
<v-card-item>
<v-card-title class="text-18">{{ title }}</v-card-title>
</v-card-item>
<v-divider></v-divider>
<v-card-text>
<slot />
</v-card-text>
</v-card>
</template>
+23
View File
@@ -0,0 +1,23 @@
<script setup lang="ts">
const props = defineProps({
title: String,
hideaction: Boolean
});
</script>
<template>
<!-- -------------------------------------------------------------------- -->
<!-- Card with Header & Footer -->
<!-- -------------------------------------------------------------------- -->
<v-card variant="outlined" elevation="0" class=" mb-6 overflow-hidden">
<v-card-item>
<v-card-title class="text-18">{{ title }}</v-card-title>
</v-card-item>
<v-divider></v-divider>
<slot />
<v-divider></v-divider>
<v-card-actions :class="`${hideaction ? 'd-none' : ''}`">
<slot name="footer" />
</v-card-actions>
</v-card>
</template>
@@ -0,0 +1,15 @@
<script setup lang="ts">
import UiParentCard from '@/components/shared/UiParentCard.vue';
</script>
<template>
<UiParentCard title="Shadow">
<v-row justify="center" class="mb-5 mt-1 px-8 px-3">
<v-col v-for="(m, n) in 25" :key="n" cols="6" sm="auto">
<v-card
:class="['d-flex justify-center align-center bg-primary py-sm-4 py-3 px-sm-8 px-4', `elevation-${n}`]">
<div>{{ n }}</div>
</v-card>
</v-col>
</v-row>
</UiParentCard>
</template>
@@ -0,0 +1,25 @@
<script setup lang="ts">
import { ref } from "vue";
const colortext = ref(
[
['Text Primary', 'text-primary text-h5','text-primary text-subtitle-1 mt-1'],
['Text Secondary', 'text-secondary text-h5','text-secondary text-subtitle-1 mt-1'],
['Text Info', 'text-info text-h5','text-info text-subtitle-1 mt-1'],
['Text Warning', 'text-warning text-h5','text-warning text-subtitle-1 mt-1'],
['Text Error', 'text-error text-h5','text-error text-subtitle-1 mt-1'],
['Text Success', 'text-success text-h5','text-success text-subtitle-1 mt-1'],
]
)
</script>
<template>
<div class="d-flex flex-column gap-1 mx-1 pa-7 pt-0 pb-0">
<div class="mb-6" v-for="[name1, cls1,cls2] in colortext" :key="name1" >
<v-card elevation="10" >
<div class="py-6 px-4">
<h5 :class="[cls1, '']">{{ name1 }} </h5>
<div :class="[cls2, '']">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quos blanditiis tenetur</div>
</div>
</v-card>
</div>
</div>
</template>
@@ -0,0 +1,49 @@
<script setup lang="ts">
import { ref } from "vue";
const headings = ref([
['h1.Heading', 'text-h1', 'font size: 30 | line-height: 45 | font weight: 500'],
['h2.Heading', 'text-h2', 'font size: 24 | line-height: 36 | font weight: 500'],
['h3.Heading', 'text-h3', 'font size: 21 | line-height: 31.5 | font weight: 500'],
['h4.Heading', 'text-h4', 'font size: 18 | line-height: 27 | font weight: 500'],
['h5.Heading', 'text-h5', 'font size: 16 | line-height: 24 | font weight: 500'],
['h6.Heading', 'text-h6', 'font size: 14 | line-height: 21 | font weight: 500'],
]);
const subtext = ref(
[
['Subtitle 1.', 'text-subtitle-1', ' Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quos blanditiis tenetur', 'font size: 16 | line-height: 28 | font weight: 400'],
['Subtitle 2.', 'text-subtitle-2', ' Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quos blanditiis tenetur', 'font size: 14 | line-height: 21 | font weight: 400'],
['Body 1.', 'text-body-1', ' Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quos blanditiis tenetur', 'font size: 16 | line-height: 24 | font weight: 400'],
['Body 2.', 'text-body-2', ' Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quos blanditiis tenetur', 'font size: 14 | line-height: 20 | font weight: 400'],
['Caption.', 'text-caption', ' Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quos blanditiis tenetur', 'font size: 12 | line-height: 19 | font weight: 400'],
['OVERLINE.', 'text-overline letter-spacing-0', ' Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quos blanditiis tenetur', 'font size: 12 | line-height: 31 | font weight: 400']
]
)
</script>
<template>
<div class="d-flex flex-column gap-1 mx-1 pa-7 pt-0 pb-0">
<div class="mb-6" v-for="[name, cls, val] in headings" :key="name">
<v-card elevation="10">
<div class="py-6 px-4">
<div :class="[cls, '']">{{ name }}</div>
<div class="text-body-1">
<div class="text-muted">{{ val }}</div>
</div>
</div>
</v-card>
</div>
</div>
<div class="d-flex flex-column gap-1 mx-1 pt-0 pa-7 pb-0">
<div class="mb-6" v-for="[name1, cls1, val1, prop] in subtext" :key="name1">
<v-card elevation="10">
<div class="py-6 px-4">
<div :class="[cls1, '']">{{ name1 }} <span>{{ val1 }}</span></div>
<div class="text-body-1 ">
<div class="text-muted">{{ prop }}</div>
</div>
</div>
</v-card>
</div>
</div>
</template>
@@ -0,0 +1,12 @@
<template>
<div class="d-flex flex-column gap-1 mx-1 pt-0 pa-7 pb-0">
<v-card elevation="10">
<div class="py-6 px-4">
<p class="text-high-emphasis">High-emphasis has an opacity of 87% in light skin and 100% in dark.</p>
<p class="text-medium-emphasis">Medium-emphasis text and hint text have opacities of 60% in light skin
and 70% in dark.</p>
<p class="text-disabled">Disabled text has an opacity of 38% in light skin and 50% in dark.</p>
</div>
</v-card>
</div>
</template>
@@ -0,0 +1,15 @@
<template>
<div class="d-flex flex-column gap-1 mx-1 pt-0 pa-7 pb-0">
<v-card elevation="10">
<div class="py-6 px-4">
<p class="text-left">Left aligned on all viewport sizes.</p>
<p class="text-center">Center aligned on all viewport sizes.</p>
<p class="text-right">Right aligned on all viewport sizes.</p>
<p class="text-sm-left">Left aligned on viewports SM (small) or wider.</p>
<p class="text-right text-md-left">Left aligned on viewports MD (medium) or wider.</p>
<p class="text-right text-lg-left">Left aligned on viewports LG (large) or wider.</p>
<p class="text-right text-xl-left">Left aligned on viewports XL (extra-large) or wider.</p>
</div>
</v-card>
</div>
</template>
@@ -0,0 +1,14 @@
<template>
<div class="d-flex flex-column gap-1 mx-1 pt-0 pa-7 pb-0">
<v-card elevation="10">
<div class="py-6 px-4">
<div class="d-flex justify-space-between flex-row">
<a href="#" class="text-decoration-none">Non-underlined link</a>
<div class="text-decoration-line-through">Line-through text</div>
<div class="text-decoration-overline">Overline text</div>
<div class="text-decoration-underline">Underline text</div>
</div>
</div>
</v-card>
</div>
</template>
+6
View File
@@ -0,0 +1,6 @@
<template>
<v-alert class="mb-3 " color="error" variant="tonal">This is an error alert check it out!</v-alert>
<v-alert class="mb-3 " color="warning" variant="tonal">This is a warning alert check it out!</v-alert>
<v-alert class="mb-3 " color="info" variant="tonal">This is an info alert check it out!</v-alert>
<v-alert color="success" variant="tonal">This is a success alert check it out!</v-alert>
</template>
@@ -0,0 +1,30 @@
<script setup lang="ts">
import { ref } from 'vue';
const alert = ref(true);
</script>
<template>
<div>
<v-alert
v-model="alert"
border="start"
variant="tonal"
closable
close-label="Close Alert"
color="primary"
title="Closable Alert"
>
Aenean imperdiet. Quisque id odio. Cras dapibus. Pellentesque ut neque. Cras dapibus.
Vivamus consectetuer hendrerit lacus. Sed mollis, eros et ultrices tempus, mauris ipsum aliquam libero, non
</v-alert>
<div
v-if="!alert"
>
<v-btn
color="primary"
@click="alert = true" flat>
Reset
</v-btn>
</div>
</div>
</template>
@@ -0,0 +1,8 @@
<template>
<div>
<v-alert class="mb-3" type="error">This is an error alert check it out!</v-alert>
<v-alert class="mb-3" type="warning">This is a warning alert check it out!</v-alert>
<v-alert class="mb-3" type="info">This is an info alert check it out!</v-alert>
<v-alert type="success">This is a success alert check it out!</v-alert>
</div>
</template>
@@ -0,0 +1,13 @@
<script setup lang="ts">
import { ref } from 'vue';
// icons
import { UserIcon} from 'vue-tabler-icons';
</script>
<template>
<div class="text-center">
<v-avatar variant="flat" color="primary">
<UserIcon />
</v-avatar>
</div>
</template>
@@ -0,0 +1,24 @@
<script setup lang="ts">
import { ref } from 'vue';
// icons
import { MoodSmileIcon} from 'vue-tabler-icons';
</script>
<template>
<div class="d-flex align-center gap-2 justify-center">
<v-avatar size="40" color="primary" variant="flat">
<MoodSmileIcon size="25" />
</v-avatar>
<v-avatar size="40" variant="flat" color="secondary" >
<MoodSmileIcon size="25" />
</v-avatar>
<v-avatar size="40" color="error" variant="flat">
<MoodSmileIcon size="25" />
</v-avatar>
<v-avatar size="40" color="warning" variant="flat">
<MoodSmileIcon size="25" />
</v-avatar>
<v-avatar size="40" color="success" variant="flat">
<MoodSmileIcon size="25" />
</v-avatar>
</div>
</template>
@@ -0,0 +1,13 @@
<template>
<div class="d-flex align-center gap-2 justify-center">
<v-avatar size="40" variant="flat">
<img src="@/assets/images/profile/user-6.jpg" width="40" alt="Julia" />
</v-avatar>
<v-avatar size="40" variant="flat">
<img src="@/assets/images/profile/user-2.jpg" width="40" alt="Julia" />
</v-avatar>
<v-avatar size="40" variant="flat">
<img src="@/assets/images/profile/user-3.jpg" width="40" alt="Julia" />
</v-avatar>
</div>
</template>
@@ -0,0 +1,9 @@
<template>
<div class="d-flex align-center gap-2 justify-center">
<v-avatar size="40" color="primary" variant="flat" class="text-h5 font-weight-medium"> A </v-avatar>
<v-avatar size="40" color="secondary" variant="flat" class="text-h5 font-weight-medium">B</v-avatar>
<v-avatar size="40" color="error" variant="flat" class="text-h5 font-weight-medium"> C </v-avatar>
<v-avatar size="40" color="warning" variant="flat" class="text-h5 font-weight-medium"> D </v-avatar>
<v-avatar size="40" color="success" variant="flat" class="text-h5 font-weight-medium"> E </v-avatar>
</div>
</template>
@@ -0,0 +1,20 @@
<template>
<div class="d-flex align-center gap-3 justify-center">
<v-avatar size="x-small" variant="flat">
<img src="@/assets/images/profile/user-3.jpg" width="25" alt="Julia" />
</v-avatar>
<v-avatar size="small" variant="flat">
<img src="@/assets/images/profile/user-3.jpg" width="35" alt="Julia" />
</v-avatar>
<v-avatar size="medium" variant="flat">
<img src="@/assets/images/profile/user-3.jpg" width="40" alt="Julia" />
</v-avatar>
<v-avatar size="large" variant="flat">
<img src="@/assets/images/profile/user-3.jpg" width="48" alt="Julia" />
</v-avatar>
<v-avatar size="x-large" variant="flat">
<img src="@/assets/images/profile/user-3.jpg" width="56" alt="Julia" />
</v-avatar>
</div>
</template>
@@ -0,0 +1,18 @@
<script setup lang="ts">
import { ref } from 'vue';
// icons
import { MoodSmileIcon} from 'vue-tabler-icons';
</script>
<template>
<div class="d-flex align-center gap-2 justify-center">
<v-avatar size="40" color="primary" variant="flat" rounded="sm">
<MoodSmileIcon size="25" />
</v-avatar>
<v-avatar size="40" color="primary" variant="flat" rounded="md">
<MoodSmileIcon size="25" />
</v-avatar>
<v-avatar size="40" color="primary" variant="flat" rounded="lg">
<MoodSmileIcon size="25" />
</v-avatar>
</div>
</template>
@@ -0,0 +1,10 @@
<template>
<div class="d-flex ga-3 align-center flex-column flex-wrap flex-xl-nowrap flex-sm-row fill-height d-flex justify-space-between">
<v-btn >elevates (default)</v-btn>
<v-btn variant="flat" color="primary">flat</v-btn>
<v-btn variant="tonal" color="primary">tonal</v-btn>
<v-btn variant="outlined" color="primary">outlined</v-btn>
<v-btn variant="text" color="primary">text</v-btn>
<v-btn variant="plain" color="primary">plain</v-btn>
</div>
</template>
@@ -0,0 +1,12 @@
<script setup lang="ts">
import { ref } from 'vue';
// buttons color data
const btnsColor = ref(['primary', 'secondary', 'error', 'warning','success']);
</script>
<template>
<div class="d-flex ga-3 align-center flex-column flex-wrap flex-xl-nowrap flex-sm-row fill-height">
<v-btn v-for="btn in btnsColor" :key="btn" :color="btn" variant="flat">
{{ btn }}
</v-btn>
</div>
</template>
@@ -0,0 +1,9 @@
<template>
<div class="d-flex flex-wrap justify-center ga-3 align-center flex-column flex-sm-row fill-height">
<v-btn color="primary" icon size="x-small" flat><BellIcon stroke-width="1.5" /></v-btn>
<v-btn color="secondary" icon size="small" flat><BellIcon stroke-width="1.5" /></v-btn>
<v-btn color="success" icon flat><BellIcon stroke-width="1.5" /></v-btn>
<v-btn color="error" icon size="large" flat><BellIcon stroke-width="1.5" /></v-btn>
<v-btn color="warning" icon size="x-large" flat><BellIcon stroke-width="1.5" /></v-btn>
</div>
</template>
@@ -0,0 +1,11 @@
<template>
<div class="d-flex ga-3 justify-center align-center flex-column flex-wrap flex-xl-nowrap flex-sm-row fill-height">
<v-btn color="primary" variant="outlined">primary</v-btn>
<v-btn color="secondary" variant="outlined">secondary</v-btn>
<v-btn variant="flat" disabled>
Disabled
</v-btn>
<v-btn color="info" variant="outlined">link</v-btn>
</div>
</template>
@@ -0,0 +1,23 @@
<template>
<div class="d-flex gap-2 justify-space-around align-center flex-column flex-md-row fill-height">
<v-btn size="x-small" color="primary" flat>
Extra small
</v-btn>
<v-btn size="small" color="primary" flat>
Small
</v-btn>
<v-btn color="primary" flat>
Normal
</v-btn>
<v-btn color="primary" size="large" flat>
Large
</v-btn>
<v-btn size="x-large" color="primary" flat>
Extra large
</v-btn>
</div>
</template>
@@ -0,0 +1,12 @@
<script setup lang="ts">
import { ref } from 'vue';
// buttons color data
const btnsColor = ref(['primary', 'secondary', 'success', 'error', 'warning']);
</script>
<template>
<div class="d-flex flex-wrap ga-3 my-2 align-center flex-column flex-wrap flex-xl-nowrap flex-sm-row fill-height">
<v-btn v-for="btn in btnsColor" :key="btn" :color="btn" variant="text">
{{ btn }}
</v-btn>
</div>
</template>
@@ -0,0 +1,82 @@
<script setup lang="ts">
import { ref } from "vue";
import proimg1 from '/images/blog/blog-img1.jpg';
const messages = ref([
{
from: "You",
message: `Sure, I'll see you later.`,
time: "10:42am",
color: "primary",
},
{
from: "John Doe",
message: "Yeah, sure. Does 1:00pm work?",
time: "10:37am",
color: "secondary",
},
{
from: "You",
message: "Did you still want to grab lunch today?",
time: "9:47am",
color: "success",
},
]);
</script>
<template>
<!-- ----------------------------------------------------------------------------- -->
<!-- Content Wrap -->
<!-- ----------------------------------------------------------------------------- -->
<div class="pa-3">
<v-row justify="space-around">
<v-card elevation="0">
<v-img
height="200"
:src='proimg1'
cover
class="text-white"
>
<v-layout full-height>
<v-app-bar
density="comfortable"
color="rgba(0, 0, 0, 0)"
flat
theme="dark"
>
<template v-slot:prepend>
<v-app-bar-nav-icon></v-app-bar-nav-icon>
</template>
<v-toolbar-title class="text-subtitle-1"> Messages </v-toolbar-title>
<template v-slot:append>
<v-icon icon="mdi-dots-vertical"></v-icon>
</template>
</v-app-bar>
</v-layout>
</v-img>
<v-card-text>
<div class="font-weight-bold ml-1 mb-2">Today</div>
<v-timeline density="compact">
<v-timeline-item
v-for="message in messages"
:key="message.time"
:dot-color="message.color"
size="x-small"
>
<div class="mb-4">
<div class="font-weight-normal">
<strong>{{ message.from }}</strong> @{{ message.time }}
</div>
<div>{{ message.message }}</div>
</div>
</v-timeline-item>
</v-timeline>
</v-card-text>
</v-card>
</v-row>
</div>
</template>
@@ -0,0 +1,34 @@
<script setup lang="ts">
import proimg2 from '/images/blog/blog-img3.jpg';
</script>
<template>
<!-- ----------------------------------------------------------------------------- -->
<!-- Media -->
<!-- ----------------------------------------------------------------------------- -->
<v-card elevation="0">
<v-img
class="align-end text-white"
height="200"
:src='proimg2'
cover
>
<v-card-title>Top 10 Australian beaches</v-card-title>
</v-img>
<v-card-subtitle class="pt-4"> Number 10 </v-card-subtitle>
<v-card-text>
<div>Whitehaven Beach</div>
<div>Whitsunday Island, Whitsunday Islands</div>
</v-card-text>
<v-card-actions>
<v-btn color="orange"> Share </v-btn>
<v-btn color="orange"> Explore </v-btn>
</v-card-actions>
</v-card>
</template>
@@ -0,0 +1,12 @@
<script setup lang="ts"></script>
<template>
<!-- ----------------------------------------------------------------------------- -->
<!-- Props -->
<!-- ----------------------------------------------------------------------------- -->
<v-card elevation="0"
title="This is a title"
subtitle="This is a subtitle"
text="This is content"
></v-card>
</template>
@@ -0,0 +1,14 @@
<script setup lang="ts"></script>
<template>
<!-- ----------------------------------------------------------------------------- -->
<!-- Props -->
<!-- ----------------------------------------------------------------------------- -->
<v-card elevation="0">
<template v-slot:title> This is a title </template>
<template v-slot:subtitle> This is a subtitle </template>
<template v-slot:text> This is content </template></v-card
>
</template>
@@ -0,0 +1,49 @@
<script setup lang="ts"></script>
<template>
<!-- ----------------------------------------------------------------------------- -->
<!-- Twiteter -->
<!-- ----------------------------------------------------------------------------- -->
<v-card
class="mx-auto"
color="#26c6da"
theme="dark"
max-width="450"
prepend-icon="mdi-twitter"
title="Twitter"
elevation="0"
>
<template v-slot:prepend>
<v-icon size="x-large"></v-icon>
</template>
<v-card-text class="text-h5 py-2">
"Turns out semicolon-less style is easier and safer in TS because most gotcha edge cases are type invalid as well."
</v-card-text>
<v-card-actions>
<v-list-item class="w-100">
<template v-slot:prepend>
<v-avatar
color="grey-darken-3"
image="https://avataaars.io/?avatarStyle=Transparent&topType=ShortHairShortCurly&accessoriesType=Prescription02&hairColor=Black&facialHairType=Blank&clotheType=Hoodie&clotheColor=White&eyeType=Default&eyebrowType=DefaultNatural&mouthType=Default&skinColor=Light"
></v-avatar>
</template>
<v-list-item-title>Evan You</v-list-item-title>
<v-list-item-subtitle>Vue Creator</v-list-item-subtitle>
<template v-slot:append>
<div class="justify-self-end">
<v-icon class="me-1" icon="mdi-heart"></v-icon>
<span class="subheading me-2">256</span>
<span class="me-1">·</span>
<v-icon class="me-1" icon="mdi-share-variant"></v-icon>
<span class="subheading">45</span>
</div>
</template>
</v-list-item>
</v-card-actions>
</v-card>
</template>
@@ -0,0 +1,115 @@
<script setup lang="ts">
import { ref } from "vue";
const labels = ref({
0: "SU",
1: "MO",
2: "TU",
3: "WED",
4: "TH",
5: "FR",
6: "SA",
});
const expand = ref(false);
const time = ref(0);
const forecast = ref([
{ day: "Tuesday", icon: "mdi-white-balance-sunny", temp: "24\xB0/12\xB0" },
{ day: "Wednesday", icon: "mdi-white-balance-sunny", temp: "22\xB0/14\xB0" },
{ day: "Thursday", icon: "mdi-cloud", temp: "25\xB0/15\xB0" },
]);
</script>
<template>
<!-- ----------------------------------------------------------------------------- -->
<!-- Weather -->
<!-- ----------------------------------------------------------------------------- -->
<v-card class="mx-auto" elevation="0">
<v-card-item title="Florida">
<template v-slot:subtitle>
<v-icon
icon="mdi-alert"
size="18"
color="error"
class="me-1 pb-1"
></v-icon>
Extreme Weather Alert
</template>
</v-card-item>
<v-card-text class="py-0">
<v-row align="center" no-gutters>
<v-col
class="text-h3"
cols="6"
>
64&deg;F
</v-col>
<v-col cols="6" class="text-right">
<v-icon
color="error"
icon="mdi-weather-hurricane"
size="40"
></v-icon>
</v-col>
</v-row>
</v-card-text>
<div class="d-flex py-3 justify-space-between">
<v-list-item
density="compact"
prepend-icon="mdi-weather-windy"
>
<v-list-item-subtitle>123 km/h</v-list-item-subtitle>
</v-list-item>
<v-list-item
density="compact"
prepend-icon="mdi-weather-pouring"
>
<v-list-item-subtitle>48%</v-list-item-subtitle>
</v-list-item>
</div>
<v-expand-transition>
<div v-if="expand">
<div class="py-2">
<v-slider
v-model="time"
:max="6"
:step="1"
:ticks="labels"
class="mx-4"
color="primary"
density="compact"
hide-details
show-ticks="always"
thumb-size="10"
></v-slider>
</div>
<v-list class="bg-transparent">
<v-list-item
v-for="item in forecast"
:key="item.day"
:title="item.day"
:append-icon="item.icon"
:subtitle="item.temp"
>
</v-list-item>
</v-list>
</div>
</v-expand-transition>
<v-divider></v-divider>
<v-card-actions>
<v-btn @click="expand = !expand">
{{ !expand ? 'Full Report' : 'Hide Report' }}
</v-btn>
</v-card-actions>
</v-card>
</template>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
+9
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>
@@ -0,0 +1,53 @@
<script setup lang="ts">
import { ref } from "vue";
const dialog = ref(false)
defineExpose({
dialog
});
// const model = defineModel<boolean>();
const props = defineProps({
dialogTitle: {
type: String,
default: 'Confirm Action'
},
dialogMessage: {
type: String,
default: 'Are you sure you want to perform this action?'
}
});
const emit = defineEmits(['confirm']);
function handleConfirmDialog(data: any) {
emit('confirm'); // Memberitahu parent untuk tambah data
dialog.value = false; // Tutup dialog
}
</script>
<template>
<v-dialog v-model="dialog" persistent class="dialog-mw" max-width="500">
<template v-slot:activator="{ props }">
<v-btn color="warning" class="w-100" v-bind="props" flat> Open Confirm Dialog </v-btn>
</template>
<v-card class="pa-6">
<v-card-title class="text-h5">
{{ dialogTitle}}
</v-card-title>
<v-card-text>{{ dialogMessage }}</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="error" variant="tonal" @click="dialog = false" flat>
Tidak
</v-btn>
<v-btn color="success" variant="tonal" @click="handleConfirmDialog(1)" flat>
Ya
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
+54
View File
@@ -0,0 +1,54 @@
<script setup lang="ts">
// defineModel membuat variabel 'modelValue' yang otomatis sinkron dengan Parent
const isOpen = defineModel<boolean>({ default: false });
const props = defineProps({
title: { type: String, default: 'Konfirmasi' },
message: { type: String, default: '' }
});
const emit = defineEmits(['action-ya']);
const handleYa = () => {
emit('action-ya'); // Kirim sinyal ke parent untuk proses data
isOpen.value = false; // Tutup modal
};
</script>
<template>
<v-dialog v-model="isOpen" persistent max-width="450">
<v-card class="pa-4" rounded="xl">
<v-card-title class="text-h5 font-weight-bold">
{{ title }}
</v-card-title>
<v-card-text class="text-body-1">
{{ message }}
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="pink-lighten-5"
class="text-pink-accent-2 px-6"
variant="flat"
rounded="lg"
@click="isOpen = false"
>
Tidak
</v-btn>
<v-btn
color="cyan-lighten-5"
class="text-cyan-darken-1 px-6"
variant="flat"
rounded="lg"
@click="handleYa"
>
Ya
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
@@ -0,0 +1,65 @@
<template>
<v-expansion-panels>
<v-expansion-panel elevation="10">
<v-expansion-panel-title>
<v-row no-gutters>
<v-col cols="12" md="5" class="d-flex justify-start">
<h6 class="text-h6">General settings</h6>
</v-col>
<v-col cols="12" md="6" class="d-flex justify-start mt-md-0 mt-3">
<h6 class="text-subtitle-1">i am an accordion</h6>
</v-col>
</v-row>
</v-expansion-panel-title>
<v-expansion-panel-text>
Nulla facilisi. Phasellus sollicitudin nulla et quam mattis feugiat. Aliquam eget maximus est, id dignissim quam.
</v-expansion-panel-text>
<v-divider></v-divider>
</v-expansion-panel>
<v-expansion-panel elevation="10">
<v-expansion-panel-title>
<v-row no-gutters>
<v-col cols="12" md="5" class="d-flex justify-start">
<h6 class="text-h6">Users</h6>
</v-col>
<v-col cols="12" md="6" class="d-flex justify-start mt-md-0 mt-3">
<h6 class="text-subtitle-1">You are currently not an owner</h6>
</v-col>
</v-row>
</v-expansion-panel-title>
<v-expansion-panel-text>
Nulla facilisi. Phasellus sollicitudin nulla et quam mattis feugiat. Aliquam eget maximus est, id dignissim quam.
</v-expansion-panel-text>
<v-divider></v-divider>
</v-expansion-panel>
<v-expansion-panel elevation="10">
<v-expansion-panel-title>
<v-row no-gutters>
<v-col cols="12" md="5" class="d-flex justify-start">
<h6 class="text-h6">Advance Settings</h6>
</v-col>
<v-col cols="12" md="6" class="d-flex justify-start mt-md-0 mt-3">
<h6 class="text-subtitle-1">Filtering has been entirely disabled for whole web server</h6>
</v-col>
</v-row>
</v-expansion-panel-title>
<v-expansion-panel-text>
Nulla facilisi. Phasellus sollicitudin nulla et quam mattis feugiat. Aliquam eget maximus est, id dignissim quam.
</v-expansion-panel-text>
<v-divider></v-divider>
</v-expansion-panel>
<v-expansion-panel elevation="10">
<v-expansion-panel-title>
<v-row no-gutters>
<v-col cols="10" class="d-flex justify-start mt-md-0 mt-3">
<h6 class="text-h6">Personal data</h6>
</v-col>
</v-row>
</v-expansion-panel-title>
<v-expansion-panel-text>
Nulla facilisi. Phasellus sollicitudin nulla et quam mattis feugiat. Aliquam eget maximus est, id dignissim quam.
</v-expansion-panel-text>
<v-divider></v-divider>
</v-expansion-panel>
</v-expansion-panels>
</template>
@@ -0,0 +1,19 @@
<template>
<v-expansion-panels>
<v-expansion-panel elevation="10">
<v-expansion-panel-title class="text-h6">Accordion 1</v-expansion-panel-title>
<v-expansion-panel-text> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.</v-expansion-panel-text>
</v-expansion-panel>
<v-divider></v-divider>
<v-expansion-panel elevation="10">
<v-expansion-panel-title class="text-h6">Accordion 2</v-expansion-panel-title>
<v-expansion-panel-text> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.</v-expansion-panel-text>
</v-expansion-panel>
<v-divider></v-divider>
<v-expansion-panel elevation="10" >
<v-expansion-panel-title class="text-h6">Accordion 3</v-expansion-panel-title>
<v-expansion-panel-text> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.</v-expansion-panel-text>
</v-expansion-panel>
<v-divider></v-divider>
</v-expansion-panels>
</template>
@@ -0,0 +1,43 @@
<script setup lang="ts">
import { ref } from 'vue';
</script>
<template>
<v-expansion-panels>
<v-expansion-panel elevation="10">
<v-expansion-panel-title expand-icon="mdi-plus" collapse-icon="mdi-minus" class="text-h6">
Accordion 1
</v-expansion-panel-title>
<v-expansion-panel-text>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</v-expansion-panel-text>
<v-divider></v-divider>
</v-expansion-panel>
<v-expansion-panel elevation="10">
<v-expansion-panel-title class="text-h6">
Accordion 2
<template v-slot:actions="{ expanded }">
<v-icon :color="!expanded ? 'teal' : ''" :icon="expanded ? 'mdi-pencil' : 'mdi-check'"></v-icon>
</template>
</v-expansion-panel-title>
<v-expansion-panel-text>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</v-expansion-panel-text>
<v-divider></v-divider>
</v-expansion-panel>
<v-expansion-panel elevation="10">
<v-expansion-panel-title disable-icon-rotate class="text-h6">
Accordion 3
<template v-slot:actions>
<v-icon color="primary" icon="mdi-alert-circle">
</v-icon>
</template>
</v-expansion-panel-title>
<v-expansion-panel-text>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</v-expansion-panel-text>
<v-divider></v-divider>
</v-expansion-panel>
</v-expansion-panels>
</template>
@@ -0,0 +1,23 @@
<script setup lang="ts">
import { ref } from 'vue';
const panel = ref([0]);
</script>
<template>
<v-expansion-panels v-model="panel">
<v-expansion-panel elevation="10" >
<v-expansion-panel-title class="text-h6">Accordion 1</v-expansion-panel-title>
<v-expansion-panel-text> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.</v-expansion-panel-text>
</v-expansion-panel>
<v-divider></v-divider>
<v-expansion-panel elevation="10">
<v-expansion-panel-title class="text-h6">Accordion 2</v-expansion-panel-title>
<v-expansion-panel-text> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.</v-expansion-panel-text>
</v-expansion-panel>
<v-divider></v-divider>
<v-expansion-panel elevation="10">
<v-expansion-panel-title class="text-h6">Accordion 3</v-expansion-panel-title>
<v-expansion-panel-text> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.</v-expansion-panel-text>
</v-expansion-panel>
</v-expansion-panels>
</template>
@@ -0,0 +1,19 @@
<template>
<v-expansion-panels variant="inset">
<v-expansion-panel elevation="10">
<v-expansion-panel-title class="text-h6">Accordion 1</v-expansion-panel-title>
<v-expansion-panel-text> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.</v-expansion-panel-text>
<v-divider></v-divider>
</v-expansion-panel>
<v-expansion-panel elevation="10">
<v-expansion-panel-title class="text-h6">Accordion 2</v-expansion-panel-title>
<v-expansion-panel-text> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.</v-expansion-panel-text>
<v-divider></v-divider>
</v-expansion-panel>
<v-expansion-panel elevation="10" >
<v-expansion-panel-title class="text-h6">Accordion 3</v-expansion-panel-title>
<v-expansion-panel-text> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.</v-expansion-panel-text>
<v-divider></v-divider>
</v-expansion-panel>
</v-expansion-panels>
</template>
@@ -0,0 +1,19 @@
<template>
<v-expansion-panels variant="popout">
<v-expansion-panel elevation="10">
<v-expansion-panel-title class="text-h6">Accordion 1</v-expansion-panel-title>
<v-expansion-panel-text> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.</v-expansion-panel-text>
<v-divider></v-divider>
</v-expansion-panel>
<v-expansion-panel elevation="10">
<v-expansion-panel-title class="text-h6">Accordion 2</v-expansion-panel-title>
<v-expansion-panel-text> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.</v-expansion-panel-text>
<v-divider></v-divider>
</v-expansion-panel>
<v-expansion-panel elevation="10" >
<v-expansion-panel-title class="text-h6">Accordion 3</v-expansion-panel-title>
<v-expansion-panel-text> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.</v-expansion-panel-text>
<v-divider></v-divider>
</v-expansion-panel>
</v-expansion-panels>
</template>
@@ -0,0 +1,59 @@
<script setup lang="ts">
import { shallowRef } from 'vue';
import {ChevronUpIcon} from 'vue-tabler-icons';
import {ChevronDownIcon} from 'vue-tabler-icons';
const props = defineProps(['icon']);
const component = props.icon;
// custom list data
const customs = shallowRef([
{
title: 'Bajaj Finsery',
profit: true,
percent: '10',
price: '1839.00'
},
{
title: 'TTML',
profit: false,
percent: '10',
price: '100.00'
},
{
title: 'Reliance',
profit: true,
percent: '10',
price: '200.00'
},
{
title: 'TTML',
profit: false,
percent: '10',
price: '189.00'
}
]);
</script>
<template>
<v-list two-lines>
<template v-for="(custom, i) in customs" :key="i">
<v-list-item color="primary" class="py-3">
<v-list-item-title class="text-subtitle-1">{{ custom.title }}</v-list-item-title>
<v-list-item-subtitle v-if="custom.profit" class="text-subtitle-2 text-success text-high-emphasis"
>{{ custom.percent }}% Profit</v-list-item-subtitle
>
<v-list-item-subtitle v-else class="text-subtitle-2 text-error "
>{{ custom.percent }}% Loss</v-list-item-subtitle
>
<template v-slot:append>
<v-list-item-subtitle class="text-subtitle-1 text-high-emphasis mr-3"> ${{ custom.price }}</v-list-item-subtitle>
<v-chip color="success" label size="x-small" v-if="custom.profit">
<ChevronUpIcon size="17" stroke-width="1.5" />
</v-chip>
<v-chip color="error" label size="x-small" v-else>
<ChevronDownIcon size="17" stroke-width="1.5" />
</v-chip>
</template>
</v-list-item>
<v-divider></v-divider>
</template>
</v-list>
</template>
@@ -0,0 +1,43 @@
<script setup lang="ts">
import { shallowRef } from 'vue';
import { AppsIcon, CircleDotIcon, DragDropIcon, FolderIcon, ChevronUpIcon, ChevronDownIcon } from 'vue-tabler-icons';
const props = defineProps(['icon']);
const component = props.icon;
// List 1,3 Data
const list1 = shallowRef([
{
name: 'Sample Page',
icon: AppsIcon,
id: 1,
link: '/basic/list'
},
{
name: 'Elements',
icon: CircleDotIcon,
id: 2,
link: ''
},
{
name: 'Page Layouts',
icon: FolderIcon,
id: 3,
link: ''
},
]);
</script>
<template>
<v-list disabled>
<v-card variant="outlined" class="py-2">
<v-list-item class="mb-2" v-for="(list, i) in list1" :value="list" rounded="md" :key="i" color="primary">
<template v-slot:prepend>
<component :is="list.icon" size="20" stroke-width="1.5" class="mr-2" />
</template>
<v-list-item-title v-text="list.name"></v-list-item-title>
</v-list-item>
</v-card>
</v-list>
</template>
@@ -0,0 +1,42 @@
<script setup lang="ts">
import { shallowRef } from 'vue';
import { FolderIcon,BriefcaseIcon,BeachIcon } from 'vue-tabler-icons';
const props = defineProps(['icon']);
const folders = shallowRef([
{
subtitle: 'Jan 9, 2022',
title: 'Photos',
icon:FolderIcon,
},
{
subtitle: 'Jan 17, 2022',
title: 'Works',
icon:BriefcaseIcon
},
{
subtitle: 'Jan 18, 2022',
title: 'Vacation',
icon:BeachIcon
}
]);
</script>
<template>
<v-list lines="two">
<v-card variant="outlined">
<v-list-item v-for="folder in folders" :key="folder.title" :subtitle="folder.subtitle">
<template v-slot:prepend>
<v-avatar color="grey400">
<component :is="folder.icon" size="20" stroke-width="1.5" />
</v-avatar>
</template>
<template v-slot:title>
<h5 class="text-subtitle-1">{{ folder.title }}</h5>
</template>
<template v-slot:subtitle>
<span class="text-subtitle-2">{{ folder.subtitle }}</span>
</template>
</v-list-item>
</v-card>
</v-list>
</template>
@@ -0,0 +1,40 @@
<script setup lang="ts">
import { shallowRef } from 'vue';
import { CircleDotIcon, DragDropIcon, InboxIcon, MailIcon, SendIcon } from 'vue-tabler-icons';
const props = defineProps(['icon']);
// List 2 data
const open = shallowRef(['Users']);
</script>
<template>
<v-list >
<v-card variant="outlined" class="py-2">
<div class="text-subttile-2 pl-4 py-3">Nested List Items</div>
<v-list-item value="" class="mb-2" color="primary">
<template v-slot:prepend>
<SendIcon size="20" stroke-width="1.5" class="mr-2" />
</template>
<v-list-item-title >Sent Mail</v-list-item-title>
</v-list-item>
<v-list-item value="" class="mb-2" color="primary">
<template v-slot:prepend>
<MailIcon size="20" stroke-width="1.5" class="mr-2" />
</template>
<v-list-item-title >Drafts</v-list-item-title>
</v-list-item>
<v-list-group value="Users">
<template v-slot:activator="{ props }">
<v-list-item v-bind="props" rounded="md" color="primary" title="inbox">
<template v-slot:prepend>
<InboxIcon size="20" stroke-width="1.5" class="mr-2" />
</template>
</v-list-item>
</template>
<v-list-item value="Started" color="primary" title="Started" rounded="md">
<template v-slot:prepend>
<CircleDotIcon size="15" stroke-width="1.5" class="mr-2" />
</template>
</v-list-item>
</v-list-group>
</v-card>
</v-list>
</template>

Some files were not shown because too many files have changed in this diff Show More