add responsiveness for the dashboard and menu

This commit is contained in:
Gregor Vostrak
2024-04-13 02:12:57 +02:00
parent 528865fc1c
commit 335a057ba1
12 changed files with 80 additions and 46 deletions

View File

@@ -4,6 +4,7 @@
:root{ :root{
--theme-color-default-background: #040618;
--theme-color-icon-default: #42466C; --theme-color-icon-default: #42466C;
--theme-color-card-background: #13152B; --theme-color-card-background: #13152B;
--theme-color-card-background-active: #1C1E34; --theme-color-card-background-active: #1C1E34;
@@ -29,6 +30,11 @@
display: none; display: none;
} }
body{
background-color: var(--theme-color-default-background);
}
@font-face { @font-face {
font-family: 'Outfit'; font-family: 'Outfit';
src: url('/fonts/Outfit-VariableFont_wght.ttf'); src: url('/fonts/Outfit-VariableFont_wght.ttf');

View File

@@ -20,7 +20,7 @@ const props = withDefaults(
const badgeClasses = { const badgeClasses = {
base: 'py-1 px-2 space-x-1.5 text-xs', base: 'py-1 px-2 space-x-1.5 text-xs',
large: 'py-1.5 px-3 space-x-2 text-sm text-muted', large: 'py-1 sm:py-1.5 px-2 sm:px-3 space-x-1.5 sm:space-x-2 text-xs sm:text-sm text-muted',
}; };
const borderClasses = computed(() => { const borderClasses = computed(() => {

View File

@@ -21,11 +21,11 @@ const iconColorClasses = computed(() => {
:class=" :class="
twMerge( twMerge(
iconColorClasses, iconColorClasses,
'flex-shrink-0 ring-0 focus:outline-none focus:ring-0 transition focus:bg-card-background-separator hover:bg-card-background-separator rounded-full w-11 h-11 flex items-center justify-center' 'flex-shrink-0 ring-0 focus:outline-none focus:ring-0 transition focus:bg-card-background-separator hover:bg-card-background-separator rounded-full w-7 sm:w-11 h-7 sm:h-11 flex items-center justify-center'
) )
"> ">
<svg <svg
class="h-7" class="w-5 sm:w-7 h-5 sm:h-7"
viewBox="0 0 8 14" viewBox="0 0 8 14"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg"> xmlns="http://www.w3.org/2000/svg">

View File

@@ -21,7 +21,7 @@ const props = withDefaults(
const indicatorClasses = { const indicatorClasses = {
base: 'w-2.5 h-2.5', base: 'w-2.5 h-2.5',
large: 'w-3 h-3', large: 'w-2 sm:w-3 h-2 sm:h-3',
}; };
</script> </script>

View File

@@ -25,10 +25,10 @@ const iconColorClasses = computed(() => {
:class=" :class="
twMerge( twMerge(
iconColorClasses, iconColorClasses,
'flex-shrink-0 ring-0 focus:outline-none focus:ring-0 transition focus:bg-card-background-separator hover:bg-card-background-separator rounded-full w-11 h-11 flex items-center justify-center' 'flex-shrink-0 ring-0 focus:outline-none focus:ring-0 transition focus:bg-card-background-separator hover:bg-card-background-separator rounded-full w-7 sm:w-11 h-7 sm:h-11 flex items-center justify-center'
) )
"> ">
<TagIcon class="w-7 h-7"></TagIcon> <TagIcon class="w-5 sm:w-7 h-5 sm:h-7"></TagIcon>
<span <span
v-if="model.length > 1" v-if="model.length > 1"
class="font-extrabold absolute rounded-full text-xs w-3 h-3 block top-[15px] rotate-[45deg] right-[14px] text-card-background"> class="font-extrabold absolute rounded-full text-xs w-3 h-3 block top-[15px] rotate-[45deg] right-[14px] text-card-background">

View File

@@ -16,11 +16,11 @@ const props = withDefaults(
); );
const buttonSizeClasses = { const buttonSizeClasses = {
base: 'w-8 h-8 bg-accent-200/40 hover:scale-110 hover:bg-accent-300/70 ring-accent-200/10 focus:ring-accent-200/10 hover:ring-4', base: 'w-8 h-8 bg-accent-200/40 hover:scale-110 hover:bg-accent-300/70 ring-accent-200/10 focus:ring-accent-200/10 hover:ring-4',
large: 'w-11 h-11 ring-accent-200/10 focus:ring-accent-200/20 ring-8 hover:scale-110', large: 'w-8 sm:w-11 h-8 sm:h-11 ring-accent-200/10 focus:ring-accent-200/20 ring-4 sm:ring-8 hover:scale-110',
}; };
const iconClass = { const iconClass = {
base: 'w-3.5 h-3.5', base: 'w-3.5 h-3.5',
large: 'w-4 h-4', large: 'w-3.5 h-3.5 sm:w-4 sm:h-4',
}; };
const buttonColorClasses = computed(() => { const buttonColorClasses = computed(() => {

View File

@@ -10,13 +10,13 @@ import {
</script> </script>
<template> <template>
<div class="px-3.5 py-2 flex @container"> <div class="px-3.5 py-2 flex justify-between @container">
<div class="flex items-center"> <div class="flex items-center">
<p class="font-semibold text-sm text-white"> <p class="font-semibold text-sm text-white">
{{ formatHumanReadableDate(date) }} {{ formatHumanReadableDate(date) }}
</p> </p>
</div> </div>
<div class="items-center justify-center flex-1 flex"> <div class="items-center justify-center flex-1 hidden @2xs:flex">
<svg <svg
class="w-20 opacity-70 transition hover:opacity-100" class="w-20 opacity-70 transition hover:opacity-100"
viewBox="0 0 42 10" viewBox="0 0 42 10"

View File

@@ -130,8 +130,9 @@ const option = ref({
</script> </script>
<template> <template>
<div class="grid gap-x-6 xl:gap-x-6 grid-cols-4"> <div
<div class="col-span-3"> class="grid space-y-5 sm:space-y-0 sm:gap-x-6 xl:gap-x-6 grid-cols-1 lg:grid-cols-3 xl:grid-cols-4">
<div class="col-span-2 xl:col-span-3">
<CardTitle <CardTitle
title="This Week" title="This Week"
class="pb-8" class="pb-8"

View File

@@ -152,9 +152,9 @@ function onTimeEntryEnterPress() {
<template> <template>
<CardTitle title="Time Tracker" :icon="ClockIcon"></CardTitle> <CardTitle title="Time Tracker" :icon="ClockIcon"></CardTitle>
<div class="flex items-center" data-testid="dashboard_timer"> <div class="flex items-center relative" data-testid="dashboard_timer">
<div <div
class="flex w-full rounded-lg bg-card-background border-card-border border transition"> class="flex flex-col sm:flex-row w-full rounded-lg bg-card-background border-card-border border transition">
<div class="flex-1 flex items-center pr-6"> <div class="flex-1 flex items-center pr-6">
<input <input
placeholder="What are you working on?" placeholder="What are you working on?"
@@ -162,36 +162,40 @@ function onTimeEntryEnterPress() {
v-model="currentTimeEntry.description" v-model="currentTimeEntry.description"
@keydown.enter="startTimerIfNotActive" @keydown.enter="startTimerIfNotActive"
@blur="updateTimeEntry" @blur="updateTimeEntry"
class="w-full rounded-l-lg py-3 px-5 text-lg text-white focus:bg-card-background-active font-medium bg-transparent border-none placeholder-muted focus:ring-0 transition" class="w-full rounded-l-lg py-2.5 px-3 border-b border-b-card-background-separator sm:px-4 text-sm sm:text-lg text-white focus:bg-card-background-active font-medium bg-transparent border-none placeholder-muted focus:ring-0 transition"
type="text" /> type="text" />
</div> </div>
<div class="flex items-center"> <div class="flex items-center justify-between pl-2">
<TimeTrackerProjectTaskDropdown <div class="flex items-center w-[130px]">
@changed="updateTimeEntry" <TimeTrackerProjectTaskDropdown
v-model:project="currentTimeEntry.project_id" @changed="updateTimeEntry"
v-model:task=" v-model:project="currentTimeEntry.project_id"
currentTimeEntry.task_id v-model:task="
"></TimeTrackerProjectTaskDropdown> currentTimeEntry.task_id
</div> "></TimeTrackerProjectTaskDropdown>
<div class="flex items-center space-x-2 px-4"> </div>
<TimeTrackerTagDropdown <div class="flex items-center space-x-2 px-4">
@changed="updateTimeEntry" <TimeTrackerTagDropdown
v-model="currentTimeEntry.tags"></TimeTrackerTagDropdown> @changed="updateTimeEntry"
<BillableToggleButton></BillableToggleButton> v-model="
</div> currentTimeEntry.tags
<div class="border-l border-card-border"> "></TimeTrackerTagDropdown>
<input <BillableToggleButton></BillableToggleButton>
placeholder="00:00:00" </div>
@focus="pauseLiveTimerUpdate" <div class="border-l border-card-border">
data-testid="time_entry_time" <input
@blur="updateTimerAndStartLiveTimerUpdate" placeholder="00:00:00"
@keydown.enter="onTimeEntryEnterPress" @focus="pauseLiveTimerUpdate"
v-model="currentTime" data-testid="time_entry_time"
class="w-40 h-full text-white py-4 rounded-r-lg text-center px-4 text-lg font-bold bg-card-background border-none placeholder-muted focus:ring-0 transition focus:bg-card-background-active" @blur="updateTimerAndStartLiveTimerUpdate"
type="text" /> @keydown.enter="onTimeEntryEnterPress"
v-model="currentTime"
class="w-[110px] sm:w-[130px] h-full text-white py-2.5 rounded-r-lg text-center px-4 text-lg font-bold bg-card-background border-none placeholder-muted focus:ring-0 transition focus:bg-card-background-active"
type="text" />
</div>
</div> </div>
</div> </div>
<div class="pl-6 pr-3"> <div class="pl-6 pr-3 absolute sm:relative top-[7px] right-0">
<TimeTrackerStartStop <TimeTrackerStartStop
:active="isActive" :active="isActive"
@changed="onToggleButtonPress" @changed="onToggleButtonPress"

View File

@@ -12,11 +12,13 @@ import {
TagIcon, TagIcon,
UserCircleIcon, UserCircleIcon,
UserGroupIcon, UserGroupIcon,
Bars3Icon,
XMarkIcon,
} from '@heroicons/vue/20/solid'; } from '@heroicons/vue/20/solid';
import NavigationSidebarItem from '@/Components/NavigationSidebarItem.vue'; import NavigationSidebarItem from '@/Components/NavigationSidebarItem.vue';
import UserSettingsIcon from '@/Components/UserSettingsIcon.vue'; import UserSettingsIcon from '@/Components/UserSettingsIcon.vue';
import MainContainer from '@/Pages/MainContainer.vue'; import MainContainer from '@/Pages/MainContainer.vue';
import { onMounted } from 'vue'; import { onMounted, ref } from 'vue';
import { useProjectsStore } from '@/utils/useProjects'; import { useProjectsStore } from '@/utils/useProjects';
import { useTagsStore } from '@/utils/useTags'; import { useTagsStore } from '@/utils/useTags';
import { useTasksStore } from '@/utils/useTasks'; import { useTasksStore } from '@/utils/useTasks';
@@ -29,6 +31,8 @@ defineProps({
title: String, title: String,
}); });
const showSidebarMenu = ref(false);
onMounted(async () => { onMounted(async () => {
useProjectsStore().fetchProjects(); useProjectsStore().fetchProjects();
useTasksStore().fetchTasks(); useTasksStore().fetchTasks();
@@ -44,10 +48,17 @@ onMounted(async () => {
v-bind="$attrs" v-bind="$attrs"
class="flex flex-wrap bg-default-background text-muted"> class="flex flex-wrap bg-default-background text-muted">
<div <div
class="flex-shrink-0 h-screen fixed w-[230px] 2xl:w-[270px] px-2.5 2xl:px-4 py-4 flex flex-col justify-between"> :class="{
'!flex bg-default-background w-full z-50': showSidebarMenu,
}"
class="flex-shrink-0 h-screen hidden fixed w-[230px] 2xl:w-[270px] px-2.5 2xl:px-4 py-4 sm:flex flex-col justify-between">
<div> <div>
<div class="border-b border-default-background-separator pb-2"> <div
class="border-b border-default-background-separator pb-2 flex justify-between">
<OrganizationSwitcher></OrganizationSwitcher> <OrganizationSwitcher></OrganizationSwitcher>
<XMarkIcon
@click="showSidebarMenu = false"
class="w-8"></XMarkIcon>
</div> </div>
<div class="border-b border-default-background-separator"> <div class="border-b border-default-background-separator">
<CurrentSidebarTimer></CurrentSidebarTimer> <CurrentSidebarTimer></CurrentSidebarTimer>
@@ -115,7 +126,15 @@ onMounted(async () => {
<UserSettingsIcon></UserSettingsIcon> <UserSettingsIcon></UserSettingsIcon>
</ul> </ul>
</div> </div>
<div class="flex-1 ml-[230px] 2xl:ml-[270px]"> <div class="flex-1 sm:ml-[230px] 2xl:ml-[270px]">
<div
class="sm:hidden w-full px-3 py-3 border-b border-b-default-background-separator text-muted flex justify-between items-center">
<Bars3Icon
@click="showSidebarMenu = !showSidebarMenu"
class="w-8 text-muted"></Bars3Icon>
<OrganizationSwitcher></OrganizationSwitcher>
</div>
<Head :title="title" /> <Head :title="title" />
<Banner /> <Banner />

View File

@@ -54,7 +54,7 @@ const props = defineProps<{
<TimeTracker></TimeTracker> <TimeTracker></TimeTracker>
</MainContainer> </MainContainer>
<MainContainer <MainContainer
class="grid gap-x-6 grid-cols-2 xl:grid-cols-4 pt-5 pb-6 border-b border-default-background-separator items-stretch"> class="grid gap-6 grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 pt-5 pb-6 border-b border-default-background-separator items-stretch">
<RecentlyTrackedTasksCard <RecentlyTrackedTasksCard
:latestTasks="props.latestTasks"></RecentlyTrackedTasksCard> :latestTasks="props.latestTasks"></RecentlyTrackedTasksCard>
<LastSevenDaysCard <LastSevenDaysCard
@@ -64,6 +64,7 @@ const props = defineProps<{
props.dailyTrackedHours props.dailyTrackedHours
"></ActivityGraphCard> "></ActivityGraphCard>
<TeamActivityCard <TeamActivityCard
class="flex lg:hidden xl:flex"
:latestTeamActivity=" :latestTeamActivity="
props.latestTeamActivity props.latestTeamActivity
"></TeamActivityCard> "></TeamActivityCard>

View File

@@ -14,12 +14,15 @@ export default {
theme: { theme: {
extend: { extend: {
containers: {
'2xs': '16rem',
},
fontFamily: { fontFamily: {
sans: ['Outfit', ...defaultTheme.fontFamily.sans], sans: ['Outfit', ...defaultTheme.fontFamily.sans],
}, },
colors: { colors: {
'white': '#D9DCFB', 'white': '#D9DCFB',
'default-background': '#040618', 'default-background': 'var(--theme-color-default-background)',
'default-background-separator': '#13152B', 'default-background-separator': '#13152B',
'card-background': 'var(--theme-color-card-background)', 'card-background': 'var(--theme-color-card-background)',
'card-background-active': 'card-background-active':