feat(timesheet): added timesheet page, created timsheet-interface and setup store and api

This commit is contained in:
Matthieu Haineault 2025-09-02 14:30:46 -04:00
parent 2eae6e5a21
commit d20f970958
5 changed files with 85 additions and 25 deletions

View File

@ -0,0 +1,33 @@
import { useAuthStore } from "src/stores/auth-store";
import { useTimesheetStore } from "src/stores/timesheet-store"
import { ref } from "vue";
import { timesheetTempService } from "../services/timesheet-services";
export const useTimesheetApi = () => {
const timesheet_store = useTimesheetStore();
const auth_store = useAuthStore();
const week_offset = ref(0);
const fetch_week = async (offset = week_offset.value) => {
const email = auth_store.user?.email;
if(!email) return;
try{
timesheet_store.is_loading = true;
const timesheet = await timesheetTempService.getTimesheetsByEmail(email, offset);
timesheet_store.current_timesheet = timesheet;
week_offset.value = offset;
}catch (err) {
console.error('fetch week error', err);
timesheet_store.current_timesheet = { ...timesheet_store.current_timesheet, shifts: [], expenses: [] };
} finally {
timesheet_store.is_loading = false;
}
};
const this_week = async () => fetch_week(0);
const next_week = async () => fetch_week(week_offset.value + 1);
const previous_week = async () => fetch_week(week_offset.value - 1);
return { week_offset, this_week, next_week, previous_week, fetch_week};
}

View File

@ -1,12 +1,19 @@
<script setup lang="ts"> <script setup lang="ts">
import { date } from 'quasar'; import { date } from 'quasar';
import { useTimesheetStore } from 'src/stores/timesheet-store'; import { useTimesheetStore } from 'src/stores/timesheet-store';
import { computed } from 'vue'; import { useTimesheetApi } from '../composables/use-timesheet-api';
import { computed, onMounted } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
const {locale} = useI18n(); const { locale } = useI18n();
const timeSheet_store = useTimesheetStore(); const timesheet_store = useTimesheetStore();
const { this_week } = useTimesheetApi();
onMounted(async () => {
await this_week();
});
const date_options: Intl.DateTimeFormatOptions = { const date_options: Intl.DateTimeFormatOptions = {
day: 'numeric', day: 'numeric',
month: 'long', month: 'long',
@ -14,7 +21,8 @@ import { useI18n } from 'vue-i18n';
}; };
const timesheet_label = computed(() => { const timesheet_label = computed(() => {
const dates = timeSheet_store.current_timesheet.label.split('.'); const dates = timesheet_store.current_timesheet.label.split('.');
console.log(dates);
const start_date = new Intl.DateTimeFormat(locale.value, date_options).format(date.extractDate(dates[0] as string, 'YYYY-MM-DD')); const start_date = new Intl.DateTimeFormat(locale.value, date_options).format(date.extractDate(dates[0] as string, 'YYYY-MM-DD'));
const end_date = new Intl.DateTimeFormat(locale.value, date_options).format(date.extractDate(dates[1] as string, 'YYYY-MM-DD')); const end_date = new Intl.DateTimeFormat(locale.value, date_options).format(date.extractDate(dates[1] as string, 'YYYY-MM-DD'));
@ -34,14 +42,14 @@ import { useI18n } from 'vue-i18n';
padding padding
class="q-pa-md bg secondary" class="q-pa-md bg secondary"
> >
<div class="text-h4 row justify-center q-mt-lg text-uppercase text-weight-bolder text-gray-8"> <div class="text-h4 row justify-center q-mt-lg text-uppercase text-weight-bolder text-grey-8">
{{ $t('pageTitles.timeSheets') }} {{ $t('pageTitles.timeSheets') }}
</div> </div>
<div class="row items-center justify-center q-py-none q-my-none"> <div class="row items-center justify-center q-py-none q-my-none">
<div class="text-primary text-h6 text-uppercase"> <div class="text-primary text-h6 text-uppercase">
{{ timesheet_label.start_date }} {{ timesheet_label.start_date }}
</div> </div>
<div class="text-primary text-h6 text-uppercase"> <div class="text-grey-8 text-weight-bold text-uppercase q-mx-md">
{{ $t('timeSheet.dateRangesTo') }} {{ $t('timeSheet.dateRangesTo') }}
</div> </div>
<div class="text-primary text-h6 text-uppercase"> <div class="text-primary text-h6 text-uppercase">

View File

@ -2,8 +2,8 @@ import { api } from "src/boot/axios";
import type {Timesheet} from "src/modules/timesheets/types/timesheet-interface"; import type {Timesheet} from "src/modules/timesheets/types/timesheet-interface";
export const timesheetTempService = { export const timesheetTempService = {
getTimesheetsByNumberAndEmail: async ( timesheet_id: number, email: string): Promise<Timesheet> => { getTimesheetsByEmail: async ( email: string, offset = 0): Promise<Timesheet> => {
const response = await api.get(`timesheet/id/${timesheet_id}/email/${email}`); const response = await api.get(`/timesheets/${encodeURIComponent(email)}`, {params: offset ? { offset } : undefined});
return response.data; return response.data as Timesheet;
}, },
}; };

View File

@ -1,9 +1,28 @@
export interface Timesheet { export interface Timesheet {
timesheet_id: number;
is_approved: boolean; is_approved: boolean;
start_day: string; start_day: string;
end_day: string; end_day: string;
label: string; label: string;
shifts: Shifts[]; shifts: Shifts[];
expenses: Expenses; expenses: Expenses[];
}
type Shifts = {
bank_type: string;
date: string;
start_time: string;
end_time: string;
description: string;
is_approved: boolean;
}
type Expenses = {
bank_type: string;
date: string;
amount: number;
km: number;
description: string;
supervisor_comment: string;
is_approved: boolean;
} }

View File

@ -7,7 +7,6 @@ import type { PayPeriodEmployeeDetails } from 'src/modules/timesheet-approval/ty
import type { PayPeriodReportFilters } from 'src/modules/timesheet-approval/types/timesheet-approval-pay-period-report-interface'; import type { PayPeriodReportFilters } from 'src/modules/timesheet-approval/types/timesheet-approval-pay-period-report-interface';
import type { Timesheet } from 'src/modules/timesheets/types/timesheet-interface'; import type { Timesheet } from 'src/modules/timesheets/types/timesheet-interface';
import { timesheetTempService } from 'src/modules/timesheets/services/timesheet-services'; import { timesheetTempService } from 'src/modules/timesheets/services/timesheet-services';
import type { EmployeeTimesheetDetailsWeek } from 'src/modules/timesheets/types/timesheet-details-interface';
const default_pay_period: PayPeriod = { const default_pay_period: PayPeriod = {
pay_period_no: -1, pay_period_no: -1,
@ -18,11 +17,14 @@ const default_pay_period: PayPeriod = {
label: '' label: ''
}; };
//employee timesheet
const default_timesheet: Timesheet = { const default_timesheet: Timesheet = {
timesheet_id: -1,
start_day: '', start_day: '',
end_day: '', end_day: '',
label: '', label: '',
is_approved: false,
shifts: [],
expenses: [],
}; };
export const useTimesheetStore = defineStore('timesheet', () => { export const useTimesheetStore = defineStore('timesheet', () => {
@ -35,7 +37,6 @@ export const useTimesheetStore = defineStore('timesheet', () => {
//employee timesheet //employee timesheet
const current_timesheet = ref<Timesheet>(default_timesheet); const current_timesheet = ref<Timesheet>(default_timesheet);
const timesheet_employee_details = ref<EmployeeTimesheetDetailsWeek | undefined>();
const getPayPeriodByDate = async (date_string: string): Promise<boolean> => { const getPayPeriodByDate = async (date_string: string): Promise<boolean> => {
is_loading.value = true; is_loading.value = true;
@ -99,20 +100,19 @@ export const useTimesheetStore = defineStore('timesheet', () => {
is_loading.value = false; is_loading.value = false;
}; };
const getTimesheetByNumberAndEmail = async (employee_email: string) => { //employee timesheet
const getTimesheetByEmail = async (employee_email: string) => {
is_loading.value = true; is_loading.value = true;
try{ try{
const response = await timesheetTempService.getTimesheetsByNumberAndEmail( const response = await timesheetTempService.getTimesheetsByEmail(employee_email);
current_timesheet.value.timesheet_id, current_timesheet.value = response;
employee_email
);
timesheet_employee_details.value = response;
}catch (error) { }catch (error) {
console.error('There was an error retrieving timesheet details for this employee: ', error); console.error('There was an error retrieving timesheet details for this employee: ', error);
} current_timesheet.value = { ...default_timesheet }
} finally {
is_loading.value = false; is_loading.value = false;
} }
}
const getTimesheetsByPayPeriodAndEmail = async (employee_email: string) => { const getTimesheetsByPayPeriodAndEmail = async (employee_email: string) => {
is_loading.value = true; is_loading.value = true;
@ -158,7 +158,7 @@ export const useTimesheetStore = defineStore('timesheet', () => {
current_timesheet, current_timesheet,
is_loading, is_loading,
getPayPeriodByDate, getPayPeriodByDate,
getTimesheetByNumberAndEmail, getTimesheetByEmail,
getPayPeriodByYearAndPeriodNumber, getPayPeriodByYearAndPeriodNumber,
getTimesheetApprovalPayPeriodEmployeeOverviews, getTimesheetApprovalPayPeriodEmployeeOverviews,
getTimesheetsByPayPeriodAndEmail, getTimesheetsByPayPeriodAndEmail,