ui enhance
This commit is contained in:
1695
src/App.css
1695
src/App.css
File diff suppressed because it is too large
Load Diff
@@ -8,38 +8,47 @@ export default function BottomNav() {
|
||||
|
||||
return (
|
||||
<nav className="bottom-nav">
|
||||
<button
|
||||
type="button"
|
||||
{/* Write */}
|
||||
<button
|
||||
type="button"
|
||||
className={`bottom-nav-btn ${isActive('/') ? 'bottom-nav-btn-active' : ''}`}
|
||||
onClick={() => navigate('/')}
|
||||
aria-label="Write"
|
||||
>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M12 19l7-7 3 3-7 7-3-3z"></path>
|
||||
<path d="M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z"></path>
|
||||
<path d="M2 2l7.586 7.586"></path>
|
||||
<circle cx="11" cy="11" r="2"></circle>
|
||||
{/* Pencil / edit icon */}
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
|
||||
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
|
||||
</svg>
|
||||
<span>Write</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
|
||||
{/* History */}
|
||||
<button
|
||||
type="button"
|
||||
className={`bottom-nav-btn ${isActive('/history') ? 'bottom-nav-btn-active' : ''}`}
|
||||
onClick={() => navigate('/history')}
|
||||
aria-label="History"
|
||||
>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path>
|
||||
<polyline points="9 22 9 12 15 12 15 22"></polyline>
|
||||
{/* Clock icon */}
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round">
|
||||
<circle cx="12" cy="12" r="10" />
|
||||
<polyline points="12 6 12 12 16 14" />
|
||||
</svg>
|
||||
<span>History</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
|
||||
{/* Settings */}
|
||||
<button
|
||||
type="button"
|
||||
className={`bottom-nav-btn ${isActive('/settings') ? 'bottom-nav-btn-active' : ''}`}
|
||||
onClick={() => navigate('/settings')}
|
||||
aria-label="Settings"
|
||||
>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<circle cx="12" cy="12" r="3"></circle>
|
||||
<path d="M12 1v6m0 6v6m5.196-15.804l-4.243 4.243m-5.657 5.657l-4.243 4.243M23 12h-6m-6 0H1m15.804 5.196l-4.243-4.243m-5.657-5.657L2.661 2.661"></path>
|
||||
{/* Gear icon */}
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round">
|
||||
<circle cx="12" cy="12" r="3" />
|
||||
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z" />
|
||||
</svg>
|
||||
<span>Settings</span>
|
||||
</button>
|
||||
|
||||
@@ -6,21 +6,22 @@
|
||||
}
|
||||
|
||||
:root {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica Neue", sans-serif;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
/* Responsive base: 16px at 320px, scales up to 18px by 768px */
|
||||
font-size: clamp(1rem, 0.9rem + 0.25vw, 1.125rem);
|
||||
/* Fixed 16px – we're always rendering at phone scale */
|
||||
font-size: 16px;
|
||||
|
||||
--color-primary: #1be62c;
|
||||
--color-primary-hover: #18c925;
|
||||
--color-bg-soft: #f1eee1;
|
||||
--touch-min: 44px;
|
||||
|
||||
--color-primary: #22c55e;
|
||||
--color-primary-hover: #16a34a;
|
||||
--color-bg-soft: #f5f0e8;
|
||||
--color-surface: #ffffff;
|
||||
--color-accent-light: #cff2dc;
|
||||
--color-accent-bright: #c3fd2f;
|
||||
--color-accent-light: #dcfce7;
|
||||
--color-text: #1a1a1a;
|
||||
--color-text-muted: #6b7280;
|
||||
--color-border: #cff2dc;
|
||||
--color-border: #e5e7eb;
|
||||
|
||||
color: var(--color-text);
|
||||
background-color: var(--color-bg-soft);
|
||||
@@ -40,16 +41,39 @@ a:hover {
|
||||
}
|
||||
|
||||
html {
|
||||
overflow-x: hidden;
|
||||
height: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
min-width: 280px;
|
||||
min-height: 100vh;
|
||||
height: 100%;
|
||||
min-height: 100dvh;
|
||||
padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
|
||||
overflow: hidden;
|
||||
/* Desktop: show as phone on a desk surface */
|
||||
background: #ccc8c0;
|
||||
}
|
||||
|
||||
/* ── Phone shell on desktop ───────────────────────────── */
|
||||
@media (min-width: 600px) {
|
||||
body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #bbb7af;
|
||||
}
|
||||
|
||||
#root {
|
||||
width: 390px !important;
|
||||
max-width: 390px !important;
|
||||
height: 100dvh;
|
||||
max-height: 100dvh;
|
||||
border-radius: 0;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 24px 80px rgba(0, 0, 0, 0.35), 0 4px 16px rgba(0, 0, 0, 0.2);
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
|
||||
@@ -11,21 +11,7 @@ interface JournalEntry {
|
||||
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 entries: JournalEntry[] = []
|
||||
|
||||
const getDaysInMonth = (date: Date) => {
|
||||
const year = date.getFullYear()
|
||||
@@ -39,7 +25,7 @@ export default function HistoryPage() {
|
||||
}
|
||||
|
||||
const hasEntryOnDate = (day: number) => {
|
||||
return mockEntries.some(entry => {
|
||||
return entries.some(entry => {
|
||||
const entryDate = new Date(entry.date)
|
||||
return entryDate.getDate() === day &&
|
||||
entryDate.getMonth() === currentMonth.getMonth() &&
|
||||
@@ -82,12 +68,6 @@ export default function HistoryPage() {
|
||||
|
||||
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>
|
||||
@@ -155,7 +135,11 @@ export default function HistoryPage() {
|
||||
<h3 className="recent-entries-title">RECENT ENTRIES</h3>
|
||||
|
||||
<div className="entries-list">
|
||||
{mockEntries.map(entry => (
|
||||
{entries.length === 0 ? (
|
||||
<p style={{ color: '#9ca3af', fontSize: '0.875rem', textAlign: 'center', padding: '1.5rem 0', fontFamily: 'Inter, sans-serif' }}>
|
||||
No entries yet. Start writing!
|
||||
</p>
|
||||
) : entries.map(entry => (
|
||||
<button
|
||||
key={entry.id}
|
||||
type="button"
|
||||
|
||||
@@ -10,36 +10,29 @@ export default function HomePage() {
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="home-page">
|
||||
<p>Loading…</p>
|
||||
<div className="home-page" style={{ alignItems: 'center', justifyContent: 'center' }}>
|
||||
<p style={{ color: '#9ca3af' }}>Loading…</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (!user) {
|
||||
return (
|
||||
<div className="home-page">
|
||||
<h1>Grateful Journal</h1>
|
||||
<p>Sign in to start your journal.</p>
|
||||
<Link to="/login" className="home-login-link">
|
||||
Go to login
|
||||
</Link>
|
||||
<div className="home-page" style={{ alignItems: 'center', justifyContent: 'center', gap: '1rem' }}>
|
||||
<h1 style={{ fontFamily: 'Playfair Display, Georgia, serif', color: '#1a1a1a' }}>Grateful Journal</h1>
|
||||
<p style={{ color: '#6b7280' }}>Sign in to start your journal.</p>
|
||||
<Link to="/login" className="home-login-link">Go to login</Link>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const displayName = user.displayName ?? user.email ?? 'there'
|
||||
|
||||
// Get current date formatted like "THURSDAY, OCT 24"
|
||||
// Format date: "THURSDAY, OCT 24"
|
||||
const today = new Date()
|
||||
const dateString = today.toLocaleDateString('en-US', {
|
||||
weekday: 'long',
|
||||
month: 'short',
|
||||
day: 'numeric'
|
||||
}).toUpperCase()
|
||||
const dateString = today
|
||||
.toLocaleDateString('en-US', { weekday: 'long', month: 'short', day: 'numeric' })
|
||||
.toUpperCase()
|
||||
|
||||
const handleWrite = () => {
|
||||
console.log('Saving entry:', { title, entry })
|
||||
// TODO: Save to Firebase
|
||||
setTitle('')
|
||||
setEntry('')
|
||||
@@ -47,29 +40,12 @@ export default function HomePage() {
|
||||
|
||||
return (
|
||||
<div className="home-page">
|
||||
<div className="home-bg-decoration">
|
||||
<div className="bg-orb bg-orb-1"></div>
|
||||
<div className="bg-orb bg-orb-2"></div>
|
||||
<div className="bg-orb bg-orb-3"></div>
|
||||
<div className="bg-pattern"></div>
|
||||
</div>
|
||||
|
||||
<header className="home-header">
|
||||
<h1>Grateful Journal</h1>
|
||||
<div className="home-user">
|
||||
<span className="home-username">{displayName}</span>
|
||||
<button type="button" className="home-sign-out" onClick={() => signOut()}>
|
||||
Sign out
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main className="journal-container">
|
||||
<div className="journal-card">
|
||||
<div className="journal-date">{dateString}</div>
|
||||
|
||||
|
||||
<h2 className="journal-prompt">What are you grateful for today?</h2>
|
||||
|
||||
|
||||
<div className="journal-writing-area">
|
||||
<input
|
||||
type="text"
|
||||
@@ -92,3 +68,4 @@ export default function HomePage() {
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -19,12 +19,6 @@ export default function SettingsPage() {
|
||||
|
||||
return (
|
||||
<div className="settings-page">
|
||||
<div className="settings-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="settings-header">
|
||||
<div className="settings-header-text">
|
||||
<h1>Settings</h1>
|
||||
@@ -80,8 +74,12 @@ export default function SettingsPage() {
|
||||
<div className="settings-item">
|
||||
<div className="settings-item-icon settings-item-icon-gray">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2z"></path>
|
||||
<path d="M12 6v6l4 2"></path>
|
||||
<path d="M2 12C2 6.5 6.5 2 12 2a10 10 0 0 1 8 4"></path>
|
||||
<path d="M5 19.5C5.5 18 6 15 6 12c0-1.73.37-3.36 1.03-4.83"></path>
|
||||
<path d="M10 21c.2-2 .4-5 .4-6 0-1 .2-1.93.56-2.78"></path>
|
||||
<path d="M14 21c.2-2 .4-5 .4-6 0-3-1-5-3.4-6.5"></path>
|
||||
<path d="M18.5 21C18 18.5 18 17 18 12c0-1-.07-2-.2-3"></path>
|
||||
<path d="M22 12a10 10 0 0 1-1.53 5.35"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div className="settings-item-content">
|
||||
|
||||
Reference in New Issue
Block a user