185 lines
3.8 KiB
Vue
185 lines
3.8 KiB
Vue
<script setup>
|
|
import { ref } from "vue";
|
|
import { useRouter } from "vue-router";
|
|
import { useModalStore } from "@/stores/modal";
|
|
import {
|
|
Home,
|
|
Community,
|
|
Calendar,
|
|
Hammer,
|
|
MultiplePagesPlus,
|
|
PathArrowSolid,
|
|
Clock,
|
|
HistoricShield,
|
|
Developer,
|
|
} from "@iconoir/vue";
|
|
import SpeedDial from "primevue/speeddial";
|
|
|
|
const router = useRouter();
|
|
const modalStore = useModalStore();
|
|
|
|
const developmentButtons = ref([
|
|
{
|
|
label: "Error Handling Demo",
|
|
command: () => {
|
|
router.push("/dev/error-handling-demo");
|
|
},
|
|
},
|
|
]);
|
|
|
|
const createButtons = ref([
|
|
{
|
|
label: "Client",
|
|
command: () => {
|
|
router.push("/client?new=true");
|
|
},
|
|
},
|
|
{
|
|
label: "On-Site Meeting",
|
|
command: () => {
|
|
router.push("/onsitemeetings/new");
|
|
},
|
|
},
|
|
{
|
|
label: "Estimate",
|
|
command: () => {
|
|
//frappe.new_doc("Estimate");
|
|
router.push("/createEstimate/new");
|
|
},
|
|
},
|
|
{
|
|
label: "Job",
|
|
command: () => {
|
|
//frappe.new_doc("Job");
|
|
modalStore.openModal("createJob");
|
|
},
|
|
},
|
|
{
|
|
label: "Invoice",
|
|
command: () => {
|
|
modalStore.openModal("createInvoice");
|
|
},
|
|
},
|
|
{
|
|
label: "Warranty Claim",
|
|
command: () => {
|
|
modalStore.openModal("createWarranty");
|
|
},
|
|
},
|
|
]);
|
|
|
|
const categories = ref([
|
|
{ name: "Home", icon: Home, url: "/" },
|
|
{ name: "Calendar", icon: Calendar, url: "/calendar" },
|
|
{ name: "Clients", icon: Community, url: "/clients" },
|
|
{ name: "Jobs", icon: Hammer, url: "/jobs" },
|
|
{ name: "Routes", icon: PathArrowSolid, url: "/routes" },
|
|
{ name: "Time Sheets", icon: Clock, url: "/timesheets" },
|
|
{ name: "Warranties", icon: HistoricShield, url: "/warranties" },
|
|
{
|
|
name: "Create New",
|
|
icon: MultiplePagesPlus,
|
|
buttons: createButtons,
|
|
},
|
|
{ name: "Development", icon: Developer, buttons: developmentButtons },
|
|
]);
|
|
const handleCategoryClick = (category) => {
|
|
router.push(category.url);
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div id="sidebar" class="sidebar">
|
|
<template v-for="category in categories">
|
|
<template v-if="category.url">
|
|
<button
|
|
:class="[
|
|
'sidebar-button',
|
|
router.currentRoute.value.path === category.url ? 'active' : '',
|
|
]"
|
|
:key="category.name"
|
|
@click="handleCategoryClick(category)"
|
|
>
|
|
<component :is="category.icon" class="button-icon" /><span
|
|
class="button-text"
|
|
>{{ category.name }}</span
|
|
>
|
|
</button>
|
|
</template>
|
|
<template v-else>
|
|
<SpeedDial :model="category.buttons" direction="down" type="linear" radius="50">
|
|
<template #button="{ toggleCallback }">
|
|
<button
|
|
class="sidebar-button"
|
|
@click="toggleCallback"
|
|
:key="category.name"
|
|
>
|
|
<component :is="category.icon" class="button-icon" /><span
|
|
class="button-text"
|
|
>{{ category.name }}</span
|
|
>
|
|
</button>
|
|
</template>
|
|
<template #item="{ item, toggleCallback }">
|
|
<button class="create-item" @click="toggleCallback" :key="item.label">
|
|
<span class="p-menuitem-text">{{ item.label }}</span>
|
|
</button>
|
|
</template>
|
|
</SpeedDial>
|
|
</template>
|
|
</template>
|
|
</div>
|
|
</template>
|
|
|
|
<style lang="css">
|
|
.sidebar-button.active {
|
|
background-color: rgb(25, 60, 53);
|
|
color: white;
|
|
}
|
|
|
|
.sidebar-button:hover {
|
|
background-color: rgb(82, 132, 119);
|
|
}
|
|
|
|
.button-icon {
|
|
justify-self: flex-start;
|
|
margin-left: 5px;
|
|
}
|
|
|
|
.create-item {
|
|
border: none;
|
|
background-color: transparent;
|
|
width: 100%;
|
|
text-align: left;
|
|
padding: 5px 10px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.button-text {
|
|
margin-left: auto;
|
|
margin-right: auto;
|
|
}
|
|
|
|
.sidebar-button {
|
|
border-radius: 5px;
|
|
border: none;
|
|
background-color: rgb(69, 112, 101);
|
|
color: white;
|
|
display: flex;
|
|
width: 100%;
|
|
align-items: center;
|
|
}
|
|
|
|
#sidebar {
|
|
display: flex;
|
|
flex-direction: column;
|
|
width: 150px;
|
|
align-self: flex-start;
|
|
gap: 10px;
|
|
background-color: #f3f3f3;
|
|
padding: 10px;
|
|
border-radius: 5px;
|
|
margin-top: 10px;
|
|
position: relative;
|
|
}
|
|
</style>
|