mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 20:42:43 +00:00
fix(onboarding,integrations,cycle): deep-link source chips + cycle settings wrench
- Onboarding 'more sources' chips anchor to their provider card (/settings/integrations#oura etc.); connection cards gain scroll anchors. Apple Health (no web card) stays on the page root. - Cycle module gains a header settings wrench for parity with labs / medications / illness; the tab strip is now controlled so the wrench jumps to the settings tab and ?tab= deep-links keep working.
This commit is contained in:
1 parent
188662311a
commit
e5ca125dfb
3 files changed
+69
-18
No files matched your search
@@ -1,9 +1,15 @@
|
||||
"use client";
|
||||
|
||||
import { useMemo, useState } from "react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import dynamic from "next/dynamic";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { Loader2, Plus, RefreshCw, Sparkles } from "lucide-react";
|
||||
import {
|
||||
Loader2,
|
||||
Plus,
|
||||
RefreshCw,
|
||||
SlidersHorizontal,
|
||||
Sparkles,
|
||||
} from "lucide-react";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
@@ -100,6 +106,14 @@ export function CycleView() {
|
||||
: "calendar";
|
||||
}, [searchParams]);
|
||||
|
||||
// Controlled so the header "cycle settings" wrench (parity with the
|
||||
// labs/medications/illness modules, which expose a customize glyph) can jump
|
||||
// to the settings tab; a `?tab=` deep-link change still switches too.
|
||||
const [tab, setTab] = useState<CycleTab>(initialTab);
|
||||
useEffect(() => {
|
||||
setTab(initialTab);
|
||||
}, [initialTab]);
|
||||
|
||||
const today = useMemo(() => shiftToday(0), []);
|
||||
const from = useMemo(() => shiftToday(-90), []);
|
||||
const to = useMemo(() => shiftToday(180), []);
|
||||
@@ -158,13 +172,26 @@ export function CycleView() {
|
||||
title={<span data-tour-id="cycle-hero">{t("cycle.title")}</span>}
|
||||
description={t("cycle.subtitle")}
|
||||
actions={
|
||||
<Button
|
||||
onClick={() => openSheet(today)}
|
||||
className="min-h-11 sm:min-h-9"
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
{t("cycle.logToday")}
|
||||
</Button>
|
||||
<>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="icon"
|
||||
className="min-h-11 min-w-11 sm:min-h-9 sm:min-w-9"
|
||||
aria-label={t("cycle.tabs.settings")}
|
||||
title={t("cycle.tabs.settings")}
|
||||
data-slot="cycle-settings-wrench"
|
||||
onClick={() => setTab("settings")}
|
||||
>
|
||||
<SlidersHorizontal className="h-4 w-4" aria-hidden="true" />
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => openSheet(today)}
|
||||
className="min-h-11 sm:min-h-9"
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
{t("cycle.logToday")}
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -266,7 +293,7 @@ export function CycleView() {
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<Tabs defaultValue={initialTab}>
|
||||
<Tabs value={tab} onValueChange={(v) => setTab(v as CycleTab)}>
|
||||
{/* v1.15.10 — the four German labels (Kalender/Prognosen/
|
||||
Erkenntnisse/Einstellungen) overflowed the `flex-1` equal-width
|
||||
cells at 375 px and forced a horizontal scroll. Below `sm` the
|
||||
|
||||
@@ -170,7 +170,15 @@ export function SourceCardGrid() {
|
||||
<li key={item.slug}>
|
||||
<Button asChild variant="outline" size="sm" className="min-h-9">
|
||||
<Link
|
||||
href="/settings/integrations"
|
||||
// Anchor each chip to its provider card so the tap lands on
|
||||
// the card, not the top of the generic Integrations page.
|
||||
// Apple Health has no web card (it syncs from the iOS app),
|
||||
// so its chip stays on the page root.
|
||||
href={
|
||||
item.slug === "apple-health"
|
||||
? "/settings/integrations"
|
||||
: `/settings/integrations#${item.slug}`
|
||||
}
|
||||
data-testid={`source-more-${item.slug}`}
|
||||
>
|
||||
{t(item.labelKey)}
|
||||
|
||||
@@ -262,13 +262,29 @@ export function ConnectionsPanel() {
|
||||
|
||||
return (
|
||||
<div className="space-y-6" data-slot="connections-panel">
|
||||
<WithingsCard viewModel={withingsViewModel} />
|
||||
<WhoopCard viewModel={whoopViewModel} />
|
||||
<FitbitCard viewModel={fitbitViewModel} />
|
||||
<GoogleHealthCard viewModel={googleHealthViewModel} />
|
||||
<PolarCard enabled={isAuthenticated} viewModel={polarViewModel} />
|
||||
<OuraCard enabled={isAuthenticated} viewModel={ouraViewModel} />
|
||||
<NightscoutCard enabled={isAuthenticated} />
|
||||
{/* Per-provider anchors so deep-links (onboarding "more sources" chips,
|
||||
`/settings/integrations#oura`) scroll straight to the right card. */}
|
||||
<div id="withings" className="scroll-mt-28">
|
||||
<WithingsCard viewModel={withingsViewModel} />
|
||||
</div>
|
||||
<div id="whoop" className="scroll-mt-28">
|
||||
<WhoopCard viewModel={whoopViewModel} />
|
||||
</div>
|
||||
<div id="fitbit" className="scroll-mt-28">
|
||||
<FitbitCard viewModel={fitbitViewModel} />
|
||||
</div>
|
||||
<div id="google-health" className="scroll-mt-28">
|
||||
<GoogleHealthCard viewModel={googleHealthViewModel} />
|
||||
</div>
|
||||
<div id="polar" className="scroll-mt-28">
|
||||
<PolarCard enabled={isAuthenticated} viewModel={polarViewModel} />
|
||||
</div>
|
||||
<div id="oura" className="scroll-mt-28">
|
||||
<OuraCard enabled={isAuthenticated} viewModel={ouraViewModel} />
|
||||
</div>
|
||||
<div id="nightscout" className="scroll-mt-28">
|
||||
<NightscoutCard enabled={isAuthenticated} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user