Some stuff
This commit is contained in:
parent
c04b781fab
commit
ef5ef8001f
38
package-lock.json
generated
38
package-lock.json
generated
@ -10,7 +10,9 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@heroicons/react": "^1.0.6",
|
"@heroicons/react": "^1.0.6",
|
||||||
"@tremor/react": "^3.12.0",
|
"@tremor/react": "^3.12.0",
|
||||||
|
"@types/ramda": "^0.29.9",
|
||||||
"next": "14.0.4",
|
"next": "14.0.4",
|
||||||
|
"ramda": "^0.29.1",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
"reaviz": "^15.2.1",
|
"reaviz": "^15.2.1",
|
||||||
@ -929,6 +931,14 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz",
|
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz",
|
||||||
"integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw=="
|
"integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/ramda": {
|
||||||
|
"version": "0.29.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.29.9.tgz",
|
||||||
|
"integrity": "sha512-X3yEG6tQCWBcUAql+RPC/O1Hm9BSU+MXu2wJnCETuAgUlrEDwTA1kIOdEEE4YXDtf0zfQLHa9CCE7WYp9kqPIQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"types-ramda": "^0.29.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/range-parser": {
|
"node_modules/@types/range-parser": {
|
||||||
"version": "1.2.7",
|
"version": "1.2.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
|
||||||
@ -2797,6 +2807,15 @@
|
|||||||
"ramda": "0.29.0"
|
"ramda": "0.29.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/file-system-cache/node_modules/ramda": {
|
||||||
|
"version": "0.29.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.29.0.tgz",
|
||||||
|
"integrity": "sha512-BBea6L67bYLtdbOqfp8f58fPMqEwx0doL+pAi8TZyp2YWz8R9G8z9x75CZI8W+ftqhFHCpEX2cRnUUXK130iKA==",
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/ramda"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fill-range": {
|
"node_modules/fill-range": {
|
||||||
"version": "7.0.1",
|
"version": "7.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||||
@ -4661,9 +4680,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/ramda": {
|
"node_modules/ramda": {
|
||||||
"version": "0.29.0",
|
"version": "0.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.29.0.tgz",
|
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.29.1.tgz",
|
||||||
"integrity": "sha512-BBea6L67bYLtdbOqfp8f58fPMqEwx0doL+pAi8TZyp2YWz8R9G8z9x75CZI8W+ftqhFHCpEX2cRnUUXK130iKA==",
|
"integrity": "sha512-OfxIeWzd4xdUNxlWhgFazxsA/nl3mS4/jGZI5n00uWOoSSFRhC1b6gl6xvmzUamgmqELraWp0J/qqVlXYPDPyA==",
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
"url": "https://opencollective.com/ramda"
|
"url": "https://opencollective.com/ramda"
|
||||||
@ -5798,6 +5817,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
|
"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
|
||||||
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="
|
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/ts-toolbelt": {
|
||||||
|
"version": "9.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz",
|
||||||
|
"integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w=="
|
||||||
|
},
|
||||||
"node_modules/tsconfig-paths": {
|
"node_modules/tsconfig-paths": {
|
||||||
"version": "3.15.0",
|
"version": "3.15.0",
|
||||||
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
|
||||||
@ -5900,6 +5924,14 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/types-ramda": {
|
||||||
|
"version": "0.29.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/types-ramda/-/types-ramda-0.29.6.tgz",
|
||||||
|
"integrity": "sha512-VJoOk1uYNh9ZguGd3eZvqkdhD4hTGtnjRBUx5Zc0U9ftmnCgiWcSj/lsahzKunbiwRje1MxxNkEy1UdcXRCpYw==",
|
||||||
|
"dependencies": {
|
||||||
|
"ts-toolbelt": "^9.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "5.3.3",
|
"version": "5.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
|
||||||
|
|||||||
@ -11,7 +11,9 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@heroicons/react": "^1.0.6",
|
"@heroicons/react": "^1.0.6",
|
||||||
"@tremor/react": "^3.12.0",
|
"@tremor/react": "^3.12.0",
|
||||||
|
"@types/ramda": "^0.29.9",
|
||||||
"next": "14.0.4",
|
"next": "14.0.4",
|
||||||
|
"ramda": "^0.29.1",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
"reaviz": "^15.2.1",
|
"reaviz": "^15.2.1",
|
||||||
|
|||||||
@ -3,20 +3,35 @@
|
|||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import {fetcher} from "@/app/utils";
|
import {fetcher} from "@/app/utils";
|
||||||
import {useEffect, useState} from "react";
|
import {useEffect, useState} from "react";
|
||||||
import {Card, Metric, Text, Title} from "@tremor/react";
|
import {Card, DonutChart, Metric, Text, Title} from "@tremor/react";
|
||||||
|
import * as R from "ramda";
|
||||||
|
|
||||||
export function ClientComponent({
|
export function SubjectOverviewCard({
|
||||||
projectId,
|
projectId,
|
||||||
title
|
title
|
||||||
}: {
|
}: {
|
||||||
projectId: number,
|
projectId: number,
|
||||||
title?: string
|
title?: string
|
||||||
}) {
|
}) {
|
||||||
|
const {
|
||||||
|
data: _project
|
||||||
|
} = useSWR<any>(`http://cosmos:8074/project?select=raw_json&toggl_id=eq.${projectId}`, fetcher);
|
||||||
|
const [project, setProject] = useState({
|
||||||
|
name: '',
|
||||||
|
color: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (_project) {
|
||||||
|
setProject(_project[0].raw_json);
|
||||||
|
}
|
||||||
|
}, [_project]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data,
|
data,
|
||||||
error,
|
error,
|
||||||
isLoading
|
isLoading,
|
||||||
} = useSWR<any[]>(`http://cosmos:8074/time_entry?select=*,project:project_id(name)&project_id=eq.${projectId}`, fetcher);
|
} = useSWR<any[]>(`http://cosmos:8074/time_entry?select=raw_json&project_id=eq.${projectId}&start=gt.2023-12-15T00:00:00.000Z`, fetcher);
|
||||||
const [a, setA] = useState(0)
|
const [a, setA] = useState(0)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -28,10 +43,52 @@ export function ClientComponent({
|
|||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card style={{ borderColor: project?.color }} decoration={'left'}>
|
||||||
<Title>{title ?? (isLoading ? 'Loading' : data?.[0]['project']['name'])}</Title>
|
<Title>{title ?? project?.name}</Title>
|
||||||
<Text>Total</Text>
|
<Text>Total</Text>
|
||||||
<Metric>{(a / (60 * 60)).toFixed(2)} hours</Metric>
|
<Metric>{(a / (60 * 60)).toFixed(2)} hours</Metric>
|
||||||
</Card>
|
</Card>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function SubjectComparisonCard({projectIds}: {
|
||||||
|
projectIds: number[]
|
||||||
|
}) {
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
error,
|
||||||
|
isLoading,
|
||||||
|
} = useSWR<any[]>(`http://cosmos:8074/time_entry?select=raw_json,project:project_id(name,raw_json)&project_id=in.(${projectIds.join(',')})`, fetcher, {});
|
||||||
|
|
||||||
|
const [a, setA] = useState<{ name: string, value: number }[]>([]);
|
||||||
|
const [colours, setColours] = useState<string[]>([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const a = R.toPairs(R.groupBy((entry) => entry.project.name, data ?? []))
|
||||||
|
.map(([name, entries]) => ({
|
||||||
|
name,
|
||||||
|
value: (entries ?? []).map((entry) => entry.raw_json.seconds).reduce((a, b) => a + b, 0),
|
||||||
|
colour: entries?.[0].project.raw_json.color
|
||||||
|
}))
|
||||||
|
|
||||||
|
setA(a);
|
||||||
|
|
||||||
|
setColours(a.map((entry) => entry.colour));
|
||||||
|
}, [data]);
|
||||||
|
|
||||||
|
const valueFormatter = (number: number) => `${(number / (60 * 60)).toFixed(2)} hours`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card className="col">
|
||||||
|
<Title>Relative Breakdown</Title>
|
||||||
|
<DonutChart
|
||||||
|
className="mt-6"
|
||||||
|
data={a ?? []}
|
||||||
|
category="value"
|
||||||
|
index="name"
|
||||||
|
valueFormatter={valueFormatter}
|
||||||
|
colors={colours}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@ -1,25 +1,38 @@
|
|||||||
import {ClientComponent} from "@/app/a.client";
|
import {SubjectComparisonCard, SubjectOverviewCard} from "@/app/a.client";
|
||||||
|
import {Title} from "@tremor/react";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
<main className="grid gap-5 m-6 grid-cols-4">
|
<main className="m-6">
|
||||||
<ClientComponent
|
<h1 className="text-3xl font-semibold font-black">Revision Tracker</h1>
|
||||||
projectId={195482340}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ClientComponent
|
<div className="grid gap-5 grid-cols-4">
|
||||||
title='Measure Theory'
|
<SubjectOverviewCard
|
||||||
projectId={195519024}
|
projectId={195482340}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ClientComponent
|
<SubjectOverviewCard
|
||||||
title='Quantum Mechanics'
|
title='Measure Theory'
|
||||||
projectId={195518593}
|
projectId={195519024}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ClientComponent
|
<SubjectOverviewCard
|
||||||
projectId={195754611}
|
title='Quantum Mechanics'
|
||||||
/>
|
projectId={195518593}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SubjectOverviewCard
|
||||||
|
projectId={195754611}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SubjectComparisonCard projectIds={[
|
||||||
|
195482340,
|
||||||
|
195519024,
|
||||||
|
195518593,
|
||||||
|
195754611,
|
||||||
|
]}/>
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user