Add bottom navigation, History and Settings pages with improved UI styling
This commit is contained in:
180
src/pages/HistoryPage.tsx
Normal file
180
src/pages/HistoryPage.tsx
Normal file
@@ -0,0 +1,180 @@
|
||||
import { useState } from 'react'
|
||||
import BottomNav from '../components/BottomNav'
|
||||
|
||||
interface JournalEntry {
|
||||
id: string
|
||||
date: Date
|
||||
title: string
|
||||
content: string
|
||||
}
|
||||
|
||||
export default function HistoryPage() {
|
||||
const [currentMonth, setCurrentMonth] = useState(new Date())
|
||||
|
||||
// Mock data - replace with actual Firebase data later
|
||||
const mockEntries: JournalEntry[] = [
|
||||
{
|
||||
id: '1',
|
||||
date: new Date(2026, 1, 12),
|
||||
title: 'Feeling much lighter today',
|
||||
content: 'After the long conversation yesterday, I woke up with a sense of clarity I haven\'t felt in weeks...'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
date: new Date(2026, 1, 5),
|
||||
title: 'Morning thoughts',
|
||||
content: 'The coffee smells amazing this morning. Simple pleasures like this remind me...'
|
||||
}
|
||||
]
|
||||
|
||||
const getDaysInMonth = (date: Date) => {
|
||||
const year = date.getFullYear()
|
||||
const month = date.getMonth()
|
||||
const firstDay = new Date(year, month, 1)
|
||||
const lastDay = new Date(year, month + 1, 0)
|
||||
const daysInMonth = lastDay.getDate()
|
||||
const startingDayOfWeek = firstDay.getDay()
|
||||
|
||||
return { daysInMonth, startingDayOfWeek }
|
||||
}
|
||||
|
||||
const hasEntryOnDate = (day: number) => {
|
||||
return mockEntries.some(entry => {
|
||||
const entryDate = new Date(entry.date)
|
||||
return entryDate.getDate() === day &&
|
||||
entryDate.getMonth() === currentMonth.getMonth() &&
|
||||
entryDate.getFullYear() === currentMonth.getFullYear()
|
||||
})
|
||||
}
|
||||
|
||||
const isToday = (day: number) => {
|
||||
const today = new Date()
|
||||
return day === today.getDate() &&
|
||||
currentMonth.getMonth() === today.getMonth() &&
|
||||
currentMonth.getFullYear() === today.getFullYear()
|
||||
}
|
||||
|
||||
const formatDate = (date: Date) => {
|
||||
return date.toLocaleDateString('en-US', {
|
||||
weekday: 'short',
|
||||
month: 'short',
|
||||
day: '2-digit'
|
||||
}).toUpperCase()
|
||||
}
|
||||
|
||||
const formatTime = (date: Date) => {
|
||||
return date.toLocaleTimeString('en-US', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
}).toUpperCase()
|
||||
}
|
||||
|
||||
const { daysInMonth, startingDayOfWeek } = getDaysInMonth(currentMonth)
|
||||
const monthName = currentMonth.toLocaleDateString('en-US', { month: 'long', year: 'numeric' })
|
||||
|
||||
const previousMonth = () => {
|
||||
setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() - 1))
|
||||
}
|
||||
|
||||
const nextMonth = () => {
|
||||
setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() + 1))
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="history-page">
|
||||
<div className="history-bg-decoration">
|
||||
<div className="bg-orb bg-orb-1"></div>
|
||||
<div className="bg-orb bg-orb-2"></div>
|
||||
<div className="bg-pattern"></div>
|
||||
</div>
|
||||
|
||||
<header className="history-header">
|
||||
<div className="history-header-text">
|
||||
<h1>History</h1>
|
||||
<p className="history-subtitle">Your past reflections</p>
|
||||
</div>
|
||||
<button type="button" className="history-search-btn" title="Search entries">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<circle cx="11" cy="11" r="8"></circle>
|
||||
<path d="m21 21-4.35-4.35"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</header>
|
||||
|
||||
<main className="history-container">
|
||||
<div className="calendar-card">
|
||||
<div className="calendar-header">
|
||||
<h2 className="calendar-month">{monthName}</h2>
|
||||
<div className="calendar-nav">
|
||||
<button type="button" onClick={previousMonth} className="calendar-nav-btn" title="Previous month">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<polyline points="15 18 9 12 15 6"></polyline>
|
||||
</svg>
|
||||
</button>
|
||||
<button type="button" onClick={nextMonth} className="calendar-nav-btn" title="Next month">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<polyline points="9 18 15 12 9 6"></polyline>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="calendar-grid">
|
||||
<div className="calendar-weekday">S</div>
|
||||
<div className="calendar-weekday">M</div>
|
||||
<div className="calendar-weekday">T</div>
|
||||
<div className="calendar-weekday">W</div>
|
||||
<div className="calendar-weekday">T</div>
|
||||
<div className="calendar-weekday">F</div>
|
||||
<div className="calendar-weekday">S</div>
|
||||
|
||||
{Array.from({ length: startingDayOfWeek }).map((_, i) => (
|
||||
<div key={`empty-${i}`} className="calendar-day calendar-day-empty"></div>
|
||||
))}
|
||||
|
||||
{Array.from({ length: daysInMonth }).map((_, i) => {
|
||||
const day = i + 1
|
||||
const hasEntry = hasEntryOnDate(day)
|
||||
const isTodayDate = isToday(day)
|
||||
|
||||
return (
|
||||
<button
|
||||
key={day}
|
||||
type="button"
|
||||
className={`calendar-day ${hasEntry ? 'calendar-day-has-entry' : ''} ${isTodayDate ? 'calendar-day-today' : ''}`}
|
||||
onClick={() => console.log('View entries for', day)}
|
||||
>
|
||||
{day}
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section className="recent-entries">
|
||||
<h3 className="recent-entries-title">RECENT ENTRIES</h3>
|
||||
|
||||
<div className="entries-list">
|
||||
{mockEntries.map(entry => (
|
||||
<button
|
||||
key={entry.id}
|
||||
type="button"
|
||||
className="entry-card"
|
||||
onClick={() => console.log('Open entry', entry.id)}
|
||||
>
|
||||
<div className="entry-header">
|
||||
<span className="entry-date">{formatDate(entry.date)}</span>
|
||||
<span className="entry-time">{formatTime(entry.date)}</span>
|
||||
</div>
|
||||
<h4 className="entry-title">{entry.title}</h4>
|
||||
<p className="entry-preview">{entry.content}</p>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<BottomNav />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user