Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(dashboard): allow configuring all time start from settings #234

Merged
merged 4 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
NEXTAUTH_SECRET=
NEXTAUTH_URL=http://localhost:3000
NEXT_PUBLIC_SITE_URL=http://localhost:3000
NEXT_PUBLIC_STATISTICS_START_DATE=2018-01-01
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ services:
- NEXTAUTH_SECRET= # (required) used to encrypt auth JWT token, generate one with `openssl rand -base64 32`
- NEXTAUTH_URL=http://localhost:8383 # (required) change to your domain if you are exposing the app to the internet
- NEXT_PUBLIC_SITE_URL=http://localhost:8383 # (required) change to your domain if you are exposing the app to the internet
- NEXT_PUBLIC_STATISTICS_START_DATE=2018-01-01 # (optional) starting date for "all time" option (YYYY-MM-DD)
volumes:
- ./config:/app/config
ports:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ const schema = z.object({
)
.optional(),
defaultStyle: z.string().optional(),
startDate: z.string().refine((val) => !isNaN(Date.parse(val)), {
message: 'Invalid start date',
}),
complete: z.boolean(),
})

Expand All @@ -57,6 +60,7 @@ export default async function saveDashboardSettings(
data.defaultPeriod = formData.get('defaultPeriod') as string
data.customPeriod = formData.get('customPeriod') as string
data.defaultStyle = formData.get('defaultStyle') as string
data.startDate = formData.get('startDate') as string
}

return await updateSettings(schema, data, 'dashboard')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client'

import DatePicker from '@/components/DatePicker'
import { Settings } from '@/types/settings'
import { DEFAULT_SETTINGS } from '@/utils/constants'
import { useState } from 'react'
Expand Down Expand Up @@ -168,6 +169,12 @@ export default function DashboardSettingsForm({ settings }: Props) {
/>
<span className='label'>Custom period</span>
</label>
<DatePicker
label='Start date'
helperText='Used for the all time period.'
name='startDate'
defaultValue={dashboardSettings.startDate}
/>
</section>
</>
)}
Expand Down
2 changes: 1 addition & 1 deletion src/types/dashboard.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type DashboardSearchParams = {
period?: '7days' | '30days' | 'thisYear' | 'pastYear' | 'allTime' | 'custom'
period?: '7days' | '30days' | 'pastYear' | 'allTime' | 'custom'
personal?: 'true'
}
1 change: 1 addition & 0 deletions src/types/settings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export type DashboardSettings = {
defaultStyle: string
defaultPeriod: string
customPeriod: string
startDate: string
complete: boolean
}

Expand Down
19 changes: 1 addition & 18 deletions src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,9 @@ const DAYS_AGO_7: Date = new Date(new Date().setDate(new Date().getDate() - 7))
const DAYS_AGO_30: Date = new Date(
new Date().setDate(new Date().getDate() - 30),
)
const CURRENT_YEAR: Date = new Date(new Date().getFullYear(), 0, 1)
const PAST_YEAR: Date = new Date(
new Date().setFullYear(new Date().getFullYear() - 1),
)
const ALL_TIME: Date = new Date(
env('NEXT_PUBLIC_STATISTICS_START_DATE') || '2018-01-01',
)

export type Period = {
date: string
Expand All @@ -30,27 +26,13 @@ export const PERIODS: { [key: string]: Period } = {
string: DAYS_AGO_30.toISOString().split('T')[0],
daysAgo: 30,
},
thisYear: {
date: CURRENT_YEAR.toISOString(),
string: CURRENT_YEAR.toISOString().split('T')[0],
daysAgo: Math.ceil(
(new Date().getTime() - CURRENT_YEAR.getTime()) / (1000 * 3600 * 24),
),
},
pastYear: {
date: PAST_YEAR.toISOString(),
string: PAST_YEAR.toISOString().split('T')[0],
daysAgo: Math.ceil(
(new Date().getTime() - PAST_YEAR.getTime()) / (1000 * 3600 * 24),
),
},
allTime: {
date: ALL_TIME.toISOString(),
string: ALL_TIME.toISOString().split('T')[0],
daysAgo: Math.ceil(
(new Date().getTime() - ALL_TIME.getTime()) / (1000 * 3600 * 24),
),
},
}

export const META_DESCRIPTION: string =
Expand Down Expand Up @@ -101,6 +83,7 @@ export const DEFAULT_SETTINGS: Settings = {
defaultStyle: 'general',
defaultPeriod: 'custom',
customPeriod: '30',
startDate: '2010-01-01',
complete: false,
},
}
Expand Down
43 changes: 33 additions & 10 deletions src/utils/getPeriod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,44 @@ export default function getPeriod(
const defaultPeriod = settings.dashboard.defaultPeriod
const customPeriod = parseInt(settings.dashboard.customPeriod)

let period = PERIODS[defaultPeriod] || PERIODS['30days']
function getCustomPeriod() {
const startDate = new Date(Date.now() - customPeriod * 24 * 60 * 60 * 1000)

if (periodSearchParams && PERIODS[periodSearchParams]) {
period = PERIODS[periodSearchParams]
} else if (defaultPeriod === 'custom' || periodSearchParams === 'custom') {
const DAYS_AGO_CUSTOM: Date = new Date(
new Date().setDate(new Date().getDate() - customPeriod),
return createPeriodObject(startDate, customPeriod)
}

function getAllTimePeriod() {
const startDate = new Date(settings.dashboard.startDate)
const daysAgo = Math.ceil(
(Date.now() - startDate.getTime()) / (24 * 60 * 60 * 1000),
)

period = {
date: DAYS_AGO_CUSTOM.toISOString(),
string: DAYS_AGO_CUSTOM.toISOString().split('T')[0],
daysAgo: customPeriod,
return createPeriodObject(startDate, daysAgo)
}

function createPeriodObject(date: Date, daysAgo: number) {
return {
date: date.toISOString(),
string: date.toISOString().split('T')[0],
daysAgo,
}
}

function getPeriodFromKey(key: string) {
switch (key) {
case 'custom':
return getCustomPeriod()
case 'allTime':
return getAllTimePeriod()
default:
return PERIODS[key]
}
}

const period =
(periodSearchParams && getPeriodFromKey(periodSearchParams)) ||
getPeriodFromKey(defaultPeriod) ||
PERIODS[defaultPeriod]

return period
}