added a fake login and some style changes

This commit is contained in:
2025-07-04 23:03:20 +02:00
parent 50b1bec73c
commit 8a0afcbe6b
9 changed files with 217 additions and 100 deletions

85
package-lock.json generated
View File

@@ -13,12 +13,15 @@
"react-dom": "^19.1.0", "react-dom": "^19.1.0",
"react-icons": "^5.5.0", "react-icons": "^5.5.0",
"react-router-dom": "^7.6.3", "react-router-dom": "^7.6.3",
"react-slick": "^0.30.3",
"slick-carousel": "^1.8.1",
"tailwindcss": "^4.1.11" "tailwindcss": "^4.1.11"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.29.0", "@eslint/js": "^9.29.0",
"@types/react": "^19.1.8", "@types/react": "^19.1.8",
"@types/react-dom": "^19.1.6", "@types/react-dom": "^19.1.6",
"@types/react-slick": "^0.23.13",
"@vitejs/plugin-react": "^4.5.2", "@vitejs/plugin-react": "^4.5.2",
"eslint": "^9.29.0", "eslint": "^9.29.0",
"eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-hooks": "^5.2.0",
@@ -1662,6 +1665,16 @@
"@types/react": "^19.0.0" "@types/react": "^19.0.0"
} }
}, },
"node_modules/@types/react-slick": {
"version": "0.23.13",
"resolved": "https://registry.npmjs.org/@types/react-slick/-/react-slick-0.23.13.tgz",
"integrity": "sha512-bNZfDhe/L8t5OQzIyhrRhBr/61pfBcWaYJoq6UDqFtv5LMwfg4NsVDD2J8N01JqdAdxLjOt66OZEp6PX+dGs/A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.35.0", "version": "8.35.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.35.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.35.0.tgz",
@@ -2137,6 +2150,12 @@
"node": ">=18" "node": ">=18"
} }
}, },
"node_modules/classnames": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
"integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==",
"license": "MIT"
},
"node_modules/color-convert": { "node_modules/color-convert": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -2256,6 +2275,12 @@
"node": ">=10.13.0" "node": ">=10.13.0"
} }
}, },
"node_modules/enquire.js": {
"version": "2.1.6",
"resolved": "https://registry.npmjs.org/enquire.js/-/enquire.js-2.1.6.tgz",
"integrity": "sha512-/KujNpO+PT63F7Hlpu4h3pE3TokKRHN26JYmQpPyjkRD/N57R7bPDNojMXdi7uveAKjYB7yQnartCxZnFWr0Xw==",
"license": "MIT"
},
"node_modules/esbuild": { "node_modules/esbuild": {
"version": "0.25.5", "version": "0.25.5",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz",
@@ -2781,6 +2806,13 @@
"jiti": "lib/jiti-cli.mjs" "jiti": "lib/jiti-cli.mjs"
} }
}, },
"node_modules/jquery": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
"integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==",
"license": "MIT",
"peer": true
},
"node_modules/js-tokens": { "node_modules/js-tokens": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -2835,6 +2867,15 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/json2mq": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz",
"integrity": "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==",
"license": "MIT",
"dependencies": {
"string-convert": "^0.2.0"
}
},
"node_modules/json5": { "node_modules/json5": {
"version": "2.2.3", "version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
@@ -3116,6 +3157,12 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
"license": "MIT"
},
"node_modules/lodash.merge": { "node_modules/lodash.merge": {
"version": "4.6.2", "version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -3503,6 +3550,29 @@
"react-dom": ">=18" "react-dom": ">=18"
} }
}, },
"node_modules/react-slick": {
"version": "0.30.3",
"resolved": "https://registry.npmjs.org/react-slick/-/react-slick-0.30.3.tgz",
"integrity": "sha512-B4x0L9GhkEWUMApeHxr/Ezp2NncpGc+5174R02j+zFiWuYboaq98vmxwlpafZfMjZic1bjdIqqmwLDcQY0QaFA==",
"license": "MIT",
"dependencies": {
"classnames": "^2.2.5",
"enquire.js": "^2.1.6",
"json2mq": "^0.2.0",
"lodash.debounce": "^4.0.8",
"resize-observer-polyfill": "^1.5.0"
},
"peerDependencies": {
"react": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/resize-observer-polyfill": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==",
"license": "MIT"
},
"node_modules/resolve-from": { "node_modules/resolve-from": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
@@ -3632,6 +3702,15 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/slick-carousel": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/slick-carousel/-/slick-carousel-1.8.1.tgz",
"integrity": "sha512-XB9Ftrf2EEKfzoQXt3Nitrt/IPbT+f1fgqBdoxO3W/+JYvtEOW6EgxnWfr9GH6nmULv7Y2tPmEX3koxThVmebA==",
"license": "MIT",
"peerDependencies": {
"jquery": ">=1.8.0"
}
},
"node_modules/source-map-js": { "node_modules/source-map-js": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
@@ -3641,6 +3720,12 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/string-convert": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz",
"integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==",
"license": "MIT"
},
"node_modules/strip-json-comments": { "node_modules/strip-json-comments": {
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",

View File

@@ -15,12 +15,15 @@
"react-dom": "^19.1.0", "react-dom": "^19.1.0",
"react-icons": "^5.5.0", "react-icons": "^5.5.0",
"react-router-dom": "^7.6.3", "react-router-dom": "^7.6.3",
"react-slick": "^0.30.3",
"slick-carousel": "^1.8.1",
"tailwindcss": "^4.1.11" "tailwindcss": "^4.1.11"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.29.0", "@eslint/js": "^9.29.0",
"@types/react": "^19.1.8", "@types/react": "^19.1.8",
"@types/react-dom": "^19.1.6", "@types/react-dom": "^19.1.6",
"@types/react-slick": "^0.23.13",
"@vitejs/plugin-react": "^4.5.2", "@vitejs/plugin-react": "^4.5.2",
"eslint": "^9.29.0", "eslint": "^9.29.0",
"eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-hooks": "^5.2.0",

View File

@@ -7,32 +7,7 @@ import {BrowserRouter, Route, Routes} from 'react-router-dom';
import Feed from "./pages/Feed.tsx"; import Feed from "./pages/Feed.tsx";
import DreamPage from "./pages/DreamPage.tsx"; import DreamPage from "./pages/DreamPage.tsx";
import ProfilePage from "./pages/ProfilePage.tsx"; import ProfilePage from "./pages/ProfilePage.tsx";
import Home from "./pages/Home.tsx";
function Home() {
return (
<div className="p-4">
<h1 className="dreamy-text text-3xl md:text-4xl mb-6">Welcome to REMind</h1>
<p className="mb-8 text-lg">Your dreamy journey to better sleep and dream tracking</p>
<div className="dream-container">
<h2 className="dream-title">Track Your Dreams</h2>
<p className="mb-4">Record and analyze your dreams with our intuitive interface</p>
<button className="dreamy-button">Get Started</button>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 mt-8">
<div className="card floating">
<h3 className="text-xl font-bold mb-2" style={{ color: 'var(--accent)' }}>Dream Journal</h3>
<p>Keep track of all your dreams in one place</p>
</div>
<div className="card" style={{ animationDelay: '2s' }}>
<h3 className="text-xl font-bold mb-2" style={{ color: 'var(--accent)' }}>Sleep Analysis</h3>
<p>Understand your sleep patterns better</p>
</div>
</div>
</div>
);
}
function Record() { function Record() {
return ( return (
@@ -141,7 +116,12 @@ function Archive() {
export default function App() { export default function App() {
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const [isLoggedIn, setIsLoggedIn] = useState(localStorage.getItem('loggedIn') === 'true' || false);
const handleLogin = () => {
setIsLoggedIn(true);
localStorage.setItem('loggedIn', 'true');
}
const handleSplashFinished = () => { const handleSplashFinished = () => {
setIsLoading(false); setIsLoading(false);
}; };
@@ -156,10 +136,10 @@ export default function App() {
<div className="pb-16 pt-8 min-h-screen"> <div className="pb-16 pt-8 min-h-screen">
<TopBar/> <TopBar/>
<div className="mx-auto w-full max-w-lg px-4 sm:px-6 md:max-w-2xl lg:max-w-4xl"> <div className="mx-auto w-full max-w-lg px-4 sm:px-6 md:max-w-2xl lg:max-w-4xl">
<Navbar/> <Navbar isLoggedIn={isLoggedIn}/>
<div className="mt-16 mb-20"> <div className="mt-16 mb-20">
<Routes> <Routes>
<Route path="/" element={<Home/>}/> <Route path="/" element={<Home isLoggedIn={isLoggedIn} handleLogin={handleLogin}/>}/>
<Route path="/feed" element={<Feed/>}/> <Route path="/feed" element={<Feed/>}/>
<Route path="/record" element={<Record/>}/> <Route path="/record" element={<Record/>}/>
<Route path="/archive" element={<Archive/>}/> <Route path="/archive" element={<Archive/>}/>

View File

@@ -1,30 +1,37 @@
import {NavLink} from 'react-router-dom'; import {NavLink} from 'react-router-dom';
import {FaArchive, FaHome, FaList, FaMicrophone, FaUser} from "react-icons/fa"; import {FaArchive, FaHome, FaList, FaMicrophone, FaUser} from "react-icons/fa";
export default function Navbar() { interface NavbarProps {
isLoggedIn: boolean;
}
export default function Navbar({isLoggedIn}: NavbarProps) {
if (!isLoggedIn && localStorage.getItem('loggedIn') !== 'true') return (
<></>
)
return (<> return (<>
<nav <nav
className="fixed bottom-0 left-0 right-0 flex justify-around py-4 z-10" className="fixed bottom-0 left-0 right-0 flex justify-around py-4 z-10"
style={{ backgroundColor: 'var(--accent-dark)', boxShadow: '0 -2px 10px var(--shadow)' }}> style={{backgroundColor: 'var(--accent-dark)', boxShadow: '0 -2px 10px var(--shadow)'}}>
<NavLink to="/" className="transition-transform hover:scale-110"> <NavLink to="/" className="transition-transform hover:scale-110">
<FaHome className="w-6 h-6 md:w-8 md:h-8" style={{ color: 'var(--accent-soft)' }}/> <FaHome className="w-6 h-6 md:w-8 md:h-8" style={{color: 'var(--accent-soft)'}}/>
</NavLink> </NavLink>
<NavLink to="/feed" className="transition-transform hover:scale-110"> <NavLink to="/feed" className="transition-transform hover:scale-110">
<FaList className="w-6 h-6 md:w-8 md:h-8" style={{ color: 'var(--accent-soft)' }}/> <FaList className="w-6 h-6 md:w-8 md:h-8" style={{color: 'var(--accent-soft)'}}/>
</NavLink> </NavLink>
<div className="w-16 md:w-20"></div> <div className="w-16 md:w-20"></div>
<NavLink to="/archive" className="transition-transform hover:scale-110"> <NavLink to="/archive" className="transition-transform hover:scale-110">
<FaArchive className="w-6 h-6 md:w-8 md:h-8" style={{ color: 'var(--accent-soft)' }}/> <FaArchive className="w-6 h-6 md:w-8 md:h-8" style={{color: 'var(--accent-soft)'}}/>
</NavLink> </NavLink>
<NavLink to="/profile" className="transition-transform hover:scale-110"> <NavLink to="/profile" className="transition-transform hover:scale-110">
<FaUser className="w-6 h-6 md:w-8 md:h-8" style={{ color: 'var(--accent-soft)' }}/> <FaUser className="w-6 h-6 md:w-8 md:h-8" style={{color: 'var(--accent-soft)'}}/>
</NavLink> </NavLink>
</nav> </nav>
<NavLink <NavLink
to="/record" to="/record"
className="microphone-button fixed bottom-6 left-1/2 transform -translate-x-1/2 p-4 md:p-5 rounded-full z-20 transition-transform hover:scale-110" className="microphone-button fixed bottom-6 left-1/2 transform -translate-x-1/2 p-4 md:p-5 rounded-full z-20 transition-transform hover:scale-110"
style={{ boxShadow: '0 4px 15px var(--shadow)' }} style={{boxShadow: '0 4px 15px var(--shadow)'}}
> >
<FaMicrophone className="w-8 h-8 md:w-10 md:h-10 text-white"/> <FaMicrophone className="w-8 h-8 md:w-10 md:h-10 text-white"/>
</NavLink> </NavLink>

View File

@@ -1,31 +1,33 @@
import { useEffect } from 'react'; import {useEffect} from 'react';
import logo from '../assets/logo.svg'; import logo from '../assets/logo.svg';
import text from '../assets/text.svg'; import text from '../assets/text.svg';
interface SplashScreenProps { interface SplashScreenProps {
onFinished: () => void; onFinished: () => void;
} }
export default function SplashScreen({ onFinished }: SplashScreenProps) { export default function SplashScreen({onFinished}: SplashScreenProps) {
useEffect(() => { useEffect(() => {
// Simulate loading time with a timeout // Simulate loading time with a timeout
const timer = setTimeout(() => { const timer = setTimeout(() => {
onFinished(); onFinished();
}, 2000); // Show splash screen for 2 seconds localStorage.setItem('loggedIn', 'false');
}, 2000); // Show splash screen for 2 seconds
return () => clearTimeout(timer); return () => clearTimeout(timer);
}, [onFinished]); }, [onFinished]);
return ( return (<div
<div className="fixed inset-0 flex flex-col items-center justify-center bg-violet-900 z-50"> className="fixed inset-0 flex flex-col items-center justify-center bg-gradient-to-br from-violet-900 via-rose-500 to-indigo-950 z-50">
<div className="animate-pulse flex flex-col items-center"> <div className="animate-pulse flex flex-col items-center">
<img src={logo} alt="REMind Logo" className="h-32 w-32 mb-4" /> <img src={logo} alt="REMind Logo" className="h-64 w-64 mb-4"/>
<img src={text} alt="REMind Text" className="h-16" /> <img src={text} alt="REMind Text" className="h-32"/>
</div> <p className="h-16">Träume analysieren, Gesellschaft verstehen</p>
<div className="mt-8 text-fuchsia-400"> </div>
<div className="animate-spin h-8 w-8 border-4 border-current border-t-transparent rounded-full mx-auto"></div> <div className="mt-8 text-fuchsia-400">
<p className="mt-4 text-center">Loading your dreams...</p> <div
</div> className="animate-spin h-8 w-8 border-4 border-current border-t-transparent rounded-full mx-auto"></div>
</div> <p className="mt-4 text-center">Loading your dreams...</p>
); </div>
</div>);
} }

View File

@@ -63,7 +63,7 @@ export const mockDreams: Dream[] = [
ai: { ai: {
interpretation: 'Der Spiegelgarten repräsentiert Selbsterkenntnis und Rückblick auf die eigene Vergangenheit. Jeder Spiegel steht für ein Fragment der Erinnerung, das entfernte Lachen deutet auf positive Prägungen und emotionale Verankerung hin.', interpretation: 'Der Spiegelgarten repräsentiert Selbsterkenntnis und Rückblick auf die eigene Vergangenheit. Jeder Spiegel steht für ein Fragment der Erinnerung, das entfernte Lachen deutet auf positive Prägungen und emotionale Verankerung hin.',
image: '05.png', image: '05.png',
audio: '05_1.mp3' audio: '05.mp3'
} }
}), }),
]; ];

View File

@@ -1,10 +1,13 @@
// src/pages/DreamPage.tsx
import {type NavigateFunction, useNavigate, useParams} from 'react-router-dom'; import {type NavigateFunction, useNavigate, useParams} from 'react-router-dom';
import {mockDreams} from '../data/MockDreams'; import {mockDreams} from '../data/MockDreams';
import MockUsers from '../data/MockUsers'; import MockUsers from '../data/MockUsers';
import User from '../types/User'; import User from '../types/User';
import type Dream from "../types/Dream.ts"; import type Dream from "../types/Dream.ts";
import {FaArrowLeft} from "react-icons/fa";
import Slider from "react-slick";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
export default function DreamPage() { export default function DreamPage() {
const {id} = useParams<{ id: string }>(); const {id} = useParams<{ id: string }>();
@@ -18,23 +21,23 @@ export default function DreamPage() {
<button <button
onClick={() => navigate(-1)} onClick={() => navigate(-1)}
className="mb-4 hover:underline" className="mb-4 hover:underline"
style={{ color: 'var(--accent)' }} style={{color: 'var(--accent)'}}
> >
Zurück Zurück
</button> </button>
<p style={{ color: 'var(--text-muted)' }}>Traum nicht gefunden.</p> <p style={{color: 'var(--text-muted)'}}>Traum nicht gefunden.</p>
</div>); </div>);
} }
return (<div className="page min-h-screen"> return (<div className="page min-h-screen">
{/* Header */} {/* Header */}
<div className="relative" style={{ background: 'var(--accent-gradient)' }}> <div className="relative" style={{background: 'var(--accent-gradient)'}}>
<div className="p-4 sm:p-6 md:p-8 text-white"> <div className="p-4 sm:p-6 md:p-8 text-white">
<button <button
onClick={() => navigate(-1)} onClick={() => navigate(-1)}
className="absolute top-4 left-4 p-2 rounded-full bg-white/20 backdrop-blur-sm" className="absolute top-4 left-4 p-2 rounded-full bg-white/20 backdrop-blur-sm"
> >
<FaArrowLeft/>
</button> </button>
<div className="flex items-center space-x-4 mt-8"> <div className="flex items-center space-x-4 mt-8">
{user && (<img {user && (<img
@@ -64,7 +67,7 @@ export default function DreamPage() {
<div className="p-4 sm:p-6 md:p-8 space-y-6 sm:space-y-8"> <div className="p-4 sm:p-6 md:p-8 space-y-6 sm:space-y-8">
<div className="dream-card rounded-xl sm:rounded-2xl p-4 sm:p-6"> <div className="dream-card rounded-xl sm:rounded-2xl p-4 sm:p-6">
<div className="flex items-center mb-4"> <div className="flex items-center mb-4">
<span className="font-medium" style={{ color: 'var(--accent)' }}>Traum-Beschreibung</span> <span className="font-medium" style={{color: 'var(--accent)'}}>Traum-Beschreibung</span>
</div> </div>
<p className="leading-relaxed text-lg"> <p className="leading-relaxed text-lg">
{dream.input} {dream.input}
@@ -74,35 +77,51 @@ export default function DreamPage() {
{dream.ai?.interpretation && dream.ai.interpretation !== '' && (<div {dream.ai?.interpretation && dream.ai.interpretation !== '' && (<div
className="dreamPanel rounded-xl sm:rounded-2xl p-4 sm:p-6"> className="dreamPanel rounded-xl sm:rounded-2xl p-4 sm:p-6">
<div className="flex items-center mb-4"> <div className="flex items-center mb-4">
<span className="font-medium" style={{ color: 'var(--accent)' }}>KI-Interpretation</span> <span className="font-medium" style={{color: 'var(--accent)'}}>KI-Interpretation</span>
</div> </div>
<p className="leading-relaxed"> <p className="leading-relaxed">
{dream.ai.interpretation} {dream.ai.interpretation}
</p> </p>
</div>)} </div>)}
{dream.ai?.image && dream.ai.image !== '' && (<div <Slider className="dreamPanel rounded-xl sm:rounded-2xl p-4 sm:p-6">
className="dreamPanel rounded-xl sm:rounded-2xl p-4 sm:p-6"> {dream.ai?.image && dream.ai.image !== '' && (<div>
<div className="flex items-center mb-4"> <div className="flex items-center mb-4">
<span className="font-medium" style={{ color: 'var(--accent)' }}>KI-Bild</span> <span className="font-medium" style={{color: 'var(--accent)'}}>KI-Bild</span>
</div> </div>
<div className="flex justify-center"> <div className="flex justify-center">
<img <img
src={`/assets/dreams/images/${dream.ai.image}`} src={`/assets/dreams/images/${dream.ai.image}`}
alt="KI-generiertes Traumbild" alt="KI-generiertes Traumbild"
className="max-w-full w-full sm:w-auto rounded-lg shadow-lg object-contain mx-auto" className="max-w-full w-full sm:w-auto rounded-lg shadow-lg object-contain mx-auto"
/> />
</div> </div>
</div>)} </div>)}
{dream.ai?.video && dream.ai.video !== '' && (<div>
<div className="flex items-center mb-4">
<span className="font-medium" style={{color: 'var(--accent)'}}>KI-Video</span>
</div>
<div className="flex justify-center">
<video
controls
src={`/assets/dreams/videos/${dream.ai.video}`}
className="max-w-full w-full sm:w-auto rounded-lg shadow-lg object-contain mx-auto"
>
Ihr Browser unterstützt das Video-Element nicht.
</video>
</div>
</div>)}
</Slider>
{dream.ai?.audio && dream.ai.audio !== '' && (<div {dream.ai?.audio && dream.ai.audio !== '' && (<div
className="dreamPanel rounded-xl sm:rounded-2xl p-4 sm:p-6"> className="dreamPanel rounded-xl sm:rounded-2xl p-4 sm:p-6">
<div className="flex items-center mb-4"> <div className="flex items-center mb-4">
<span className="font-medium" style={{ color: 'var(--accent)' }}>KI-Audio</span> <span className="font-medium" style={{color: 'var(--accent)'}}>KI-Audio</span>
</div> </div>
<div className="flex justify-center"> <div className="flex justify-center">
<audio <audio
controls controls
src={`/assets/dreams/audio/${dream.ai.audio}`} src={`/assets/dreams/audio/${dream.ai.audio}`}
className="w-full max-w-md sm:max-w-lg mx-auto" className="w-full max-w-md sm:max-w-lg mx-auto"
> >
@@ -111,25 +130,9 @@ export default function DreamPage() {
</div> </div>
</div>)} </div>)}
{dream.ai?.video && dream.ai.video !== '' && (<div
className="dreamPanel rounded-xl sm:rounded-2xl p-4 sm:p-6">
<div className="flex items-center mb-4">
<span className="font-medium" style={{ color: 'var(--accent)' }}>KI-Video</span>
</div>
<div className="flex justify-center">
<video
controls
src={`/assets/dreams/videos/${dream.ai.video}`}
className="max-w-full w-full sm:w-auto rounded-lg shadow-lg object-contain mx-auto"
>
Ihr Browser unterstützt das Video-Element nicht.
</video>
</div>
</div>)}
<div className="dream-card rounded-xl sm:rounded-2xl p-4 sm:p-6"> <div className="dream-card rounded-xl sm:rounded-2xl p-4 sm:p-6">
<h2 className="text-lg font-semibold mb-3">Details</h2> <h2 className="text-lg font-semibold mb-3">Details</h2>
<div className="space-y-2" style={{ color: 'var(--text-muted)' }}> <div className="space-y-2" style={{color: 'var(--text-muted)'}}>
<div className="flex justify-between"> <div className="flex justify-between">
<span>Eingabetyp</span> <span>Eingabetyp</span>
<span className="capitalize">{dream.inputType}</span> <span className="capitalize">{dream.inputType}</span>

37
src/pages/Home.tsx Normal file
View File

@@ -0,0 +1,37 @@
interface HomeProps {
isLoggedIn: boolean;
handleLogin: () => void;
}
export default function Home({isLoggedIn, handleLogin}: HomeProps) {
if (isLoggedIn) {
return (<div>
<h1>Hallo Neo!</h1>
</div>)
}
return (<div className="p-4">
<h1 className="dreamy-text text-3xl md:text-4xl mb-6">Welcome to REMind</h1>
<p className="mb-8 text-lg">Your dreamy journey to better sleep and dream tracking</p>
<div className="dream-container">
<h2 className="dream-title">Track Your Dreams</h2>
<p className="mb-4">Record and analyze your dreams with our intuitive interface</p>
<button className="dreamy-button" onClick={handleLogin}>
Get Started
</button>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 mt-8">
<div className="card floating">
<h3 className="text-xl font-bold mb-2" style={{color: 'var(--accent)'}}>Dream Journal
</h3>
<p>Keep track of all your dreams in one place</p>
</div>
<div className="card" style={{animationDelay: '2s'}}>
<h3 className="text-xl font-bold mb-2" style={{color: 'var(--accent)'}}>Sleep Analysis</h3>
<p>Understand your sleep patterns better</p>
</div>
</div>
</div>);
}

View File

@@ -12,7 +12,7 @@ const ProfilePage: React.FC = () => {
const defaultStreakDays = 0; const defaultStreakDays = 0;
return ( return (
<div className="page p-4"> <div className="page min-h-screen p-4">
<div className="dreamPanel flex flex-col items-center p-6"> <div className="dreamPanel flex flex-col items-center p-6">
{/* Profile Picture */} {/* Profile Picture */}
<div className="w-32 h-32 rounded-full overflow-hidden mb-4 border-4 border-accent"> <div className="w-32 h-32 rounded-full overflow-hidden mb-4 border-4 border-accent">