LOA UI completed (without integration)

This commit is contained in:
2025-09-15 18:32:20 -04:00
parent 456c29a731
commit 303b72a160
33 changed files with 984 additions and 7 deletions

122
ui/src/pages/LOA.vue Normal file
View File

@@ -0,0 +1,122 @@
<script setup lang="ts">
import { Check, Search } from "lucide-vue-next"
import { Combobox, ComboboxAnchor, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxItemIndicator, ComboboxList } from "@/components/ui/combobox"
import { getRanks, Rank } from "@/api/rank"
import { onMounted, ref } from "vue";
import { Member, getMembers } from "@/api/member";
import Button from "@/components/ui/button/Button.vue";
import {
CalendarDate,
DateFormatter,
getLocalTimeZone,
} from "@internationalized/date"
import type { DateRange } from "reka-ui"
import type { Ref } from "vue"
import Popover from "@/components/ui/popover/Popover.vue";
import PopoverTrigger from "@/components/ui/popover/PopoverTrigger.vue";
import PopoverContent from "@/components/ui/popover/PopoverContent.vue";
import { RangeCalendar } from "@/components/ui/range-calendar"
import { cn } from "@/lib/utils";
import { CalendarIcon } from "lucide-vue-next"
import Input from "@/components/ui/input/Input.vue";
import Textarea from "@/components/ui/textarea/Textarea.vue";
import Separator from "@/components/ui/separator/Separator.vue";
const members = ref<Member[]>([])
const currentMember = ref<Member | null>(null);
defineProps({
adminMode: {
type: Boolean,
default: false
}
})
const df = new DateFormatter("en-US", {
dateStyle: "medium",
})
const value = ref({
start: new CalendarDate(2022, 1, 20),
end: new CalendarDate(2022, 1, 20).add({ days: 20 }),
}) as Ref<DateRange>
onMounted(async () => {
members.value = await getMembers();
});
</script>
<template>
<div class="flex flex-row-reverse gap-6 mx-auto m-10" :class="!adminMode ? 'max-w-5xl' : 'max-w-2xl'">
<div v-if="!adminMode" class="flex-1 flex space-x-4 rounded-md border p-4">
<div class="flex-2 space-y-1">
<p class="text-sm font-medium leading-none">
LOA Policy
</p>
<p class="text-sm text-muted-foreground">
Policy goes here.
</p>
</div>
<Switch />
</div>
<div class="flex-1 flex flex-col gap-5">
<div class="flex w-full gap-5 ">
<Combobox class="w-1/2" v-model="currentMember" :disabled="!adminMode">
<ComboboxAnchor class="w-full">
<ComboboxInput placeholder="Search members..." class="w-full pl-9"
:display-value="(v) => v ? v.member_name : ''" />
</ComboboxAnchor>
<ComboboxList class="w-full">
<ComboboxEmpty class="text-muted-foreground">No results</ComboboxEmpty>
<ComboboxGroup>
<template v-for="member in members" :key="member.member_id">
<ComboboxItem :value="member"
class="data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground relative cursor-pointer select-none px-2 py-1.5">
{{ member.member_name }}
<ComboboxItemIndicator class="absolute left-2 inline-flex items-center">
<Check class="h-4 w-4" />
</ComboboxItemIndicator>
</ComboboxItem>
</template>
</ComboboxGroup>
</ComboboxList>
</Combobox>
<Popover>
<PopoverTrigger as-child>
<Button variant="outline" :class="cn(
'w-1/2 justify-start text-left font-normal',
!value && 'text-muted-foreground',
)">
<CalendarIcon class="mr-2 h-4 w-4" />
<template v-if="value.start">
<template v-if="value.end">
{{ df.format(value.start.toDate(getLocalTimeZone())) }} - {{
df.format(value.end.toDate(getLocalTimeZone())) }}
</template>
<template v-else>
{{ df.format(value.start.toDate(getLocalTimeZone())) }}
</template>
</template>
<template v-else>
Pick a date
</template>
</Button>
</PopoverTrigger>
<PopoverContent class="w-auto p-0">
<RangeCalendar v-model="value" initial-focus :number-of-months="2"
@update:start-value="(startDate) => value.start = startDate" />
</PopoverContent>
</Popover>
</div>
<Textarea placeholder="Reason for LOA" class="w-full resize-none" />
<div class="flex justify-end">
<Button :onClick="() => { }" class="w-min">Submit</Button>
</div>
</div>
</div>
</template>