diff --git a/src/assets/links/facturation-transparent.png b/src/assets/links/facturation-transparent.png index 550e260..1249e8e 100644 Binary files a/src/assets/links/facturation-transparent.png and b/src/assets/links/facturation-transparent.png differ diff --git a/src/assets/links/hydroQC_icon.png b/src/assets/links/hydroQC_icon.png index 63f77be..b97e65f 100644 Binary files a/src/assets/links/hydroQC_icon.png and b/src/assets/links/hydroQC_icon.png differ diff --git a/src/assets/links/intranet_logo.png b/src/assets/links/intranet_logo.png index 4ebcccf..bc9089b 100644 Binary files a/src/assets/links/intranet_logo.png and b/src/assets/links/intranet_logo.png differ diff --git a/src/assets/links/logo_gmail.png b/src/assets/links/logo_gmail.png index 9882513..b75b0de 100644 Binary files a/src/assets/links/logo_gmail.png and b/src/assets/links/logo_gmail.png differ diff --git a/src/css/app.scss b/src/css/app.scss index f5b3f6e..dfb3916 100644 --- a/src/css/app.scss +++ b/src/css/app.scss @@ -19,8 +19,8 @@ background: #fd4b2d !important; } -.q-table tbody tr:hover { - background: #00ff260c; +.q-table tbody tr:hover > td { + background-color: var(--q-accent2) !important; } body.body--dark { @@ -71,6 +71,6 @@ input[type=number] { } .q-field--dark .q-field__control:hover::before, .q-field--outlined .q-field__control:hover::before { - border-color: var(--q-accent); + border-color: var(--q-accent2); border-width: 2px; } \ No newline at end of file diff --git a/src/css/quasar.variables.scss b/src/css/quasar.variables.scss index 1b60238..b210fed 100644 --- a/src/css/quasar.variables.scss +++ b/src/css/quasar.variables.scss @@ -15,15 +15,13 @@ $primary : #30303A; $secondary : #DAE0E7; $accent : #0c9a3b; -$accent2 : #0a7d32; -$dark-shadow-color : #000000; +$dark-shadow-color : #000; -$elevation-dark-umbra : rgba($dark-shadow-color, 1); -$elevation-dark-penumbra : rgba($dark-shadow-color, 0.75); -$elevation-dark-ambient : rgba($dark-shadow-color, 0.53); +$elevation-dark-umbra : rgba($dark-shadow-color, .2); +$elevation-dark-penumbra : rgba($dark-shadow-color, .14); +$elevation-dark-ambient : rgba($dark-shadow-color, .12); -$dark-shadow-2 : 2px 3px $elevation-dark-umbra, 2px 3px 6px $elevation-dark-penumbra, 2px 3px 14px $elevation-dark-ambient; $layout-shadow-dark : 0 0 5px 5px rgba($dark-shadow-color, 0.5); $input-text-color : #455A64; diff --git a/src/i18n/en-ca/index.ts b/src/i18n/en-ca/index.ts index c462be4..cc08350 100644 --- a/src/i18n/en-ca/index.ts +++ b/src/i18n/en-ca/index.ts @@ -250,6 +250,7 @@ export default { name: "name", lock: "", unlock: "", + today: "today", }, misc: { or: "or", diff --git a/src/i18n/fr-ca/index.ts b/src/i18n/fr-ca/index.ts index 2509717..3be3cef 100644 --- a/src/i18n/fr-ca/index.ts +++ b/src/i18n/fr-ca/index.ts @@ -250,6 +250,7 @@ export default { name: "nom", lock: "verrouiller", unlock: "déverrouiller", + today: "aujourd'hui", }, misc: { or: "ou", diff --git a/src/layouts/main-layout.vue b/src/layouts/main-layout.vue index 704a258..0385b09 100644 --- a/src/layouts/main-layout.vue +++ b/src/layouts/main-layout.vue @@ -8,11 +8,12 @@ import ChatbotDrawer from 'src/modules/chatbot/components/chatbot-drawer.vue'; import { onMounted, watch, ref } from 'vue'; + import { setCssVar } from 'quasar'; import { RouterView } from 'vue-router'; import { useUiStore } from 'src/stores/ui-store'; import { useAuthStore } from 'src/stores/auth-store'; - + setCssVar('accent2', '#36c45a44'); const ui_store = useUiStore(); const auth_store = useAuthStore(); const userPreferences = ref(ui_store.userPreferences); @@ -47,3 +48,13 @@ + + \ No newline at end of file diff --git a/src/modules/chatbot/components/chatbot-drawer.vue b/src/modules/chatbot/components/chatbot-drawer.vue index a0b5c84..1b397a0 100644 --- a/src/modules/chatbot/components/chatbot-drawer.vue +++ b/src/modules/chatbot/components/chatbot-drawer.vue @@ -12,7 +12,7 @@ const chatbot_store = useChatbotStore(); const text = ref(''); - const is_showing_right_drawer = ref(true); + const isShowingRightDrawer = ref(true); const drawer_width = ref(85); const handleSend = async () => { @@ -28,7 +28,7 @@ - \ No newline at end of file diff --git a/src/modules/dashboard/components/employee/shortcut-card.vue b/src/modules/dashboard/components/employee/shortcut-card.vue index d71b696..4f3f7bd 100644 --- a/src/modules/dashboard/components/employee/shortcut-card.vue +++ b/src/modules/dashboard/components/employee/shortcut-card.vue @@ -4,7 +4,6 @@ > const { route = "" } = defineProps<{ iconImageSource: string, - bgImageSource: string, name: string, route?: string, }>(); @@ -16,36 +15,21 @@ @@ -54,11 +38,17 @@ scoped lang="css" > -.link-card { - background-blend-mode: multiply; - background-position: bottom right; - background-repeat: no-repeat; - background-color: var(--q-dark); - background-size: contain; +.link-btn { + box-shadow: 0 6px rgb(4, 77, 4); + transform: translateY(-6px); +} + +.link-btn:hover { + background-color: var(--q-accent2) !important; +} + +.link-btn:active { + box-shadow: 0 2px rgb(4, 77, 4); + transform: translateY(2px); } \ No newline at end of file diff --git a/src/modules/dashboard/components/main-carousel.vue b/src/modules/dashboard/components/main-carousel.vue index 8f3c5b0..5d8e9fc 100644 --- a/src/modules/dashboard/components/main-carousel.vue +++ b/src/modules/dashboard/components/main-carousel.vue @@ -28,28 +28,34 @@ :autoplay="autoplayTimer" control-color="accent" control-type="outline" - class="bg-dark fit rounded-15 shadow-18" + class="bg-dark rounded-15 fit shadow-18" @mouseenter="onCarouselMouseEvent('enter')" @mouseleave="onCarouselMouseEvent('exit')" > -
+
-
+
{{ $t('dashboard.carousel.welcome_title') }}
-
+
{{ $t('dashboard.carousel.welcome_message') }}
@@ -61,19 +67,25 @@ class="q-pa-none cursor-pointer" @click="$router.push(RouteNames.HELP)" > -
+
-
+
{{ $t('dashboard.carousel.help_title') }}
-
+
{{ $t('dashboard.carousel.help_message') }}
diff --git a/src/modules/timesheets/components/new-shift-list.vue b/src/modules/timesheets/components/mobile/shift-list-mobile.vue similarity index 90% rename from src/modules/timesheets/components/new-shift-list.vue rename to src/modules/timesheets/components/mobile/shift-list-mobile.vue index 4b87399..be8c29e 100644 --- a/src/modules/timesheets/components/new-shift-list.vue +++ b/src/modules/timesheets/components/mobile/shift-list-mobile.vue @@ -42,8 +42,6 @@ // ========== methods ======================================== - // const timesheetRows = computed(() => timesheetStore.timesheets); - const addNewShift = (day_shifts: Shift[], date: string, timesheet_id: number) => { uiStore.focusNextComponent = true; const newShift = new Shift; @@ -52,14 +50,6 @@ day_shifts.push(newShift); }; - const deleteUnsavedShift = (timesheet_index: number, day_index: number) => { - if (timesheetStore.timesheets !== undefined) { - const day = timesheetStore.timesheets[timesheet_index]!.days[day_index]!; - const shifts_without_deleted_shift = day.shifts.filter(shift => shift.id !== 0); - day.shifts = shifts_without_deleted_shift; - } - }; - const getDayApproval = (day: TimesheetDay) => { if (day.shifts.length < 1) return false; return day.shifts.every(shift => shift.is_approved === true); @@ -101,7 +91,7 @@ :class="$q.platform.is.mobile ? 'column no-wrap q-pb-lg' : 'row'" >
@@ -226,13 +213,11 @@ />
diff --git a/src/modules/timesheets/components/shift-list-date-widget.vue b/src/modules/timesheets/components/shift-list-date-widget.vue index 4ce59c2..f841d35 100644 --- a/src/modules/timesheets/components/shift-list-date-widget.vue +++ b/src/modules/timesheets/components/shift-list-date-widget.vue @@ -4,14 +4,15 @@ > import { computed } from 'vue'; import { date, useQuasar } from 'quasar'; - + const q = useQuasar(); const { extractDate } = date; - const { displayDate, dense = false, approved = false} = defineProps<{ + const { displayDate, dense = false, approved = false } = defineProps<{ displayDate: string; dense?: boolean; approved?: boolean; + today?: boolean; }>(); const date_font_size = computed(() => dense ? '1.5em' : '2.5em'); @@ -26,21 +27,31 @@ class="column flex-center rounded-10 text-center self-center bg-transparent" :style="date_box_size" > + + {{ $t('shared.label.today') }} + + - {{ $d(display_date, { weekday: $q.platform.is.mobile ? 'short' : 'long'}) }} + {{ $d(display_date, { weekday: $q.platform.is.mobile ? 'short' : 'long' }) }} + {{ display_date.getDate() }} +
- \ No newline at end of file + + + \ No newline at end of file diff --git a/src/modules/timesheets/components/shift-list-day.vue b/src/modules/timesheets/components/shift-list-day.vue index c1ecda1..9c8f891 100644 --- a/src/modules/timesheets/components/shift-list-day.vue +++ b/src/modules/timesheets/components/shift-list-day.vue @@ -3,127 +3,195 @@ lang="ts" > import ShiftListDayRow from 'src/modules/timesheets/components/shift-list-day-row.vue'; - import ShiftListDayRowMobile from 'src/modules/timesheets/components/mobile/shift-list-day-row-mobile.vue'; + import ShiftListDateWidget from 'src/modules/timesheets/components/shift-list-date-widget.vue'; - import { inject, ref } from 'vue'; + import { useI18n } from 'vue-i18n'; + import { computed, inject, ref } from 'vue'; + import { useUiStore } from 'src/stores/ui-store'; import { useTimesheetStore } from 'src/stores/timesheet-store'; import { useShiftApi } from 'src/modules/timesheets/composables/use-shift-api'; import { useTimesheetApi } from 'src/modules/timesheets/composables/use-timesheet-api'; import { isShiftOverlap } from 'src/modules/timesheets/utils/shift.util'; - import type { Shift } from 'src/modules/timesheets/models/shift.models'; + import { Shift } from 'src/modules/timesheets/models/shift.models'; import type { TimesheetDay } from 'src/modules/timesheets/models/timesheet.models'; - // ================== State ================== + // ========== Constants ======================================== - const { timesheetId, weekDayIndex, day, dense = false, approved = false, holiday = false } = defineProps<{ + const CURRENT_DATE_STRING = new Date().toISOString().slice(0, 10); + + // ========== State ======================================== + + const day = defineModel({ required: true }); + + const { timesheetId, weekDayIndex, timesheetApproved = false } = defineProps<{ timesheetId: number; weekDayIndex: number; - day: TimesheetDay; dense?: boolean; - approved?: boolean; - holiday?: boolean; + timesheetApproved?: boolean; }>(); - const emit = defineEmits<{ - 'deleteUnsavedShift': [void]; - }>(); - - const shift_api = useShiftApi(); - const timesheet_api = useTimesheetApi(); - const timesheet_store = useTimesheetStore(); - const preset_mouseover = ref(false); - const shift_error_message = ref(); + const { locale } = useI18n(); + const uiStore = useUiStore(); + const shiftApi = useShiftApi(); + const timesheetApi = useTimesheetApi(); + const timesheetStore = useTimesheetStore(); + const presetMouseover = ref(false); + const shiftErrorMessage = ref(); const employeeEmail = inject('employeeEmail'); + // ========== Computed ======================================== + + const isDayApproved = computed(() => day.value.shifts.length > 0 && day.value.shifts.every( + shift => shift.is_approved === true)); + + const isHoliday = computed(() => timesheetStore.federal_holidays.some( + holiday => holiday.date === day.value.date)); + + const isToday = computed(() => CURRENT_DATE_STRING === day.value.date); + // ================== Methods ================== - const deleteCurrentShift = async (shift: Shift) => { - if (shift.id <= 0) { - shift.id = 0; - emit('deleteUnsavedShift'); - } else { - await shift_api.deleteShiftById(shift.id, employeeEmail); - } + const addNewShift = () => { + uiStore.focusNextComponent = true; + const newShift = new Shift(day.value.date); + newShift.timesheet_id = timesheetId; + day.value.shifts.push(newShift); + }; - if (day.shifts.length < 2 && shift_error_message.value !== undefined) { + const deleteCurrentShift = async (shiftId: number, index: number) => { + if (shiftId <= 0) + day.value.shifts.splice(index, 1); + else + await shiftApi.deleteShiftById(shiftId, employeeEmail); + + if (day.value.shifts.length < 2 && shiftErrorMessage.value !== undefined) { onTimeFieldBlur(); } }; const onTimeFieldBlur = () => { - const is_error = isShiftOverlap(day.shifts); - day.shifts.map(shift => shift.has_error = is_error); + const is_error = isShiftOverlap(day.value.shifts); + day.value.shifts.map(shift => shift.has_error = is_error); if (is_error) - shift_error_message.value = 'timesheet.errors.SHIFT_OVERLAP_SHORT'; + shiftErrorMessage.value = 'timesheet.errors.SHIFT_OVERLAP_SHORT'; else - shift_error_message.value = undefined; + shiftErrorMessage.value = undefined; } const onClickApplyDailyPreset = async () => { - await timesheet_api.applyPreset(timesheetId, weekDayIndex, day.date, employeeEmail); + await timesheetApi.applyPreset(timesheetId, weekDayIndex, day.value.date, employeeEmail); } + + const getHolidayName = (date: string) => { + const holiday = timesheetStore.federal_holidays.find(holiday => holiday.date === date); + if (!holiday) return; + + if (locale.value === 'fr-FR') + return holiday.nameFr; + + else if (locale.value === 'en-CA') + return holiday.nameEn; + }; \ No newline at end of file diff --git a/src/modules/timesheets/components/shift-list-scrollable.vue b/src/modules/timesheets/components/shift-list-scrollable.vue index cc33003..82975aa 100644 --- a/src/modules/timesheets/components/shift-list-scrollable.vue +++ b/src/modules/timesheets/components/shift-list-scrollable.vue @@ -1,8 +1,9 @@