add Ko-fi bean
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
---
|
||||
# nuzlocke-tracker-d68l
|
||||
title: 'Frontend: Journal entry editor and list view'
|
||||
status: todo
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-03-20T15:15:55Z
|
||||
updated_at: 2026-03-20T15:15:59Z
|
||||
updated_at: 2026-03-20T15:37:39Z
|
||||
parent: nuzlocke-tracker-mz16
|
||||
blocked_by:
|
||||
- nuzlocke-tracker-vmto
|
||||
@@ -21,15 +21,49 @@ Create the frontend UI for writing and viewing journal entries.
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Add `JournalEntry` TypeScript types to `frontend/src/types/`
|
||||
- [ ] Create API client functions for journal CRUD
|
||||
- [ ] Create `JournalList` component — chronological list of entries for a run
|
||||
- [x] Add `JournalEntry` TypeScript types to `frontend/src/types/`
|
||||
- [x] Create API client functions for journal CRUD
|
||||
- [x] Create `JournalList` component — chronological list of entries for a run
|
||||
- Show title, date, preview snippet, and linked boss (if any)
|
||||
- Link each entry to its detail/edit view
|
||||
- [ ] Create `JournalEditor` component — markdown textarea with title input
|
||||
- [x] Create `JournalEditor` component — markdown textarea with title input
|
||||
- Optional boss result selector dropdown (link entry to a boss battle)
|
||||
- Preview tab to render markdown
|
||||
- Save and delete actions
|
||||
- [ ] Create `JournalEntryView` component — rendered markdown display
|
||||
- [ ] Add journal section/tab to the run detail page
|
||||
- [ ] Add route for journal entry detail/edit view
|
||||
- [x] Create `JournalEntryView` component — rendered markdown display
|
||||
- [x] Add journal section/tab to the run detail page
|
||||
- [x] Add route for journal entry detail/edit view
|
||||
|
||||
|
||||
## Summary of Changes
|
||||
|
||||
Implemented the frontend journal entry editor and list view with the following components:
|
||||
|
||||
**Types created:**
|
||||
- `frontend/src/types/journal.ts` - TypeScript types for JournalEntry, CreateJournalEntryInput, UpdateJournalEntryInput
|
||||
|
||||
**API client created:**
|
||||
- `frontend/src/api/journal.ts` - CRUD functions for journal entries
|
||||
- `frontend/src/hooks/useJournal.ts` - React Query hooks for journal data fetching and mutations
|
||||
|
||||
**Components created:**
|
||||
- `frontend/src/components/journal/JournalList.tsx` - Chronological list of entries with title, date, preview snippet, and linked boss display
|
||||
- `frontend/src/components/journal/JournalEditor.tsx` - Markdown textarea with title input, boss result selector, write/preview tabs, save/delete actions
|
||||
- `frontend/src/components/journal/JournalEntryView.tsx` - Rendered markdown display with entry metadata
|
||||
- `frontend/src/components/journal/JournalSection.tsx` - Wrapper component for embedding in RunEncounters page
|
||||
|
||||
**Pages created:**
|
||||
- `frontend/src/pages/JournalEntryPage.tsx` - Standalone page for viewing/editing a single journal entry
|
||||
|
||||
**Modified files:**
|
||||
- `frontend/src/types/index.ts` - Added journal type exports
|
||||
- `frontend/src/pages/index.ts` - Added JournalEntryPage export
|
||||
- `frontend/src/App.tsx` - Added route `/runs/:runId/journal/:entryId`
|
||||
- `frontend/src/pages/RunEncounters.tsx` - Added Encounters/Journal tab navigation with JournalSection integration
|
||||
|
||||
**Features:**
|
||||
- Tab navigation in run detail page to switch between Encounters and Journal views
|
||||
- Create new journal entries with markdown content and optional boss battle linking
|
||||
- Edit and delete existing entries
|
||||
- Write/Preview toggle in editor
|
||||
- Rendered markdown display with full prose styling
|
||||
|
||||
@@ -5,7 +5,7 @@ status: completed
|
||||
type: epic
|
||||
priority: normal
|
||||
created_at: 2026-02-19T07:43:05Z
|
||||
updated_at: 2026-03-20T15:30:38Z
|
||||
updated_at: 2026-03-20T15:37:21Z
|
||||
---
|
||||
|
||||
Let users tell the story of their nuzlocke run through session journal entries (blog posts).
|
||||
@@ -35,4 +35,4 @@ The journal becomes a chronological narrative of the nuzlocke run, with game dat
|
||||
## Success Criteria
|
||||
|
||||
- [x] Backend: journal entries CRUD API is complete (`nuzlocke-tracker-vmto`)
|
||||
- [ ] Frontend: journal list, editor, and view are functional (`nuzlocke-tracker-d68l`)
|
||||
- [x] Frontend: journal list, editor, and view are functional (`nuzlocke-tracker-d68l`)
|
||||
|
||||
@@ -963,10 +963,29 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": "I want to add a draft to integrate Ko-fi. While the idea is not to make money from this, if this where to be hosted somewhere, it will cost something, and maybe people want to help out with that.",
|
||||
"timestamp": 1774021092843
|
||||
},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": "Created **Ko-fi Integration** (`nuzlocke-tracker-oar4`) as a `draft` / `deferred` feature. It has open questions to work through when you're ready to refine it — things like placement, widget vs. link, and whether supporters get any acknowledgment.\n\nAnything else?",
|
||||
"timestamp": 1774021107517,
|
||||
"toolCalls": [
|
||||
{
|
||||
"name": "Bash",
|
||||
"args": {
|
||||
"command": "beans create --json \"Ko-fi Integration\" -t feature -d \"Add Ko-fi integration to allow visitors to contribute toward hosting costs. This is not about monetization — it's a way for users who enjoy the tool to optionally help cover server/infrastructure expenses.\n\n## Open Questions\n\n- [ ] Where should the Ko-fi link/button live? (footer, about page, dedicated page, or subtle banner?)\n- [ ] Should it be a simple outbound link to a Ko-fi page, or use Ko-fi's embeddable widget/overlay?\n- [ ] Should there be any acknowledgment for supporters (e.g., a thank-you page, supporter list)?\n- [ ] Should this be gated behind user auth (only shown to logged-in users) or visible to everyone?\n- [ ] Any legal/tax considerations to document?\" -s draft -p deferred",
|
||||
"description": "Create Ko-fi draft bean"
|
||||
}
|
||||
],
|
||||
"createdAt": 1774018905931,
|
||||
"updatedAt": 1774020533491
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createdAt": 1774018905931,
|
||||
"updatedAt": 1774021107517
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -25,3 +25,4 @@ There basically is no local storage, runs live in the database. I think that exc
|
||||
/start
|
||||
/status
|
||||
/stop
|
||||
I want to add a draft to integrate Ko-fi. While the idea is not to make money from this, if this where to be hosted somewhere, it will cost something, and maybe people want to help out with that.
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
GenlockeDetail,
|
||||
GenlockeList,
|
||||
Home,
|
||||
JournalEntryPage,
|
||||
NewGenlocke,
|
||||
NewRun,
|
||||
RunList,
|
||||
@@ -30,6 +31,7 @@ function App() {
|
||||
<Route path="runs" element={<RunList />} />
|
||||
<Route path="runs/new" element={<NewRun />} />
|
||||
<Route path="runs/:runId" element={<RunEncounters />} />
|
||||
<Route path="runs/:runId/journal/:entryId" element={<JournalEntryPage />} />
|
||||
<Route path="genlockes" element={<GenlockeList />} />
|
||||
<Route path="genlockes/new" element={<NewGenlocke />} />
|
||||
<Route path="genlockes/:genlockeId" element={<GenlockeDetail />} />
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
} from '../components'
|
||||
import { BossDefeatModal } from '../components/BossDefeatModal'
|
||||
import { ConditionBadge } from '../components/ConditionBadge'
|
||||
import { JournalSection } from '../components/journal'
|
||||
import type {
|
||||
Route,
|
||||
RouteWithChildren,
|
||||
@@ -497,6 +498,7 @@ export function RunEncounters() {
|
||||
const [showTeam, setShowTeam] = useState(true)
|
||||
const [teamSort, setTeamSort] = useState<TeamSortKey>('route')
|
||||
const [filter, setFilter] = useState<'all' | RouteStatus>('all')
|
||||
const [activeTab, setActiveTab] = useState<'encounters' | 'journal'>('encounters')
|
||||
|
||||
const storageKey = `expandedGroups-${runId}`
|
||||
const [expandedGroups, setExpandedGroups] = useState<Set<number>>(() => {
|
||||
@@ -1137,6 +1139,40 @@ export function RunEncounters() {
|
||||
<CustomRulesDisplay customRules={run.rules?.customRules ?? ''} />
|
||||
</div>
|
||||
|
||||
{/* Tab Navigation */}
|
||||
<div className="flex gap-1 mb-6 border-b border-border">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setActiveTab('encounters')}
|
||||
className={`px-4 py-2 text-sm font-medium border-b-2 -mb-px transition-colors ${
|
||||
activeTab === 'encounters'
|
||||
? 'border-blue-500 text-blue-500'
|
||||
: 'border-transparent text-text-secondary hover:text-text-primary'
|
||||
}`}
|
||||
>
|
||||
Encounters
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setActiveTab('journal')}
|
||||
className={`px-4 py-2 text-sm font-medium border-b-2 -mb-px transition-colors ${
|
||||
activeTab === 'journal'
|
||||
? 'border-blue-500 text-blue-500'
|
||||
: 'border-transparent text-text-secondary hover:text-text-primary'
|
||||
}`}
|
||||
>
|
||||
Journal
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Journal Tab */}
|
||||
{activeTab === 'journal' && (
|
||||
<JournalSection runId={runIdNum} bossResults={bossResults} bosses={bosses} />
|
||||
)}
|
||||
|
||||
{/* Encounters Tab */}
|
||||
{activeTab === 'encounters' && (
|
||||
<>
|
||||
{/* Team Section */}
|
||||
{(alive.length > 0 || dead.length > 0) && (
|
||||
<div className="mb-6">
|
||||
@@ -1551,6 +1587,8 @@ export function RunEncounters() {
|
||||
allowedTypes={rulesAllowedTypes.length ? rulesAllowedTypes : undefined}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Shiny Encounter Modal */}
|
||||
{showShinyModal && routes && (
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export { GenlockeDetail } from './GenlockeDetail'
|
||||
export { GenlockeList } from './GenlockeList'
|
||||
export { Home } from './Home'
|
||||
export { JournalEntryPage } from './JournalEntryPage'
|
||||
export { NewGenlocke } from './NewGenlocke'
|
||||
export { NewRun } from './NewRun'
|
||||
export { RunList } from './RunList'
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export * from './admin'
|
||||
export * from './game'
|
||||
export * from './journal'
|
||||
export * from './rules'
|
||||
export * from './stats'
|
||||
|
||||
Reference in New Issue
Block a user