Journal UI: write and read season notes where you're already looking (#53) (#67)
Build image / build-and-push (push) Successful in 11s
Build image / build-and-push (push) Successful in 11s
Co-authored-by: Steve Dudenhoeffer <[email protected]>
This commit was merged in pull request #67.
This commit is contained in:
@@ -5,6 +5,7 @@ import { Button } from '@/components/ui/Button'
|
||||
import { GardenCanvas } from '@/editor/GardenCanvas'
|
||||
import { EditorRail, type RailTab } from '@/editor/EditorRail'
|
||||
import { HistoryPanel } from '@/editor/HistoryPanel'
|
||||
import { JournalPanel } from '@/editor/JournalPanel'
|
||||
import { Inspector } from '@/editor/Inspector'
|
||||
import { PlopInspector } from '@/editor/PlopInspector'
|
||||
import { PlantPicker } from '@/editor/PlantPicker'
|
||||
@@ -29,6 +30,7 @@ import {
|
||||
} from '@/lib/objects'
|
||||
import { toEditorPlanting } from '@/lib/plantings'
|
||||
import type { Plant } from '@/lib/plants'
|
||||
import { useJournalCounts } from '@/lib/journal'
|
||||
import { useSeedTray } from '@/lib/seedTray'
|
||||
import { usePageTitle } from '@/lib/usePageTitle'
|
||||
|
||||
@@ -58,6 +60,13 @@ export function GardenEditorPage() {
|
||||
const setFocusedObject = useEditorStore((s) => s.setFocusedObject)
|
||||
const railTab = useEditorStore((s) => s.railTab)
|
||||
const setRailTab = useEditorStore((s) => s.setRailTab)
|
||||
const journalObjectId = useEditorStore((s) => s.journalObjectId)
|
||||
const setJournalObjectId = useEditorStore((s) => s.setJournalObjectId)
|
||||
const journalCounts = useJournalCounts(gid)
|
||||
const journalTotal = useMemo(
|
||||
() => [...(journalCounts.data?.values() ?? [])].reduce((a, b) => a + b, 0),
|
||||
[journalCounts.data],
|
||||
)
|
||||
const armedPlant = useEditorStore((s) => s.armedPlant)
|
||||
const setArmedPlant = useEditorStore((s) => s.setArmedPlant)
|
||||
|
||||
@@ -316,6 +325,13 @@ export function GardenEditorPage() {
|
||||
setFocusedObject(selectedObject.id)
|
||||
select(null)
|
||||
}}
|
||||
noteCount={journalCounts.data?.get(selectedObject.id) ?? 0}
|
||||
onAddNote={() => {
|
||||
// Two taps from a selected bed to typing: scope the journal to it
|
||||
// and switch tabs. The composer is already open in there.
|
||||
setJournalObjectId(selectedObject.id)
|
||||
setRailTab('journal')
|
||||
}}
|
||||
/>
|
||||
) : selectedPlop ? (
|
||||
<PlopInspector
|
||||
@@ -332,6 +348,24 @@ export function GardenEditorPage() {
|
||||
<p className="text-sm text-muted">Select a bed or a planting to edit it.</p>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'journal',
|
||||
label: 'Journal',
|
||||
// The total on the tab is the discoverability half: a garden with a
|
||||
// season's notes in it shouldn't look identical to an empty one.
|
||||
badge: journalTotal,
|
||||
render: () => (
|
||||
<JournalPanel
|
||||
gardenId={gid}
|
||||
canEdit={canEdit}
|
||||
currentUserId={me.data?.id}
|
||||
isOwner={isOwner}
|
||||
objects={objects}
|
||||
scopeObjectId={journalObjectId}
|
||||
onScopeChange={setJournalObjectId}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'history',
|
||||
label: 'History',
|
||||
@@ -362,6 +396,16 @@ export function GardenEditorPage() {
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="mt-2 w-full text-sm"
|
||||
onClick={() => {
|
||||
setJournalObjectId(null)
|
||||
setRailTab(railTab === 'journal' ? null : 'journal')
|
||||
}}
|
||||
>
|
||||
Journal
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="mt-1 w-full text-sm"
|
||||
onClick={() => setRailTab(railTab === 'history' ? null : 'history')}
|
||||
>
|
||||
History
|
||||
|
||||
Reference in New Issue
Block a user