Alisa/web/src/components/HeaderBar.vue
2024-07-11 13:25:39 +02:00

333 lines
9.3 KiB
Vue

<template>
<div>
<v-toolbar color="main" dark prominent>
<img src="../assets/turbologo.svg" alt="logo" class="logo" width="75" />
<v-spacer></v-spacer>
<!-- Create, Edit -->
<div>
<!-- -->
<!-- GROUP SECTION -->
<!-- -->
<v-btn icon class="mr-3" @click="group = true">
<FolderPlus />
</v-btn>
<v-dialog v-model="group" width="600" persistent>
<v-card max-width="600">
<v-form @submit.prevent="submit">
<v-card-title>
<span class="headline">Add Group</span>
</v-card-title>
<v-card-subtitle>
<span> Add a Group to the Database</span>
</v-card-subtitle>
<v-card-text>
<div>
<v-text-field
label="Group Name *"
v-model="groupLicenseName"
variant="outlined"
required
clearable
:rules="licenseGroupRules"
class="mb-3"
></v-text-field>
</div>
</v-card-text>
<v-card-actions>
<v-row>
<v-col cols="10" align="right" no-gutters>
<v-btn
class="ms-auto"
text="Cancel"
@click="group = false"
></v-btn>
</v-col>
<v-col>
<v-btn class="ms-auto" text="Add" type="submit"></v-btn>
</v-col>
</v-row>
</v-card-actions>
</v-form>
</v-card>
</v-dialog>
<!-- -->
<!-- ADD SECTION -->
<!-- -->
<v-btn icon class="mr-3" @click="add = true">
<Plus />
</v-btn>
<v-dialog v-model="add" width="600" persistent>
<v-card max-width="600">
<v-form @submit.prevent="submit">
<v-card-title>
<span class="headline">Add License</span>
</v-card-title>
<v-card-subtitle>
<span> Add an extra License to the database</span>
</v-card-subtitle>
<v-card-text>
<div>
<v-text-field
label="License Name *"
v-model="addLicenseName"
variant="outlined"
required
clearable
:rules="licenseNameRules"
class="mb-3"
></v-text-field>
<v-text-field
label="License Key *"
v-model="addLicenseKey"
variant="outlined"
required
clearable
:rules="licenseKeyRules"
class="mb-3"
></v-text-field>
<v-autocomplete
clearable
label="Select Group *"
:items="data"
variant="outlined"
:rules="selectGroupRules"
class="mb-1"
v-model="addLicenseGroup"
></v-autocomplete>
<!-- Divider maybe remove -->
<v-divider
class="border-opacity-50"
:thickness="2"
></v-divider>
<div>
<div class="mb-3 mt-3">
<v-date-input
label="Start Date (optional)"
variant="outlined"
prepend-icon=""
prepend-inner-icon="mdi-calendar-check"
clearable
v-model="addStartDate"
hide-details
></v-date-input>
</div>
<div class="mb-6">
<v-date-input
label="Stop Date (optional)"
variant="outlined"
prepend-icon=""
prepend-inner-icon="mdi-calendar-remove"
clearable
v-model="addStopDate"
hide-details
></v-date-input>
</div>
</div>
<v-number-input
label="Amount (optional)"
variant="outlined"
clearable
:min="0"
v-model="addAmount"
>
</v-number-input>
<v-text-field
label="Notes (optional)"
v-model="addNotes"
variant="outlined"
clearable
></v-text-field>
<span class="dialogNote">
all fields marked with * are required
</span>
</div>
</v-card-text>
<v-card-actions>
<v-row>
<v-col cols="10" align="right" no-gutters>
<v-btn
class="ms-auto"
text="Cancel"
@click="add = false"
></v-btn>
</v-col>
<v-col>
<v-btn class="ms-auto" text="Add" type="submit"></v-btn>
</v-col>
</v-row>
</v-card-actions>
</v-form>
</v-card>
</v-dialog>
</div>
<!-- Search -->
<v-text-field
class="compact-form mr-2"
label="Search"
variant="solo"
density="compact"
prepend-inner-icon="mdi-magnify"
hide-details
single-line
clearable
rounded="pill"
></v-text-field>
<!-- Logout -->
<v-btn icon variant="outlined" @click="handlelogout">
<LogOut />
</v-btn>
</v-toolbar>
</div>
<v-snackbar v-model="snackbar" :timeout="2000" elevation="24" location="top">
<span> Who am I??? </span>
</v-snackbar>
</template>
<script setup lang="ts">
import { store } from "@/store";
import { SubmitEventPromise } from "vuetify";
import { ref } from "vue";
import { Plus, LogOut, Pencil, FolderPlus } from "lucide-vue-next";
import { useQuery, useMutation, useQueryClient } from "@tanstack/vue-query";
import axios from "axios";
import { axiosInstance } from "@/client";
import { LicenseGroup, CreateLicenseDto } from "@/types";
const queryClient = useQueryClient();
const { data } = useQuery({
queryKey: ["licenses"],
queryFn: async () => {
const res = await axios.get<LicenseGroup[]>(
import.meta.env.VITE_BACKEND_URL + "/licenses",
{
headers: {
Authorization: `Bearer ${store.token}`,
},
}
);
return res.data;
},
select: (data) => {
return data.map((group) => {
return {
title: group.name,
value: group.id,
};
});
},
});
const { isPending, mutate } = useMutation({
mutationFn: async (newLicense: CreateLicenseDto) => {
await axiosInstance.post("/licenses", newLicense);
},
onError: (error) => {
snackbar.value = true;
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["licenses"] });
add.value = false;
},
});
function handlelogout() {
store.setToken(null);
}
async function submit(event: SubmitEventPromise) {
const result = await event;
if (result.valid && addLicenseGroup.value) {
const data = {
name: addLicenseName.value,
group_id: addLicenseGroup.value,
amount: addAmount.value,
key: addLicenseKey.value,
start: addStartDate.value,
stop: addStopDate.value,
notes: addNotes.value,
};
console.log(data);
mutate(data);
} else {
console.log("Invalid");
}
}
const snackbar = ref(false);
//
// GROUP SECTION
//
const group = ref(false); // Dialog for Group
const groupLicenseName = ref<string>("");
// Rules for Group Dialog
const licenseGroupRules = [
(value: string) => {
if (value) return true;
return "YOU MUST ENTER (A GROUP NAME)";
},
];
//
// ADD SECTION
//
const add = ref(false);
// References for Add License Dialog
const addLicenseName = ref<string>("");
const addLicenseKey = ref<string>("");
const addLicenseGroup = ref<string>();
// Rules for Add License Dialog
const licenseNameRules = [
(value: string) => {
if (value) return true;
return "YOU MUST ENTER (A LICENSE NAME)";
},
];
const selectGroupRules = [
(value: string) => {
if (value) return true;
return "YOU MUST SELECT (A LICENSE GROUP)";
},
];
const licenseKeyRules = [
(value: string) => {
if (value) return true;
return "YOU MUST ENTER (A LICENSE KEY)";
},
];
// Optional Fields
const addAmount = ref<number | undefined>();
const addNotes = ref<string | undefined>("");
// Date Picker
const addStartDate = ref<Date | undefined>();
const addStopDate = ref<Date | undefined>();
//
// EDIT SECTION
//
const edit = ref(false);
</script>
<style scoped>
.logo {
margin-right: 20%;
margin-left: 10px;
}
.dialogNote {
font-size: 13px;
color: grey;
}
</style>