super-time-tracker-ui 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +5 -0
- package/CHANGELOG.md +28 -0
- package/CLAUDE.md +1 -0
- package/README.md +36 -0
- package/app/api/backup/route.ts +39 -0
- package/app/api/entry/delete-bulk/route.ts +53 -0
- package/app/api/entry/move/route.ts +46 -0
- package/app/api/entry/move-bulk/route.ts +62 -0
- package/app/api/entry/route.ts +75 -0
- package/app/api/in/route.ts +38 -0
- package/app/api/note/route.ts +120 -0
- package/app/api/out/route.ts +31 -0
- package/app/api/sheet/route.ts +68 -0
- package/app/api/state/route.ts +16 -0
- package/app/api/tags/route.ts +75 -0
- package/app/color-palettes.css +260 -0
- package/app/favicon.ico +0 -0
- package/app/globals.css +140 -0
- package/app/layout.tsx +54 -0
- package/app/page.tsx +24 -0
- package/app/reporting/page.tsx +11 -0
- package/app/settings/data/page.tsx +9 -0
- package/app/settings/display/page.tsx +8 -0
- package/app/settings/page.tsx +12 -0
- package/app/settings/tags/page.tsx +13 -0
- package/bin/stt-ui.js +63 -0
- package/components/active-entry-panel.tsx +199 -0
- package/components/backup-restore-setting.tsx +168 -0
- package/components/check-in-form-collapsed-setting.tsx +44 -0
- package/components/check-in-form-collapsible.tsx +52 -0
- package/components/check-in-form.tsx +89 -0
- package/components/checkbox.tsx +75 -0
- package/components/checkout-button-group.tsx +73 -0
- package/components/chevron-icon.tsx +25 -0
- package/components/clear-tag-filters-on-sheet-change-setting.tsx +45 -0
- package/components/color-palette-setting.tsx +75 -0
- package/components/compact-lists-setting.tsx +42 -0
- package/components/confirm-before-checkout-setting.tsx +42 -0
- package/components/confirm-destructive-actions-setting.tsx +46 -0
- package/components/confirm-dialog-provider.tsx +71 -0
- package/components/confirm-dialog.tsx +90 -0
- package/components/data-settings-view.tsx +47 -0
- package/components/default-reporting-range-setting.tsx +56 -0
- package/components/default-reporting-sort-setting.tsx +45 -0
- package/components/default-sheet-session-setting.tsx +118 -0
- package/components/display-settings-view.tsx +75 -0
- package/components/duration-format-setting.tsx +40 -0
- package/components/entry-actions-menu.tsx +207 -0
- package/components/entry-edit-form.tsx +113 -0
- package/components/entry-list-bulk-bar.tsx +128 -0
- package/components/entry-list-sort-setting.tsx +41 -0
- package/components/entry-list.tsx +336 -0
- package/components/entry-notes-list.tsx +211 -0
- package/components/entry-tag-filter.tsx +99 -0
- package/components/format_datetime_hint.ts +8 -0
- package/components/format_time.ts +10 -0
- package/components/general-settings-view.tsx +40 -0
- package/components/hamburger-icon.tsx +21 -0
- package/components/note-edit-form.tsx +77 -0
- package/components/note-form.tsx +109 -0
- package/components/pencil-icon.tsx +21 -0
- package/components/reporting-date-range-picker.tsx +121 -0
- package/components/reporting-sort-controls.tsx +53 -0
- package/components/reporting-view.tsx +340 -0
- package/components/setting-radio-group.tsx +79 -0
- package/components/settings-nav.tsx +66 -0
- package/components/settings-page-layout.tsx +53 -0
- package/components/settings-saved-toast.tsx +57 -0
- package/components/sheet-actions-menu.tsx +108 -0
- package/components/sheet-sidebar.tsx +196 -0
- package/components/tag-autocomplete-input.tsx +183 -0
- package/components/tag-filter-mode-setting.tsx +47 -0
- package/components/tag-management-view.tsx +290 -0
- package/components/theme-mode-setting.tsx +44 -0
- package/components/theme-mode-system-listener.tsx +43 -0
- package/components/theme_switcher.tsx +38 -0
- package/components/time-format-setting.tsx +39 -0
- package/components/timer-in-title-setting.tsx +38 -0
- package/components/timer-show-seconds-setting.tsx +41 -0
- package/components/tracker-active-bar.tsx +76 -0
- package/components/tracker-app.tsx +338 -0
- package/components/tracker-breadcrumb.tsx +56 -0
- package/components/tracker-document-title.tsx +67 -0
- package/components/tracker-topbar.tsx +63 -0
- package/components/trash-icon.tsx +24 -0
- package/components/week-starts-on-setting.tsx +39 -0
- package/eslint.config.mjs +18 -0
- package/lib/add_note_to_entry.ts +65 -0
- package/lib/api_error_response.ts +10 -0
- package/lib/apply_accent_color.ts +12 -0
- package/lib/apply_color_palette.ts +12 -0
- package/lib/apply_compact_lists.ts +9 -0
- package/lib/apply_tag_autocomplete_selection.ts +26 -0
- package/lib/apply_theme.ts +8 -0
- package/lib/build_reporting_stats.ts +55 -0
- package/lib/build_resume_description.ts +15 -0
- package/lib/check_in_entry.ts +81 -0
- package/lib/check_out_entry.ts +75 -0
- package/lib/collect_known_tags.ts +22 -0
- package/lib/collect_tag_stats.ts +27 -0
- package/lib/collect_tags_from_entries.ts +35 -0
- package/lib/config.ts +9 -0
- package/lib/convert_json_db.ts +49 -0
- package/lib/delete_entries.ts +62 -0
- package/lib/delete_entry.ts +29 -0
- package/lib/delete_note_on_entry.ts +42 -0
- package/lib/delete_sheet.ts +30 -0
- package/lib/delete_tracker_action.ts +22 -0
- package/lib/edit_entry.ts +56 -0
- package/lib/edit_note_on_entry.ts +49 -0
- package/lib/ensure_dir_exists.ts +22 -0
- package/lib/entry_matches_tag_filter.ts +26 -0
- package/lib/fetch_tracker_state.ts +15 -0
- package/lib/filter_entries_by_tags.ts +20 -0
- package/lib/filter_known_tags.ts +20 -0
- package/lib/find_all_serialized_active_entries.ts +28 -0
- package/lib/find_serialized_active_entry.ts +12 -0
- package/lib/find_serialized_active_entry_for_sheet.ts +31 -0
- package/lib/find_sheet_with_active_entry.ts +16 -0
- package/lib/format_display_tag.ts +6 -0
- package/lib/format_duration.ts +45 -0
- package/lib/gen_db.ts +43 -0
- package/lib/get_active_panel_class_name.ts +20 -0
- package/lib/get_average_entry_ms.ts +13 -0
- package/lib/get_button_class_name.ts +24 -0
- package/lib/get_check_out_confirm_dialog.ts +19 -0
- package/lib/get_clipped_entry_duration_ms.ts +18 -0
- package/lib/get_compact_lists_snapshot.ts +15 -0
- package/lib/get_date_range_ms_from_inputs.ts +31 -0
- package/lib/get_delete_entries_confirm_dialog.ts +21 -0
- package/lib/get_delete_entry_confirm_dialog.ts +19 -0
- package/lib/get_delete_note_confirm_dialog.ts +21 -0
- package/lib/get_delete_sheet_confirm_dialog.ts +25 -0
- package/lib/get_entry_duration_ms.ts +14 -0
- package/lib/get_entry_row_key.ts +8 -0
- package/lib/get_initial_preferred_sheet_name.ts +34 -0
- package/lib/get_initial_reporting_range_inputs.ts +31 -0
- package/lib/get_input_class_name.ts +15 -0
- package/lib/get_merge_tags_confirm_dialog.ts +25 -0
- package/lib/get_period_range_ms.ts +43 -0
- package/lib/get_reporting_date_range_shortcut_inputs.ts +84 -0
- package/lib/get_reporting_period_totals.ts +39 -0
- package/lib/get_reporting_stats.ts +25 -0
- package/lib/get_restore_db_confirm_dialog.ts +14 -0
- package/lib/get_running_entry_key.ts +8 -0
- package/lib/get_serialized_entries_total_ms.ts +10 -0
- package/lib/get_sheet.ts +14 -0
- package/lib/get_sheet_report_stats.ts +22 -0
- package/lib/get_sheet_report_stats_for_range.ts +46 -0
- package/lib/get_sheet_tag_filter_snapshot.ts +22 -0
- package/lib/get_sheets_duration_in_range.ts +27 -0
- package/lib/get_tag_autocomplete_context.ts +32 -0
- package/lib/get_theme_snapshot.ts +16 -0
- package/lib/get_tracker_state.ts +67 -0
- package/lib/has_string_value.ts +6 -0
- package/lib/is_entry_in_day.ts +15 -0
- package/lib/is_idle_sheet_report.ts +8 -0
- package/lib/is_json_time_tracker_db.ts +14 -0
- package/lib/merge_tags_across_db.ts +79 -0
- package/lib/migrate_json_db.ts +56 -0
- package/lib/migrate_json_db_to_version_three.ts +51 -0
- package/lib/migrate_json_db_to_version_two.ts +50 -0
- package/lib/move_entries_to_sheet.ts +152 -0
- package/lib/move_entry_to_sheet.ts +82 -0
- package/lib/normalize_stored_tag.ts +16 -0
- package/lib/notify_settings_saved.ts +47 -0
- package/lib/parse_default_sheet_session_mode.ts +21 -0
- package/lib/parse_entry_from_input.ts +23 -0
- package/lib/parse_natural_language_date.ts +23 -0
- package/lib/parse_reporting_source_sheets.ts +22 -0
- package/lib/partition_sheet_report_stats.ts +30 -0
- package/lib/patch_tracker_action.ts +22 -0
- package/lib/persist_ui_preference.ts +18 -0
- package/lib/post_tracker_action.ts +22 -0
- package/lib/preferences/accent_color_preference.ts +21 -0
- package/lib/preferences/check_in_form_collapsed_preference.ts +20 -0
- package/lib/preferences/clear_tag_filters_on_sheet_change_preference.ts +20 -0
- package/lib/preferences/color_palette_preference.ts +21 -0
- package/lib/preferences/confirm_before_checkout_preference.ts +20 -0
- package/lib/preferences/confirm_destructive_actions_preference.ts +20 -0
- package/lib/preferences/default_reporting_range_preference.ts +21 -0
- package/lib/preferences/default_reporting_sort_preference.ts +24 -0
- package/lib/preferences/duration_format_preference.ts +19 -0
- package/lib/preferences/entry_list_sort_preference.ts +21 -0
- package/lib/preferences/tag_filter_mode_preference.ts +18 -0
- package/lib/preferences/theme_mode_preference.ts +18 -0
- package/lib/preferences/time_format_preference.ts +18 -0
- package/lib/preferences/timer_in_title_preference.ts +18 -0
- package/lib/preferences/timer_show_seconds_preference.ts +19 -0
- package/lib/preferences/week_starts_on_preference.ts +19 -0
- package/lib/prompt_check_out_at.ts +17 -0
- package/lib/prompt_entry_note.ts +14 -0
- package/lib/prune_sheet_tag_filter.ts +27 -0
- package/lib/read_db.ts +49 -0
- package/lib/read_db_backup_contents.ts +22 -0
- package/lib/read_document_compact_lists.ts +12 -0
- package/lib/read_document_theme.ts +14 -0
- package/lib/read_sheet_tag_filter.ts +26 -0
- package/lib/read_stored_active_sheet.ts +14 -0
- package/lib/read_stored_compact_lists.ts +24 -0
- package/lib/read_stored_default_sheet_fixed_name.ts +16 -0
- package/lib/read_stored_default_sheet_session_mode.ts +18 -0
- package/lib/read_stored_sheet_tag_filters.ts +28 -0
- package/lib/read_stored_theme.ts +18 -0
- package/lib/rename_sheet.ts +39 -0
- package/lib/rename_tag_across_db.ts +19 -0
- package/lib/resolve_active_sheet_name.ts +36 -0
- package/lib/resolve_session_preferred_sheet.ts +37 -0
- package/lib/resolve_theme.ts +18 -0
- package/lib/resolve_theme_mode_to_theme.ts +19 -0
- package/lib/restore_db_from_uploaded_json.ts +24 -0
- package/lib/serialize_entry.ts +27 -0
- package/lib/serialize_reporting_source_sheets.ts +19 -0
- package/lib/serialize_sheet_entries.ts +18 -0
- package/lib/set_accent_color.ts +12 -0
- package/lib/set_active_sheet.ts +18 -0
- package/lib/set_color_palette.ts +12 -0
- package/lib/set_compact_lists.ts +12 -0
- package/lib/set_default_sheet_fixed_name.ts +8 -0
- package/lib/set_default_sheet_session_mode.ts +11 -0
- package/lib/set_sheet_tag_filter.ts +13 -0
- package/lib/set_theme_mode.ts +19 -0
- package/lib/sheet_tag_filter_snapshots.ts +48 -0
- package/lib/sort_serialized_entries.ts +35 -0
- package/lib/sort_sheet_report_stats.ts +43 -0
- package/lib/subscribe_compact_lists.ts +25 -0
- package/lib/subscribe_sheet_tag_filters.ts +28 -0
- package/lib/subscribe_theme.ts +23 -0
- package/lib/sync_active_sheet_preference.ts +19 -0
- package/lib/tags_are_equal.ts +12 -0
- package/lib/theme_init_script.ts +11 -0
- package/lib/toggle_sheet_tag_filter.ts +28 -0
- package/lib/toggle_theme.ts +20 -0
- package/lib/types/confirm_dialog.ts +9 -0
- package/lib/types/data.ts +16 -0
- package/lib/types/generic_data.ts +25 -0
- package/lib/types/index.ts +2 -0
- package/lib/types/reporting.ts +59 -0
- package/lib/types/tag_management.ts +7 -0
- package/lib/types/theme.ts +3 -0
- package/lib/types/tracker_state.ts +39 -0
- package/lib/types/ui_preferences.ts +104 -0
- package/lib/types/ui_settings.ts +17 -0
- package/lib/ui_preference_store.ts +80 -0
- package/lib/ui_settings_init_script.ts +33 -0
- package/lib/use_check_in_form_collapsed.ts +18 -0
- package/lib/use_clear_tag_filters_on_sheet_change.ts +18 -0
- package/lib/use_confirm_before_checkout.ts +18 -0
- package/lib/use_confirm_destructive_actions.ts +18 -0
- package/lib/use_duration_format.ts +17 -0
- package/lib/use_entry_list_sort.ts +17 -0
- package/lib/use_tag_filter_mode.ts +17 -0
- package/lib/use_time_format.ts +17 -0
- package/lib/use_timer_in_title.ts +18 -0
- package/lib/use_timer_show_seconds.ts +18 -0
- package/lib/use_week_starts_on.ts +17 -0
- package/lib/validate_entry_times.ts +12 -0
- package/lib/week_starts_on_to_index.ts +8 -0
- package/lib/write_active_sheet_preference.ts +28 -0
- package/lib/write_db.ts +20 -0
- package/lib/write_sheet_tag_filter.ts +20 -0
- package/lib/write_stored_compact_lists.ts +15 -0
- package/lib/write_stored_default_sheet_fixed_name.ts +28 -0
- package/lib/write_stored_default_sheet_session_mode.ts +24 -0
- package/lib/write_stored_sheet_tag_filters.ts +18 -0
- package/lib/write_stored_theme.ts +12 -0
- package/next.config.ts +7 -0
- package/package.json +96 -0
- package/pnpm-workspace.yaml +7 -0
- package/postcss.config.mjs +7 -0
- package/public/file.svg +1 -0
- package/public/globe.svg +1 -0
- package/public/next.svg +1 -0
- package/public/vercel.svg +1 -0
- package/public/window.svg +1 -0
- package/tsconfig.json +34 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { useSyncExternalStore } from 'react'
|
|
4
|
+
|
|
5
|
+
import { week_starts_on_preference } from '@/lib/preferences/week_starts_on_preference'
|
|
6
|
+
import { type WeekStartsOn } from '@/lib/types/ui_preferences'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Subscribes to the week-starts-on preference.
|
|
10
|
+
*/
|
|
11
|
+
export function use_week_starts_on(): WeekStartsOn {
|
|
12
|
+
return useSyncExternalStore(
|
|
13
|
+
week_starts_on_preference.subscribe,
|
|
14
|
+
week_starts_on_preference.get_snapshot,
|
|
15
|
+
week_starts_on_preference.get_server_snapshot,
|
|
16
|
+
)
|
|
17
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ensures a completed entry has a start time strictly before its end time.
|
|
3
|
+
*/
|
|
4
|
+
export function validate_entry_times(start: Date, end: Date | null): void {
|
|
5
|
+
if (end === null) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
if (+start >= +end) {
|
|
10
|
+
throw new Error("Start must be before end");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ACTIVE_SHEET_COOKIE_NAME,
|
|
3
|
+
ACTIVE_SHEET_STORAGE_KEY,
|
|
4
|
+
} from '@/lib/types/ui_settings'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Persists the last opened sheet in localStorage and a cookie for SSR reloads.
|
|
8
|
+
*/
|
|
9
|
+
export function write_active_sheet_preference(sheet_name: string): void {
|
|
10
|
+
const trimmed = sheet_name.trim()
|
|
11
|
+
|
|
12
|
+
if (trimmed.length === 0) {
|
|
13
|
+
return
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
window.localStorage.setItem(ACTIVE_SHEET_STORAGE_KEY, trimmed)
|
|
18
|
+
} catch {
|
|
19
|
+
// Ignore storage failures in private browsing.
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const encoded = encodeURIComponent(trimmed)
|
|
24
|
+
document.cookie = `${ACTIVE_SHEET_COOKIE_NAME}=${encoded}; Path=/; Max-Age=31536000; SameSite=Lax`
|
|
25
|
+
} catch {
|
|
26
|
+
// Ignore cookie failures.
|
|
27
|
+
}
|
|
28
|
+
}
|
package/lib/write_db.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
|
|
3
|
+
import { DB_PATH } from "@/lib/config";
|
|
4
|
+
import { type TimeTrackerDB } from "@/lib/types";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Persists the in-memory database to disk as JSON.
|
|
8
|
+
*/
|
|
9
|
+
export async function write_db(
|
|
10
|
+
db: TimeTrackerDB,
|
|
11
|
+
db_path: string = DB_PATH,
|
|
12
|
+
): Promise<void> {
|
|
13
|
+
const db_json = JSON.stringify(db);
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
await fs.writeFile(db_path, db_json);
|
|
17
|
+
} catch (err: unknown) {
|
|
18
|
+
throw new Error(`Failed to save DB: ${String(err)}`, { cause: err });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { read_stored_sheet_tag_filters } from '@/lib/read_stored_sheet_tag_filters'
|
|
2
|
+
import { write_stored_sheet_tag_filters } from '@/lib/write_stored_sheet_tag_filters'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Updates one sheet's tag filter list in localStorage.
|
|
6
|
+
*/
|
|
7
|
+
export function write_sheet_tag_filter(
|
|
8
|
+
sheet_name: string,
|
|
9
|
+
filter_tags: string[],
|
|
10
|
+
): void {
|
|
11
|
+
const filters = read_stored_sheet_tag_filters()
|
|
12
|
+
|
|
13
|
+
if (filter_tags.length === 0) {
|
|
14
|
+
delete filters[sheet_name]
|
|
15
|
+
} else {
|
|
16
|
+
filters[sheet_name] = filter_tags
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
write_stored_sheet_tag_filters(filters)
|
|
20
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { COMPACT_LISTS_STORAGE_KEY } from "@/lib/types/ui_settings";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Persists the compact lists setting to localStorage.
|
|
5
|
+
*/
|
|
6
|
+
export function write_stored_compact_lists(enabled: boolean): void {
|
|
7
|
+
try {
|
|
8
|
+
window.localStorage.setItem(
|
|
9
|
+
COMPACT_LISTS_STORAGE_KEY,
|
|
10
|
+
enabled ? "true" : "false",
|
|
11
|
+
);
|
|
12
|
+
} catch {
|
|
13
|
+
// Ignore storage failures in private browsing.
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_SHEET_FIXED_NAME_COOKIE_NAME,
|
|
3
|
+
DEFAULT_SHEET_FIXED_NAME_STORAGE_KEY,
|
|
4
|
+
} from '@/lib/types/ui_settings'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Persists the fixed default sheet name in localStorage and a cookie.
|
|
8
|
+
*/
|
|
9
|
+
export function write_stored_default_sheet_fixed_name(sheet_name: string): void {
|
|
10
|
+
const trimmed = sheet_name.trim()
|
|
11
|
+
|
|
12
|
+
if (trimmed.length === 0) {
|
|
13
|
+
return
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
window.localStorage.setItem(DEFAULT_SHEET_FIXED_NAME_STORAGE_KEY, trimmed)
|
|
18
|
+
} catch {
|
|
19
|
+
// Ignore storage failures in private browsing.
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const encoded = encodeURIComponent(trimmed)
|
|
24
|
+
document.cookie = `${DEFAULT_SHEET_FIXED_NAME_COOKIE_NAME}=${encoded}; Path=/; Max-Age=31536000; SameSite=Lax`
|
|
25
|
+
} catch {
|
|
26
|
+
// Ignore cookie failures.
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type DefaultSheetSessionMode } from '@/lib/types/ui_settings'
|
|
2
|
+
import {
|
|
3
|
+
DEFAULT_SHEET_SESSION_MODE_COOKIE_NAME,
|
|
4
|
+
DEFAULT_SHEET_SESSION_MODE_STORAGE_KEY,
|
|
5
|
+
} from '@/lib/types/ui_settings'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Persists the default sheet session mode in localStorage and a cookie.
|
|
9
|
+
*/
|
|
10
|
+
export function write_stored_default_sheet_session_mode(
|
|
11
|
+
mode: DefaultSheetSessionMode,
|
|
12
|
+
): void {
|
|
13
|
+
try {
|
|
14
|
+
window.localStorage.setItem(DEFAULT_SHEET_SESSION_MODE_STORAGE_KEY, mode)
|
|
15
|
+
} catch {
|
|
16
|
+
// Ignore storage failures in private browsing.
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
document.cookie = `${DEFAULT_SHEET_SESSION_MODE_COOKIE_NAME}=${mode}; Path=/; Max-Age=31536000; SameSite=Lax`
|
|
21
|
+
} catch {
|
|
22
|
+
// Ignore cookie failures.
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { read_stored_sheet_tag_filters } from '@/lib/read_stored_sheet_tag_filters'
|
|
2
|
+
import { SHEET_TAG_FILTERS_STORAGE_KEY } from '@/lib/types/ui_settings'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Persists per-sheet tag filter selections to localStorage.
|
|
6
|
+
*/
|
|
7
|
+
export function write_stored_sheet_tag_filters(
|
|
8
|
+
filters: Record<string, string[]>,
|
|
9
|
+
): void {
|
|
10
|
+
try {
|
|
11
|
+
window.localStorage.setItem(
|
|
12
|
+
SHEET_TAG_FILTERS_STORAGE_KEY,
|
|
13
|
+
JSON.stringify(filters),
|
|
14
|
+
)
|
|
15
|
+
} catch {
|
|
16
|
+
// Ignore storage failures in private browsing.
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { THEME_STORAGE_KEY, type Theme } from "@/lib/types/theme";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Persists the active theme to localStorage.
|
|
5
|
+
*/
|
|
6
|
+
export function write_stored_theme(theme: Theme): void {
|
|
7
|
+
try {
|
|
8
|
+
window.localStorage.setItem(THEME_STORAGE_KEY, theme);
|
|
9
|
+
} catch {
|
|
10
|
+
// Storage may be unavailable in private browsing or restricted contexts.
|
|
11
|
+
}
|
|
12
|
+
}
|
package/next.config.ts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "super-time-tracker-ui",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Web UI for the super-time-tracker CLI time sheets",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"nextjs",
|
|
7
|
+
"react",
|
|
8
|
+
"time-tracking",
|
|
9
|
+
"timesheet",
|
|
10
|
+
"super-time-tracker",
|
|
11
|
+
"ui"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://github.com/f3rnox/super-time-tracker-ui",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/f3rnox/super-time-tracker-ui/issues"
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/f3rnox/super-time-tracker-ui.git"
|
|
20
|
+
},
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"author": "Cris Mihalache <f3rnox42@gmail.com>",
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=20.0.0"
|
|
25
|
+
},
|
|
26
|
+
"bin": {
|
|
27
|
+
"stt-ui": "./bin/stt-ui.js"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"dev": "next dev",
|
|
31
|
+
"build": "next build",
|
|
32
|
+
"start": "next start",
|
|
33
|
+
"stt-ui": "node bin/stt-ui.js",
|
|
34
|
+
"format": "pnpm format:prettier",
|
|
35
|
+
"format:check": "pnpm format:prettier:check",
|
|
36
|
+
"format:prettier": "prettier --write .",
|
|
37
|
+
"format:prettier:check": "prettier --check .",
|
|
38
|
+
"lint": "pnpm lint:markdownlint && pnpm lint:eslint",
|
|
39
|
+
"lint:eslint": "eslint package.json src/**/*",
|
|
40
|
+
"lint:eslint:fix": "eslint package.json src/**/*",
|
|
41
|
+
"lint:fix": "pnpm lint:markdownlint:fix && pnpm lint:eslint:fix",
|
|
42
|
+
"lint:markdownlint": "markdownlint README.md",
|
|
43
|
+
"lint:markdownlint:fix": "markdownlint --fix README.md",
|
|
44
|
+
"prepare": "husky",
|
|
45
|
+
"prepare-release": "pnpm build && git add docs",
|
|
46
|
+
"prepublish": "pnpm build",
|
|
47
|
+
"release": "pnpm prepare-release && pnpm update-version && git push --follow-tags origin main",
|
|
48
|
+
"serve:coverage": "http-server ./coverage",
|
|
49
|
+
"serve:docs": "http-server ./docs",
|
|
50
|
+
"test": "NODE_PATH=./src NODE_ENV=test vitest run",
|
|
51
|
+
"update-deps": "updates -u -g -c",
|
|
52
|
+
"update-version": "standard-version -a"
|
|
53
|
+
},
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"date-fns": "^4.2.1",
|
|
56
|
+
"humanize-duration": "^3.33.2",
|
|
57
|
+
"next": "16.2.6",
|
|
58
|
+
"react": "19.2.4",
|
|
59
|
+
"react-dom": "19.2.4",
|
|
60
|
+
"time-speak": "^1.9.0"
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@tailwindcss/postcss": "^4",
|
|
64
|
+
"@types/humanize-duration": "^3.27.4",
|
|
65
|
+
"@types/node": "^20",
|
|
66
|
+
"@types/react": "^19",
|
|
67
|
+
"@types/react-dom": "^19",
|
|
68
|
+
"eslint": "^9",
|
|
69
|
+
"eslint-config-next": "16.2.6",
|
|
70
|
+
"tailwindcss": "^4",
|
|
71
|
+
"typescript": "^5",
|
|
72
|
+
"@commitlint/cli": "^20.5.0",
|
|
73
|
+
"@commitlint/config-conventional": "^20.5.0",
|
|
74
|
+
"@commitlint/format": "^20.5.0",
|
|
75
|
+
"@commitlint/types": "^20.5.0",
|
|
76
|
+
"@eslint/js": "^10.0.1",
|
|
77
|
+
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
|
78
|
+
"globals": "^17.4.0",
|
|
79
|
+
"http-server": "^14.1.1",
|
|
80
|
+
"husky": "^9.1.7",
|
|
81
|
+
"jiti": "^2.6.1",
|
|
82
|
+
"lint-staged": "^16.4.0",
|
|
83
|
+
"markdownlint-cli": "^0.48.0",
|
|
84
|
+
"nyc": "^18.0.0",
|
|
85
|
+
"prettier": "^3.8.1",
|
|
86
|
+
"remark": "^15.0.1",
|
|
87
|
+
"standard-version": "^9.5.0",
|
|
88
|
+
"ts-node": "^10.9.2",
|
|
89
|
+
"tslib": "^2.8.1",
|
|
90
|
+
"tsx": "^4.21.0",
|
|
91
|
+
"typedoc": "^0.28.18",
|
|
92
|
+
"typescript-eslint": "^8.58.0",
|
|
93
|
+
"updates": "^17.13.5",
|
|
94
|
+
"vitest": "^4.1.2"
|
|
95
|
+
}
|
|
96
|
+
}
|
package/public/file.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
|
package/public/globe.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
|
package/public/next.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2017",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
5
|
+
"allowJs": true,
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noEmit": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"module": "esnext",
|
|
11
|
+
"moduleResolution": "bundler",
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"jsx": "react-jsx",
|
|
15
|
+
"incremental": true,
|
|
16
|
+
"plugins": [
|
|
17
|
+
{
|
|
18
|
+
"name": "next"
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"paths": {
|
|
22
|
+
"@/*": ["./*"]
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"include": [
|
|
26
|
+
"next-env.d.ts",
|
|
27
|
+
"**/*.ts",
|
|
28
|
+
"**/*.tsx",
|
|
29
|
+
".next/types/**/*.ts",
|
|
30
|
+
".next/dev/types/**/*.ts",
|
|
31
|
+
"**/*.mts"
|
|
32
|
+
],
|
|
33
|
+
"exclude": ["node_modules"]
|
|
34
|
+
}
|