Skip to content

Commit

Permalink
Merge pull request #26 from ferviddigital/feature-ui
Browse files Browse the repository at this point in the history
Nav, Measurements
  • Loading branch information
roymckenzie committed Oct 13, 2023
2 parents b17c637 + d6adfb7 commit f2cee62
Show file tree
Hide file tree
Showing 10 changed files with 83 additions and 70 deletions.
12 changes: 2 additions & 10 deletions src/components/Layout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ window.addEventListener('scroll', () => {
<div v-if="record">
<div class="dash-layout grid grid-rows-[auto_min-content] sm:grid-rows-none sm:grid-flow-col sm:grid-cols-[min-content_auto] sm:min-h-0">
<header
class="main-header fixed sm:sticky grid grid-flow-col sm:grid-rows-[min-content_auto_min-content] gap-2 sm:gap-4 overflow-scroll sm:overflow-visible sm:min-h-[calc(100vh-2rem)] items-center sm:items-start sm:justify-normal order-last sm:order-none self-end sm:self-start p-4 py-2 sm:py-6 bottom-4 md:bottom-auto mb-4 sm:mb-auto mr-4 sm:mr-0 ml-4 mt-4 sm:top-4 right-0 left-0 rounded-3xl bg-gray-900 text-white z-20">
class="main-header fixed sm:sticky grid grid-flow-col grid-cols-[min-content_min-content_auto] sm:grid-cols-none sm:grid-rows-[min-content_auto_min-content] gap-2 sm:gap-4 overflow-scroll sm:overflow-visible sm:min-h-[calc(100vh-2rem)] items-center sm:items-start sm:justify-normal order-last sm:order-none self-end sm:self-start p-4 py-2 sm:py-6 bottom-0 md:bottom-auto mb-4 sm:mb-auto mr-4 sm:mr-0 ml-4 mt-4 sm:top-4 right-0 left-0 rounded-3xl bg-gray-900 text-white z-20">
<h2 class="app-title grid grid-flow-col items-center sm:block self-start font-bold text-xl lg:mb-3 transition-all">
<RouterLink
class="grid grid-flow-col items-center sm:justify-start gap-1 sm:gap-4 p-2 sm:p-0 sm:px-3"
Expand All @@ -26,7 +26,7 @@ window.addEventListener('scroll', () => {
<SquaresPlusIcon class="h-6 w-6"/> <span class="hidden lg:inline">HealthRecord</span>
</RouterLink>
</h2>
<nav class="main-nav">
<nav class="main-nav justify-self-start">
<ul v-if="selectedPersonId" class="grid gap-2 sm:gap-4 grid-flow-col sm:grid-flow-row">
<li>
<RouterLink
Expand All @@ -44,14 +44,6 @@ window.addEventListener('scroll', () => {
<HeartIcon class="h-6 w-6" /> <span>Vitals</span>
</RouterLink>
</li>
<li>
<RouterLink
:to="{ name: 'PersonMeasurements', params: { personId: selectedPersonId } }"
aria-label="Measurements"
>
<ChartBarIcon class="h-6 w-6" /> <span>Measurements</span>
</RouterLink>
</li>
</ul>
</nav>
<nav class="main-nav place-self-end sm:place-self-auto">
Expand Down
10 changes: 8 additions & 2 deletions src/components/Measurements/Create.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@ import { Dialog, DialogPanel, DialogTitle } from '@headlessui/vue';
import { useRoute, useRouter } from 'vue-router';
import { store as measurementStore } from '../../store/measurements';
import MeasurementForm from './Form.vue';
import { vitals } from '../../store/vitals';
import { computed } from 'vue';
const router = useRouter();
const route = useRoute();
const vital = computed(() => {
return vitals.value.find(vital => vital.id === route.params.vitalId);
});
/**
* Create Measurement
*
Expand All @@ -23,8 +29,8 @@ const createMeasurement = (measurement) => {
<div class="fixed inset-0 bg-black/30 backdrop-blur-sm" />
<div class="fixed flex w-screen h-screen top-0 items-start justify-center overflow-y-auto">
<DialogPanel class="bg-white w-full max-w-xs rounded-2xl shadow-lg my-10">
<DialogTitle as="h3" class="text-lg font-semibold border-b p-6 py-3">Add Measurement</DialogTitle>
<MeasurementForm @submit="createMeasurement" class="p-6" />
<DialogTitle as="h3" class="text-lg font-semibold border-b p-6 py-3">Add {{ vital?.name }} Measurement</DialogTitle>
<MeasurementForm @submit="createMeasurement" class="p-6" :person-id="String(route.params.personId)" :vital-id="String(route.params.vitalId)" />
</DialogPanel>
</div>
</Dialog>
Expand Down
53 changes: 33 additions & 20 deletions src/components/Measurements/Form.vue
Original file line number Diff line number Diff line change
@@ -1,25 +1,45 @@
<script setup>
import { computed, ref } from 'vue';
import { people } from '../../store/people';
import { computed, nextTick, onMounted, ref, watch } from 'vue';
import { vitals } from '../../store/vitals';
import dayjs from 'dayjs';
import { useRoute } from 'vue-router';
const route = useRoute();
const router = useRoute();
const props = defineProps(['value', 'date', 'personId', 'vitalId', 'deletable']);
const props = defineProps({
value: {
type: Number,
default: null
},
date: {
type: Number,
default: Date.now()
},
personId: {
type: String,
required: true
},
vitalId: {
type: String,
default: ''
},
deletable: {
type: Boolean,
default: false
}
});
const emit = defineEmits(['submit', 'delete']);
const value = ref(props.value || '');
const date = ref(dayjs(props.date).format('YYYY-MM-DDThh:mm') || '');
const personId = ref(props.personId || route.params.personId || '');
const vitalId = ref(props.vitalId || route.params.vitalId || '');
const vitalId = ref(props.vitalId);
const valueInput = ref();
const vitalSelect = ref();
const isFormComplete = computed(() => {
return value.value
&& date.value.length > 0
&& personId.value.length > 0
&& vitalId.value.length > 0
});
const measurement = computed(() => {
Expand All @@ -28,7 +48,7 @@ const measurement = computed(() => {
id: crypto.randomUUID(),
value: Number(value.value),
date: dayjs(date.value).valueOf(),
personId: personId.value,
personId: props.personId,
vitalId: vitalId.value,
}
return measurement;
Expand All @@ -41,33 +61,26 @@ const vital = computed(() => {

<template>
<form @submit.prevent="emit('submit', measurement)">
<label for="personId">
Person
</label>
<select v-model="personId" id="personId" required>
<option value="" disabled hidden>Choose person</option>
<option v-for="person in people" :key="person.id" :value="person.id">{{ person.firstName + ' ' + person.lastName }}</option>
</select>
<label for="vitalId">
<label v-if="!$route.params.vitalId" for="vitalId">
Vital
</label>
<select v-model="vitalId" id="vitalId" required>
<select v-if="!$route.params.vitalId" ref="vitalSelect" v-model="vitalId" id="vitalId" required>
<option value="" disabled hidden>Choose vital</option>
<option v-for="vital in vitals" :key="vital.id" :value="vital.id">{{ vital.name }}</option>
</select>
<label for="value">
Value
</label>
<div class="input-group mb-3">
<input v-model="value" type="text" id="value" inputmode="decimal" autocomplete="off">
<input v-model="value" type="text" id="value" ref="valueInput" inputmode="decimal" autocomplete="off" tabindex="2">
<span v-if="vital">{{ vital.unit }}</span>
</div>
<label for="date">
Date
</label>
<input v-model="date" type="datetime-local" id="date" required>
<div class="grid grid-flow-col justify-end items-center gap-5 mt-4">
<a v-if="deletable" @click="emit('delete')" class="text-sm text-red-500 font-light cursor-pointer">Delete</a>
<a v-if="deletable" @click="emit('delete', measurement.id)" class="text-sm text-red-500 font-light cursor-pointer">Delete</a>
<a @click="$router.back()" class="text-sm text-gray-500 font-light cursor-pointer">Cancel</a>
<button type="submit" class="btn" :disabled="!isFormComplete">Save</button>
</div>
Expand Down
24 changes: 17 additions & 7 deletions src/components/Measurements/Update.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Dialog, DialogPanel, DialogTitle } from '@headlessui/vue';
import { computed, ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { measurements, store as measurementStore } from '../../store/measurements';
import { vitals } from '../../store/vitals';
import MeasurementForm from './Form.vue';
const route = useRoute();
Expand All @@ -18,8 +19,10 @@ const measurement = computed(() => {
const value = ref(measurement.value.value);
const date = ref(measurement.value.date);
const personId = ref(measurement.value.personId);
const vitalId = ref(measurement.value.vitalId);
const vital = computed(() => {
return vitals.value.find(vital => vital.id === measurement.value.vitalId);
});
/**
* Update Measurement
Expand All @@ -31,19 +34,26 @@ const updateMeasurement = (updatedMeasurement) => {
measurementStore.update(measurement.value.id, updatedMeasurement);
}
const deleteMeasurement = () => {
/**
* Delete Measurement
*
* @param {string} measurementId Measurement ID
*/
const deleteMeasurement = (measurementId) => {
router.back();
measurementStore.delete(measurement.value.id);
setTimeout(()=> {
measurementStore.delete(measurementId);
}, 100);
}
</script>

<template>
<Dialog :open="true" @close="$router.back()" :initialFocus="null" class="relative z-50">
<Dialog :open="true" @close="$router.back()" class="relative z-50">
<div class="fixed inset-0 bg-black/30 backdrop-blur-sm" />
<div class="fixed flex w-screen h-screen top-0 items-start justify-center overflow-y-auto">
<DialogPanel class="bg-white w-full max-w-xs rounded-2xl shadow-lg my-10">
<DialogTitle as="h3" class="text-lg font-semibold border-b p-6 py-3">Edit Measurement</DialogTitle>
<MeasurementForm class="p-6" @submit="updateMeasurement" @delete="deleteMeasurement" :value="value" :date="date" :personId="personId" :vitalId="vitalId" :deletable="true" />
<DialogTitle as="h3" class="text-lg font-semibold border-b p-6 py-3">Edit {{ vital.name }} Measurement</DialogTitle>
<MeasurementForm class="p-6" @submit="updateMeasurement" @delete="deleteMeasurement" :value="value" :date="date" :personId="measurement.personId" :vitalId="measurement.vitalId" :deletable="true" />
</DialogPanel>
</div>
</Dialog>
Expand Down
15 changes: 2 additions & 13 deletions src/components/Person/Person.vue
Original file line number Diff line number Diff line change
Expand Up @@ -89,21 +89,10 @@ const vitalMeasurements = (vitalId) => {
@click="$router.push({ name: 'PersonVital', params: { vitalId: vital.id } })"
>
<header class="grid grid-cols-[auto_min-content] p-3 pb-0">
<h3 class="font-semibold mb-1">{{ vital.name }}</h3>
<h3 class="font-semibold">{{ vital.name }}</h3>
<ChevronRightIcon class="h-5 w-5 self-start text-gray-400 group-hover:text-black transition-all" />
</header>
<VitalChart class="cursor-pointer scale-105 origin-bottom -mb-1" :vital="vital" :measurements="vitalMeasurements(vital.id)" :small="true"/>
</div>
</div>
<div class="pt-9 grid gap-3">
<h3 class="grid grid-flow-col text-xl font-bold mb-1 cursor-pointer" @click="$router.push({ name: 'PersonMeasurements' })">
Measurements
<span class="font-normal text-base text-indigo-500 justify-self-end whitespace-nowrap">
View all {{ personMeasurements.length }} <ChevronRightIcon class="w-6 h-6 inline align-top" />
</span>
</h3>
<div class="grid grid-cols-2 grid-rows-2 gap-3">
<MeasurementListItem v-for="measurement in personMeasurements.slice(0,4)" :key="measurement.id" :measurement="measurement" />
<VitalChart class="cursor-pointer" :vital="vital" :measurements="vitalMeasurements(vital.id)" :small="true"/>
</div>
</div>
</div>
Expand Down
6 changes: 4 additions & 2 deletions src/components/Person/Vital.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const vitalId = route.params.vitalId;
const personId = route.params.personId;
/** @type {import('vue').Ref<import('../../typedefs').VitalChartRange>} */
const vitalRange = ref('all');
const vitalRange = ref('year');
const person = computed(() => {
const person = people.value.find(person => person.id === personId);
Expand Down Expand Up @@ -137,7 +137,9 @@ const backRoute = computed(() => {
Measurements
<span class="text-xs font-normal text-gray-500 align-middle">({{ vitalMeasurements.length }})</span>
</h3>
<MeasurementListItem v-for="measurement in vitalMeasurements" :key="measurement.id" :measurement="measurement" />
<div class="grid gap-3 grid-cols-2 sm:grid-cols-3">
<MeasurementListItem v-for="measurement in vitalMeasurements" :key="measurement.id" :measurement="measurement" />
</div>
</div>
</div>
<RouterView name="modal" />
Expand Down
12 changes: 8 additions & 4 deletions src/components/Person/VitalChart.vue
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,9 @@ const data = computed(() => {
const options = {
layout: {
padding: {
left: props.small ? -9 : 0,
bottom: props.small ? -9 : 0
top: 2,
right: -1,
bottom: -2
}
},
onHover: (event, elements, chart) => {
Expand Down Expand Up @@ -143,6 +144,7 @@ const options = {
type: 'time',
time: {
unit: 'day',
round: 'day',
tooltipFormat: 'MM/DD/YYYY'
},
bounds: 'ticks',
Expand All @@ -152,23 +154,25 @@ const options = {
grid: {
display: false,
color: '#efefef',
tickLength: props.small ? 0 : 10
},
ticks: {
display: false,
autoSkipPadding: 30,
autoSkipPadding: 50,
color: '#aaa',
},
},
y: {
grid: {
display: false,
tickLength: props.small ? 0 : 10
},
border: {
display: false //props.small ? false : true
},
ticks: {
color: '#aaa',
autoSkipPadding: 30,
autoSkipPadding: 55,
major: {
enabled: true
},
Expand Down
6 changes: 3 additions & 3 deletions src/components/Person/Vitals.vue
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ const vitalMeasurements = (vitalId) => {
class="group bg-gray-50 rounded-xl cursor-pointer shadow-sm hover:shadow-md hover:bg-white transition-all overflow-hidden"
@click="$router.push({ name: 'PersonVital', params: { vitalId: vital.id } })"
>
<header class="grid grid-cols-[auto_min-content] p-3">
<h3 class="font-semibold mb-1">{{ vital.name }}</h3>
<header class="grid grid-cols-[auto_min-content] p-3 pb-0">
<h3 class="font-semibold">{{ vital.name }}</h3>
<ChevronRightIcon class="h-5 w-5 self-start text-gray-400 group-hover:text-black transition-all" />
</header>
<VitalChart class="cursor-pointer scale-105 origin-bottom -mb-1" :vital="vital" :measurements="vitalMeasurements(vital.id)" :small="true"/>
<VitalChart class="cursor-pointer" :vital="vital" :measurements="vitalMeasurements(vital.id)" :small="true"/>
</div>
</div>
</div>
Expand Down
9 changes: 0 additions & 9 deletions src/components/Settings/Settings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -121,15 +121,6 @@ const appVersion = APP_VERSION;
<ChevronRightIcon class="w-5 h-5 text-gray-300" />
</span>
</section>
<section class="grid grid-flow-col gap-4 items-center p-4 py-3 pr-3 cursor-pointer hover:bg-gray-100"
@click="$router.push({ name: 'SettingsMeasurements' })"
>
<h4>Measurements</h4>
<span class="grid grid-flow-col gap-1 justify-self-end items-center text-gray-400">
{{ measurements.length }}
<ChevronRightIcon class="w-5 h-5 text-gray-300" />
</span>
</section>
</div>
<h3 class="text-sm ml-4 mb-1 uppercase text-gray-500">
Record Details
Expand Down
6 changes: 6 additions & 0 deletions src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
@tailwind components;
@tailwind utilities;

@media (hover: none) and (display-mode: standalone) {
.main-header {
@apply bottom-[env(safe-area-inset-bottom)] md:bottom-auto mb-0;
}
}

body {
min-width: -webkit-fill-available;
}
Expand Down

0 comments on commit f2cee62

Please sign in to comment.