Skip to content

Commit 1a871aa

Browse files
committed
Add encryption store
cgen-1be2cc6b363c4a0f8af49da883260faf
1 parent 8e86756 commit 1a871aa

File tree

15 files changed

+249
-0
lines changed

15 files changed

+249
-0
lines changed

frontend/src/App.css

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/* Base app styles */
2+
:root {
3+
--cosmic-blue: #0B1426;
4+
--starlight: #E6F3FF;
5+
--gold: #FFD700;
6+
}
7+
8+
.app { min-height: 100vh; background: var(--cosmic-blue); color: var(--starlight); }
9+
10+
/* Layout */
11+
.layout-shell { display: flex; min-height: 100vh; flex-direction: column; }
12+
.layout-header { padding: 16px; border-bottom: 1px solid rgba(255,255,255,.06); }
13+
.layout-title { margin: 0; font-size: 20px; color: var(--gold); }
14+
.layout-content { flex: 1; padding: 24px; }
15+
16+
/* Pages */
17+
.page { max-width: 960px; margin: 0 auto; padding: 24px; }
18+
.page-title { margin: 0 0 8px; font-size: 28px; color: var(--gold); }
19+
.page-subtitle { margin: 0; opacity: .9; }
20+
21+
/* Spinner */
22+
.spinner { display: inline-block; border: 3px solid rgba(255,255,255,.15); border-top-color: var(--starlight); border-radius: 50%; animation: spin 1s linear infinite; }
23+
.spinner-mystical { border-top-color: var(--gold); }
24+
@keyframes spin { to { transform: rotate(360deg); } }
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import React from 'react'
2+
3+
interface Props {
4+
fallback: React.ComponentType<{ error: Error }>
5+
children: React.ReactNode
6+
}
7+
8+
interface State {
9+
hasError: boolean
10+
error: Error | null
11+
}
12+
13+
class ErrorBoundary extends React.Component<Props, State> {
14+
constructor(props: Props) {
15+
super(props)
16+
this.state = { hasError: false, error: null }
17+
}
18+
19+
static getDerivedStateFromError(error: Error): State {
20+
return { hasError: true, error }
21+
}
22+
23+
componentDidCatch(error: Error, info: React.ErrorInfo) {
24+
console.error('ErrorBoundary caught error', error, info)
25+
}
26+
27+
render() {
28+
const { fallback: Fallback, children } = this.props
29+
if (this.state.hasError && this.state.error) {
30+
return <Fallback error={this.state.error} />
31+
}
32+
return children
33+
}
34+
}
35+
36+
export default ErrorBoundary
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import React from 'react'
2+
3+
interface Props {
4+
children: React.ReactNode
5+
}
6+
7+
const Layout: React.FC<Props> = ({ children }) => {
8+
return (
9+
<div className="layout-shell">
10+
<header className="layout-header">
11+
<h1 className="layout-title">The Turning Wheel</h1>
12+
</header>
13+
<main className="layout-content">
14+
{children}
15+
</main>
16+
</div>
17+
)
18+
}
19+
20+
export default Layout
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import React from 'react'
2+
3+
interface Props {
4+
size?: 'small' | 'medium' | 'large'
5+
variant?: 'default' | 'mystical'
6+
}
7+
8+
const sizeMap: Record<NonNullable<Props['size']>, number> = {
9+
small: 20,
10+
medium: 32,
11+
large: 48
12+
}
13+
14+
const LoadingSpinner: React.FC<Props> = ({ size = 'medium', variant = 'default' }) => {
15+
const px = sizeMap[size]
16+
const classes = `spinner ${variant === 'mystical' ? 'spinner-mystical' : ''}`
17+
return <span className={classes} style={{ width: px, height: px }} aria-label="loading" />
18+
}
19+
20+
export default LoadingSpinner
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { useEffect, useState } from 'react'
2+
3+
export function useInitializeApp() {
4+
const [isLoading, setIsLoading] = useState(false)
5+
const [error, setError] = useState<Error | null>(null)
6+
7+
useEffect(() => {
8+
let mounted = true
9+
const init = async () => {
10+
try {
11+
// initialization placeholder completed synchronously for now
12+
if (!mounted) return
13+
setIsLoading(false)
14+
} catch (e) {
15+
if (!mounted) return
16+
setError(e as Error)
17+
setIsLoading(false)
18+
}
19+
}
20+
init()
21+
return () => {
22+
mounted = false
23+
}
24+
}, [])
25+
26+
return { isLoading, error }
27+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import React from 'react'
2+
3+
const AnalyticsPage: React.FC = () => {
4+
return (
5+
<section className="page analytics-page">
6+
<h2 className="page-title">Analytics</h2>
7+
<p className="page-subtitle">Insights and data visualizations.</p>
8+
</section>
9+
)
10+
}
11+
12+
export default AnalyticsPage

frontend/src/pages/AuthPage.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import React from 'react'
2+
3+
const AuthPage: React.FC = () => {
4+
return (
5+
<section className="page auth-page">
6+
<h2 className="page-title">Sign In</h2>
7+
<p className="page-subtitle">Authentication UI coming soon.</p>
8+
</section>
9+
)
10+
}
11+
12+
export default AuthPage
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import React from 'react'
2+
3+
const DashboardPage: React.FC = () => {
4+
return (
5+
<section className="page dashboard-page">
6+
<h2 className="page-title">Dashboard</h2>
7+
<p className="page-subtitle">Your progress and insights appear here.</p>
8+
</section>
9+
)
10+
}
11+
12+
export default DashboardPage

frontend/src/pages/JourneyPage.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import React from 'react'
2+
3+
const JourneyPage: React.FC = () => {
4+
return (
5+
<section className="page journey-page">
6+
<h2 className="page-title">Your Journey</h2>
7+
<p className="page-subtitle">Track your steps through the wheel.</p>
8+
</section>
9+
)
10+
}
11+
12+
export default JourneyPage

frontend/src/pages/LandingPage.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import React from 'react'
2+
3+
const LandingPage: React.FC = () => {
4+
return (
5+
<section className="page landing-page">
6+
<h2 className="page-title">Welcome to The Turning Wheel</h2>
7+
<p className="page-subtitle">Begin your journey by signing in.</p>
8+
</section>
9+
)
10+
}
11+
12+
export default LandingPage

0 commit comments

Comments
 (0)