Skip to content

Commit

Permalink
Merge pull request #183 from mikepsinn/develop
Browse files Browse the repository at this point in the history
Measurement date range filter, User variable charts and settings page
  • Loading branch information
mikepsinn authored Apr 22, 2024
2 parents 0ac2e7a + 1070221 commit 3a16446
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 109 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { Metadata } from "next"
import { notFound, redirect } from "next/navigation"

import { getUserVariable } from "@/lib/api/userVariables"
import { authOptions } from "@/lib/auth"
import { getCurrentUser } from "@/lib/session"
import { UserVariableEditForm } from "@/components/userVariable/user-variable-edit-form"
import { Shell } from "@/components/layout/shell"
import { DashboardHeader } from "@/components/pages/dashboard/dashboard-header"
import { UserVariableCharts } from '@/components/userVariable/user-variable-charts';
Expand All @@ -14,7 +12,7 @@ export const metadata: Metadata = {
}

interface UserVariableEditProps {
params: { userVariableId: string }
params: { variableId: string }
}

export default async function UserVariableChart({ params }: UserVariableEditProps) {
Expand All @@ -24,7 +22,10 @@ export default async function UserVariableChart({ params }: UserVariableEditProp
redirect(authOptions?.pages?.signIn || "/signin")
}

const userVariable = await getUserVariable(params.userVariableId)
const response = await fetch(
`/api/dfda/userVariables?variableId=${params.variableId}&includeCharts=true`)
const userVariables = await response.json()
const userVariable = userVariables[0]

if (!userVariable) {
notFound()
Expand Down
8 changes: 6 additions & 2 deletions apps/nextjs/app/dashboard/userVariables/[variableId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ interface UserVariablePageProps {
// }

export default async function UserVariablePage({
params
params,
searchParams,
}: UserVariablePageProps) {
const user = await getCurrentUser()

Expand All @@ -41,7 +42,10 @@ export default async function UserVariablePage({

return (
<Shell>
<UserVariableOverview variableId={params.variableId} user={user} />
<UserVariableOverview variableId={params.variableId} user={user} measurementsDateRange={{
from: searchParams.from,
to: searchParams.to
}} />
</Shell>
)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Metadata } from "next"
import { notFound, redirect } from "next/navigation"

import { getUserVariable } from "@/lib/api/userVariables"
import { authOptions } from "@/lib/auth"
import { getCurrentUser } from "@/lib/session"
import { UserVariableEditForm } from "@/components/userVariable/user-variable-edit-form"
Expand All @@ -13,7 +12,7 @@ export const metadata: Metadata = {
}

interface UserVariableEditProps {
params: { userVariableId: string }
params: { variableId: string }
}

export default async function UserVariableEdit({ params }: UserVariableEditProps) {
Expand All @@ -23,7 +22,10 @@ export default async function UserVariableEdit({ params }: UserVariableEditProps
redirect(authOptions?.pages?.signIn || "/signin")
}

const userVariable = await getUserVariable(parseInt(params.userVariableId), true)
const response = await fetch(
`/api/dfda/userVariables?variableId=${params.variableId}&includeCharts=0`)
const userVariables = await response.json()
const userVariable = userVariables[0]

if (!userVariable) {
notFound()
Expand All @@ -40,8 +42,7 @@ export default async function UserVariableEdit({ params }: UserVariableEditProps
userVariable={{
id: userVariable.id,
name: userVariable.name,
description: userVariable.description,
colorCode: userVariable.colorCode,
description: userVariable.description
}}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,6 @@ import { Icons } from "@/components/icons"
import { MeasurementDeleteButton } from "./measurement-delete-button"
import { Measurement } from "@/app/types.ts";

export type MeasurementsType = {
id: string
date: Date
count: number
userVariable: {
id: string
name: string
}
}

export const measurementColumns: ColumnDef<Measurement>[] = [
{
accessorKey: "date",
Expand Down Expand Up @@ -73,21 +63,38 @@ export const measurementColumns: ColumnDef<Measurement>[] = [
},
},
{
accessorKey: "count",
accessorKey: "value",
header: ({ column }) => {
return (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
>
Count
Value
<Icons.sort className="ml-2 h-4 w-4" />
</Button>
)
},
cell: ({ row }) => {
const value = row.original.value
return <div className="px-4">{value} {row.original.unitAbbreviatedName}</div>
return <div className="px-4">{value}</div>
},
},
{
accessorKey: "unitAbbreviatedName",
header: ({ column }) => {
return (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
>
Unit
<Icons.sort className="ml-2 h-4 w-4" />
</Button>
)
},
cell: ({ row }) => {
return <div className="px-4">{row.original.unitAbbreviatedName}</div>
},
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,46 @@ type MeasurementsListProps = {
id: string;
};
variableId: number;
measurementsDateRange: {
from: string;
to: string;
};
};

export const MeasurementsList: FC<MeasurementsListProps> = ({ user, variableId }) => {
export const MeasurementsList: FC<MeasurementsListProps> = ({ user, variableId, measurementsDateRange }) => {

const [measurements, setMeasurements] = useState<Measurement[]>();
const [isLoading, setIsLoading] = useState(true); // Add a loading state

useEffect(() => {
setIsLoading(true); // Set loading to true when starting to fetch
const url = `/api/dfda/measurements?variableId=${variableId}`;
let url = `/api/dfda/measurements?variableId=${variableId}`;
if(measurementsDateRange.from) {
url += `&earliestMeasurementTime=${measurementsDateRange.from}`;
}
if(measurementsDateRange.to) {
url += `&latestMeasurementTime=${measurementsDateRange.to}`;
}

fetch(url)
.then(response => response.json())
.then(measurements => {
if(measurementsDateRange.from){
measurements = measurements.filter((measurement: Measurement) => {
const measurementTime = new Date(measurement.startAt);
const fromDate = new Date(measurementsDateRange.from);
return measurementTime >= fromDate;
});
}
if(measurementsDateRange.to){
measurements = measurements.filter((measurement: Measurement) => {
const measurementTime = new Date(measurement.startAt);
const toDate = new Date(measurementsDateRange.to);
return measurementTime <= toDate;
});
}
setMeasurements(measurements);

setIsLoading(false); // Set loading to false once data is fetched
})
.catch(error => {
Expand Down
85 changes: 9 additions & 76 deletions apps/nextjs/components/userVariable/user-variable-charts.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
"use client"

import * as React from "react"
import { useRouter } from "next/navigation"
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import * as z from "zod"
import HighchartsReact from 'highcharts-react-official';
import Highcharts from 'highcharts';

import { cn } from "@/lib/utils"
import { userVariablePatchSchema } from "@/lib/validations/userVariable"
import { buttonVariants } from "@/components/ui/button"
import {
Card,
CardContent,
Expand All @@ -23,60 +16,16 @@ import { toast } from "@/components/ui/use-toast"
import { Icons } from "@/components/icons"
import { UserVariable } from "@/types/models/UserVariable";

interface UserVariableEditFormProps extends React.HTMLAttributes<HTMLFormElement> {
userVariable: Pick<UserVariable, "id" | "name" | "description">
interface UserVariableChartsProps extends React.HTMLAttributes<HTMLFormElement> {
userVariable: UserVariable
}

type FormData = z.infer<typeof userVariablePatchSchema>

export function UserVariableCharts({
userVariable,
className,
...props
}: UserVariableEditFormProps) {
const router = useRouter()
const {
handleSubmit,
register,
formState: { errors, isSubmitting },
} = useForm<FormData>({
resolver: zodResolver(userVariablePatchSchema),
defaultValues: {
name: userVariable?.name || "",
description: userVariable?.description || "",
colorCode: "",
},
})
const [color, setColor] = React.useState(userVariable.colorCode || "#ffffff")

async function onSubmit(data: FormData) {
const response = await fetch(`/api/userVariables/${userVariable.id}`, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
name: data.name,
description: data.description,
colorCode: color,
}),
})

if (!response?.ok) {
return toast({
title: "Something went wrong.",
description: "Your userVariable was not updated. Please try again.",
variant: "destructive",
})
}
}: UserVariableChartsProps) {

toast({
description: "Your userVariable has been updated.",
})

router.back()
router.refresh()
}

return (

Expand All @@ -88,31 +37,15 @@ export function UserVariableCharts({
)}
</CardHeader>
<CardContent className="space-y-4">
{userVariable.charts.map((qmChart: { highchartConfig: any }, key: React.Key | null | undefined) =>
qmChart && qmChart.highchartConfig ? (
<div key={key} className="card transparent-bg highcharts-container">
<HighchartsReact
highcharts={Highcharts}
options={qmChart.highchartConfig}
/>
</div>
) : null
)}

<div className="card transparent-bg highcharts-container">
<HighchartsReact
highcharts={Highcharts}
options={userVariable.charts?.lineChartWithoutSmoothing?.highchartConfig}
/>
</div>
</CardContent>
<CardFooter>
<button
type="submit"
className={cn(buttonVariants(), className)}
disabled={isSubmitting}
>
{isSubmitting && (
<Icons.spinner className="mr-2 h-4 w-4 animate-spin" />
)}
<span>Save changes</span>
</button>
</CardFooter>
</Card>
</form>
)
}
16 changes: 9 additions & 7 deletions apps/nextjs/components/userVariable/user-variable-overview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@ type UserVariableOverviewProps = {
id: string;
};
variableId: number;
measurementsDateRange: {
from: string;
to: string;
};
};

export const UserVariableOverview: FC<UserVariableOverviewProps> = ({ user, variableId }) => {
export const UserVariableOverview: FC<UserVariableOverviewProps> = ({ user, variableId, measurementsDateRange }) => {

const [userVariable, setUserVariable] = useState<UserVariable>();
const [isLoading, setIsLoading] = useState(true); // Add a loading state
Expand Down Expand Up @@ -46,12 +50,10 @@ export const UserVariableOverview: FC<UserVariableOverviewProps> = ({ user, vari
return <div>No data found.</div>; // Handle the case where userVariable is undefined
}



return (

<><DashboardHeader
heading={`${userVariable.name} Stats`}
<>
<DashboardHeader
heading={`${userVariable.name} Measurements`}
text={userVariable.description}
>
<div className="flex flex-col items-stretch gap-2 md:items-end">
Expand All @@ -68,7 +70,7 @@ export const UserVariableOverview: FC<UserVariableOverviewProps> = ({ user, vari
</UserVariableOperationsButton>
</div>
</DashboardHeader>
<MeasurementsList user={user} variableId={variableId}></MeasurementsList>
<MeasurementsList user={user} variableId={variableId} measurementsDateRange={measurementsDateRange}></MeasurementsList>
</>
)
}

0 comments on commit 3a16446

Please sign in to comment.