Implement header, notes and google in dashboard
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
<title>OpenWall</title>
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"
|
||||
content="default-src *; script-src * 'unsafe-inline' 'unsafe-eval'; style-src * 'unsafe-inline'; img-src * data: blob:; frame-src *; connect-src *; font-src *; media-src *; object-src *; child-src *;"
|
||||
/>
|
||||
</head>
|
||||
|
||||
|
@@ -1,9 +1,38 @@
|
||||
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
|
||||
import Header from './common/Header'
|
||||
import Calendar from './pages/Calendar'
|
||||
import Shopping from './pages/Shopping'
|
||||
import Notes from './pages/Notes'
|
||||
import Search from './pages/Search'
|
||||
|
||||
// Configuration
|
||||
const BACKGROUND_IMAGE_URL = 'https://cdn.pixabay.com/photo/2018/11/19/03/26/iceland-3824494_1280.jpg'
|
||||
|
||||
const APP_BACKGROUND_STYLE = {
|
||||
backgroundImage: `url(${BACKGROUND_IMAGE_URL})`,
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'center',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
backgroundAttachment: 'fixed',
|
||||
minHeight: '100vh'
|
||||
}
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<>
|
||||
<h1>Not implemented yet</h1>
|
||||
</>
|
||||
<Router>
|
||||
<div className="app" style={APP_BACKGROUND_STYLE}>
|
||||
<Header />
|
||||
<main className="app__main">
|
||||
<Routes>
|
||||
<Route path="/" element={<Calendar />} />
|
||||
<Route path="/shopping" element={<Shopping />} />
|
||||
<Route path="/notes" element={<Notes />} />
|
||||
<Route path="/search" element={<Search />} />
|
||||
</Routes>
|
||||
</main>
|
||||
</div>
|
||||
</Router>
|
||||
)
|
||||
}
|
||||
|
||||
export default App;
|
||||
export default App
|
119
dashboard/src/renderer/src/common/Header/Header.jsx
Normal file
119
dashboard/src/renderer/src/common/Header/Header.jsx
Normal file
@@ -0,0 +1,119 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { useNavigate, useLocation } from 'react-router-dom'
|
||||
import { FiCalendar, FiShoppingBag, FiBookOpen, FiSearch } from 'react-icons/fi'
|
||||
import './styles.sass'
|
||||
|
||||
// Static color configuration
|
||||
const HEADER_COLORS = {
|
||||
primary: 'rgba(76, 175, 160, 0.25)',
|
||||
secondary: 'rgba(34, 139, 156, 0.35)',
|
||||
tertiary: 'rgba(21, 94, 117, 0.4)',
|
||||
accent: 'rgba(147, 197, 253, 0.3)'
|
||||
}
|
||||
|
||||
// Icon-specific colors for better differentiation
|
||||
const ICON_COLORS = {
|
||||
calendar: '#FF6B6B', // Red
|
||||
shopping: '#4ECDC4', // Teal
|
||||
notes: '#45B7D1', // Blue
|
||||
search: '#FFA726' // Orange
|
||||
}
|
||||
|
||||
const Header = () => {
|
||||
const [currentTime, setCurrentTime] = useState(new Date())
|
||||
const navigate = useNavigate()
|
||||
const location = useLocation()
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setInterval(() => {
|
||||
setCurrentTime(new Date())
|
||||
}, 1000)
|
||||
|
||||
return () => clearInterval(timer)
|
||||
}, [])
|
||||
|
||||
const formatTime = (date) => {
|
||||
return date.toLocaleTimeString('de-DE', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
})
|
||||
}
|
||||
|
||||
const getCurrentMonth = (date) => {
|
||||
return date.toLocaleDateString('de-DE', { month: 'long' })
|
||||
}
|
||||
|
||||
const navigationItems = [
|
||||
{ id: 'calendar', icon: FiCalendar, label: 'Kalender', path: '/' },
|
||||
{ id: 'shopping', icon: FiShoppingBag, label: 'Einkaufen', path: '/shopping' },
|
||||
{ id: 'notes', icon: FiBookOpen, label: 'Notizen', path: '/notes' },
|
||||
{ id: 'search', icon: FiSearch, label: 'Suchen', path: '/search' }
|
||||
]
|
||||
|
||||
const getActiveIcon = () => {
|
||||
const currentPath = location.pathname
|
||||
const activeItem = navigationItems.find(item => item.path === currentPath)
|
||||
return activeItem ? activeItem.id : 'calendar'
|
||||
}
|
||||
|
||||
const handleNavigation = (path) => {
|
||||
navigate(path)
|
||||
}
|
||||
|
||||
const headerStyle = {
|
||||
background: `linear-gradient(135deg, ${HEADER_COLORS.primary}, ${HEADER_COLORS.secondary}, ${HEADER_COLORS.tertiary})`,
|
||||
borderColor: HEADER_COLORS.accent
|
||||
}
|
||||
|
||||
const buttonStyle = {
|
||||
background: `linear-gradient(135deg, ${HEADER_COLORS.accent}, ${HEADER_COLORS.primary})`,
|
||||
borderColor: HEADER_COLORS.accent,
|
||||
color: '#ffffff',
|
||||
boxShadow: `0 8px 32px ${HEADER_COLORS.tertiary}, inset 0 1px 0 ${HEADER_COLORS.accent}`
|
||||
}
|
||||
|
||||
const activeButtonStyle = {
|
||||
background: `linear-gradient(135deg, ${HEADER_COLORS.primary}, ${HEADER_COLORS.secondary})`,
|
||||
borderColor: HEADER_COLORS.primary,
|
||||
color: '#ffffff',
|
||||
boxShadow: `0 12px 40px ${HEADER_COLORS.primary}, inset 0 2px 0 ${HEADER_COLORS.accent}`
|
||||
}
|
||||
|
||||
return (
|
||||
<header className="header" style={headerStyle}>
|
||||
<nav className="header__nav">
|
||||
<div className="header__left">
|
||||
<span className="header__month">{getCurrentMonth(currentTime)}</span>
|
||||
<span className="header__time">{formatTime(currentTime)}</span>
|
||||
</div>
|
||||
|
||||
<div className="header__right">
|
||||
{navigationItems.map(({ id, icon: Icon, label, path }) => {
|
||||
const isActive = getActiveIcon() === id
|
||||
const iconColor = ICON_COLORS[id]
|
||||
|
||||
const buttonStyleWithIcon = {
|
||||
...(isActive ? activeButtonStyle : buttonStyle),
|
||||
'--icon-color': iconColor
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
key={id}
|
||||
className={`header__nav-item ${isActive ? 'header__nav-item--active' : ''}`}
|
||||
onClick={() => handleNavigation(path)}
|
||||
aria-label={label}
|
||||
title={label}
|
||||
style={buttonStyleWithIcon}
|
||||
>
|
||||
<Icon style={{ color: iconColor, filter: 'drop-shadow(0 1px 2px rgba(0, 0, 0, 0.3))' }} />
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
)
|
||||
}
|
||||
|
||||
export default Header
|
1
dashboard/src/renderer/src/common/Header/index.js
Normal file
1
dashboard/src/renderer/src/common/Header/index.js
Normal file
@@ -0,0 +1 @@
|
||||
export { default } from './Header'
|
161
dashboard/src/renderer/src/common/Header/styles.sass
Normal file
161
dashboard/src/renderer/src/common/Header/styles.sass
Normal file
@@ -0,0 +1,161 @@
|
||||
// Header Component - Dynamic Color Extraction from Background
|
||||
.header
|
||||
position: fixed
|
||||
top: 0.5rem
|
||||
left: 0.5rem
|
||||
right: 0.5rem
|
||||
z-index: 1000
|
||||
padding: 1rem 2rem
|
||||
backdrop-filter: blur(80px) saturate(180%)
|
||||
border-radius: 24px
|
||||
border: 1px solid
|
||||
box-shadow: 0 20px 80px rgba(0, 0, 0, 0.15), 0 8px 32px rgba(0, 0, 0, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.4)
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1)
|
||||
|
||||
&:hover
|
||||
backdrop-filter: blur(100px) saturate(200%)
|
||||
box-shadow: 0 24px 96px rgba(0, 0, 0, 0.25), 0 12px 48px rgba(0, 0, 0, 0.15), inset 0 2px 0 rgba(255, 255, 255, 0.5)
|
||||
transform: translateY(-1px)
|
||||
|
||||
&__nav
|
||||
display: flex
|
||||
justify-content: space-between
|
||||
align-items: center
|
||||
max-width: 100%
|
||||
margin: 0 auto
|
||||
|
||||
&__left
|
||||
display: flex
|
||||
flex-direction: column
|
||||
align-items: flex-start
|
||||
gap: 0.125rem
|
||||
|
||||
&__month
|
||||
font-size: 1.5rem
|
||||
font-weight: 700
|
||||
color: rgba(255, 255, 255, 0.95)
|
||||
letter-spacing: -0.02em
|
||||
text-shadow: 0 2px 8px rgba(21, 94, 117, 0.6), 0 1px 2px rgba(0, 0, 0, 0.3)
|
||||
line-height: 1.1
|
||||
|
||||
&__time
|
||||
font-size: 2.25rem
|
||||
font-weight: 800
|
||||
color: #ffffff
|
||||
font-variant-numeric: tabular-nums
|
||||
text-shadow: 0 3px 12px rgba(21, 94, 117, 0.8), 0 1px 4px rgba(0, 0, 0, 0.4)
|
||||
line-height: 0.9
|
||||
letter-spacing: -0.05em
|
||||
|
||||
&__right
|
||||
display: flex
|
||||
align-items: center
|
||||
gap: 1rem
|
||||
|
||||
&__nav-item
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
width: 56px
|
||||
height: 56px
|
||||
border: none
|
||||
border-radius: 18px
|
||||
cursor: pointer
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1)
|
||||
backdrop-filter: blur(40px)
|
||||
border: 1px solid
|
||||
font-size: 1.375rem
|
||||
position: relative
|
||||
overflow: hidden
|
||||
|
||||
// Allow custom icon colors
|
||||
svg
|
||||
transition: all 0.3s ease
|
||||
|
||||
&::before
|
||||
content: ''
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
right: 0
|
||||
bottom: 0
|
||||
opacity: 0
|
||||
transition: opacity 0.3s ease
|
||||
border-radius: 18px
|
||||
|
||||
&:hover
|
||||
transform: translateY(-3px) scale(1.08)
|
||||
|
||||
svg
|
||||
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.4)) !important
|
||||
|
||||
&::before
|
||||
opacity: 1
|
||||
|
||||
&:active
|
||||
transform: translateY(-1px) scale(1.03)
|
||||
|
||||
&--active
|
||||
border: 1px solid
|
||||
|
||||
svg
|
||||
filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.5)) !important
|
||||
|
||||
&::before
|
||||
opacity: 1
|
||||
|
||||
&:hover
|
||||
transform: translateY(-3px) scale(1.08)
|
||||
|
||||
// Responsive Design
|
||||
@media (max-width: 768px)
|
||||
.header
|
||||
top: 0.375rem
|
||||
left: 0.375rem
|
||||
right: 0.375rem
|
||||
padding: 0.875rem 1.75rem
|
||||
border-radius: 20px
|
||||
|
||||
&__left
|
||||
gap: 0.0625rem
|
||||
|
||||
&__month
|
||||
font-size: 1.25rem
|
||||
|
||||
&__time
|
||||
font-size: 1.875rem
|
||||
|
||||
&__right
|
||||
gap: 0.875rem
|
||||
|
||||
&__nav-item
|
||||
width: 52px
|
||||
height: 52px
|
||||
border-radius: 16px
|
||||
font-size: 1.25rem
|
||||
|
||||
@media (max-width: 480px)
|
||||
.header
|
||||
top: 0.25rem
|
||||
left: 0.25rem
|
||||
right: 0.25rem
|
||||
padding: 0.75rem 1.5rem
|
||||
border-radius: 18px
|
||||
|
||||
&__left
|
||||
gap: 0.0625rem
|
||||
|
||||
&__month
|
||||
font-size: 1.125rem
|
||||
|
||||
&__time
|
||||
font-size: 1.625rem
|
||||
|
||||
&__right
|
||||
gap: 0.75rem
|
||||
|
||||
&__nav-item
|
||||
width: 48px
|
||||
height: 48px
|
||||
border-radius: 14px
|
||||
font-size: 1.125rem
|
71
dashboard/src/renderer/src/index.sass
Normal file
71
dashboard/src/renderer/src/index.sass
Normal file
@@ -0,0 +1,71 @@
|
||||
// Global Styles - Light Mode with Waterfall Background
|
||||
// Reset and base styles
|
||||
*
|
||||
margin: 0
|
||||
padding: 0
|
||||
box-sizing: border-box
|
||||
|
||||
html, body
|
||||
height: 100vh
|
||||
width: 100vw
|
||||
overflow: hidden
|
||||
|
||||
body
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif
|
||||
background: linear-gradient(rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.3)), url('https://cdn.pixabay.com/photo/2024/07/16/23/33/waterfall-8900207_1280.png')
|
||||
background-size: cover
|
||||
background-position: center
|
||||
background-attachment: fixed
|
||||
color: #1e293b
|
||||
font-weight: 400
|
||||
letter-spacing: -0.01em
|
||||
line-height: 1.5
|
||||
-webkit-font-smoothing: antialiased
|
||||
-moz-osx-font-smoothing: grayscale
|
||||
|
||||
#root
|
||||
height: 100vh
|
||||
width: 100vw
|
||||
display: flex
|
||||
flex-direction: column
|
||||
|
||||
// App Layout Styles
|
||||
.app
|
||||
height: 100vh
|
||||
width: 100vw
|
||||
display: flex
|
||||
flex-direction: column
|
||||
|
||||
&__main
|
||||
flex: 1
|
||||
padding-top: 5rem
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
|
||||
&__content
|
||||
text-align: center
|
||||
backdrop-filter: blur(40px) saturate(180%)
|
||||
background: rgba(255, 255, 255, 0.25)
|
||||
padding: 4rem
|
||||
border-radius: 32px
|
||||
border: 1px solid rgba(255, 255, 255, 0.3)
|
||||
box-shadow: 0 16px 64px rgba(0, 0, 0, 0.1), 0 8px 32px rgba(0, 0, 0, 0.05), inset 0 1px 0 rgba(255, 255, 255, 0.4)
|
||||
max-width: 600px
|
||||
margin: 0 auto
|
||||
|
||||
h1
|
||||
font-size: 3rem
|
||||
font-weight: 800
|
||||
margin-bottom: 1.5rem
|
||||
background: linear-gradient(135deg, #1e293b, #475569, #0f766e)
|
||||
-webkit-background-clip: text
|
||||
-webkit-text-fill-color: transparent
|
||||
background-clip: text
|
||||
line-height: 1.2
|
||||
|
||||
p
|
||||
font-size: 1.25rem
|
||||
color: rgba(30, 41, 59, 0.8)
|
||||
font-weight: 500
|
||||
line-height: 1.6
|
@@ -1,5 +1,6 @@
|
||||
import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import './index.sass'
|
||||
import App from './App'
|
||||
|
||||
createRoot(document.getElementById('root')).render(
|
||||
|
9
dashboard/src/renderer/src/pages/Calendar.jsx
Normal file
9
dashboard/src/renderer/src/pages/Calendar.jsx
Normal file
@@ -0,0 +1,9 @@
|
||||
const Calendar = () => {
|
||||
return (
|
||||
<div>
|
||||
<h1>Kalender</h1>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Calendar
|
203
dashboard/src/renderer/src/pages/Notes.jsx
Normal file
203
dashboard/src/renderer/src/pages/Notes.jsx
Normal file
@@ -0,0 +1,203 @@
|
||||
import { useRef, useEffect, useState } from 'react'
|
||||
import { FiEdit3, FiTrash, FiChevronDown } from 'react-icons/fi'
|
||||
import { TbEraser } from 'react-icons/tb'
|
||||
import './Notes.sass'
|
||||
|
||||
const Notes = () => {
|
||||
const canvasRef = useRef(null)
|
||||
const [isDrawing, setIsDrawing] = useState(false)
|
||||
const [tool, setTool] = useState('pen') // 'pen' or 'eraser'
|
||||
const [penColor, setPenColor] = useState('#2d3748')
|
||||
const [showColorPicker, setShowColorPicker] = useState(false)
|
||||
|
||||
const colors = [
|
||||
'#2d3748', // Dark gray
|
||||
'#000000', // Black
|
||||
'#e53e3e', // Red
|
||||
'#3182ce', // Blue
|
||||
'#38a169', // Green
|
||||
'#d69e2e', // Yellow
|
||||
'#805ad5', // Purple
|
||||
'#dd6b20', // Orange
|
||||
'#e91e63', // Pink
|
||||
'#00acc1' // Cyan
|
||||
]
|
||||
|
||||
useEffect(() => {
|
||||
const canvas = canvasRef.current
|
||||
const ctx = canvas.getContext('2d')
|
||||
|
||||
// Set canvas size
|
||||
const resizeCanvas = () => {
|
||||
const container = canvas.parentElement
|
||||
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
|
||||
|
||||
canvas.width = container.clientWidth
|
||||
canvas.height = container.clientHeight
|
||||
|
||||
// Set drawing properties
|
||||
ctx.lineCap = 'round'
|
||||
ctx.lineJoin = 'round'
|
||||
ctx.imageSmoothingEnabled = true
|
||||
|
||||
// Restore canvas content after resize
|
||||
ctx.putImageData(imageData, 0, 0)
|
||||
|
||||
// Load saved canvas data
|
||||
loadCanvasFromStorage()
|
||||
}
|
||||
|
||||
resizeCanvas()
|
||||
window.addEventListener('resize', resizeCanvas)
|
||||
|
||||
return () => window.removeEventListener('resize', resizeCanvas)
|
||||
}, [])
|
||||
|
||||
const saveCanvasToStorage = () => {
|
||||
const canvas = canvasRef.current
|
||||
const dataURL = canvas.toDataURL()
|
||||
localStorage.setItem('notes-canvas', dataURL)
|
||||
}
|
||||
|
||||
const loadCanvasFromStorage = () => {
|
||||
const canvas = canvasRef.current
|
||||
const ctx = canvas.getContext('2d')
|
||||
const savedData = localStorage.getItem('notes-canvas')
|
||||
|
||||
if (savedData) {
|
||||
const img = new Image()
|
||||
img.onload = () => {
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
||||
ctx.drawImage(img, 0, 0)
|
||||
}
|
||||
img.src = savedData
|
||||
}
|
||||
}
|
||||
|
||||
const startDrawing = (e) => {
|
||||
setIsDrawing(true)
|
||||
const canvas = canvasRef.current
|
||||
const ctx = canvas.getContext('2d')
|
||||
const rect = canvas.getBoundingClientRect()
|
||||
|
||||
const x = e.clientX - rect.left
|
||||
const y = e.clientY - rect.top
|
||||
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(x, y)
|
||||
}
|
||||
|
||||
const draw = (e) => {
|
||||
if (!isDrawing) return
|
||||
|
||||
const canvas = canvasRef.current
|
||||
const ctx = canvas.getContext('2d')
|
||||
const rect = canvas.getBoundingClientRect()
|
||||
|
||||
const x = e.clientX - rect.left
|
||||
const y = e.clientY - rect.top
|
||||
|
||||
if (tool === 'pen') {
|
||||
ctx.globalCompositeOperation = 'source-over'
|
||||
ctx.strokeStyle = penColor
|
||||
ctx.lineWidth = 3
|
||||
ctx.lineTo(x, y)
|
||||
ctx.stroke()
|
||||
} else if (tool === 'eraser') {
|
||||
ctx.globalCompositeOperation = 'destination-out'
|
||||
ctx.lineWidth = 40 // Increased eraser size
|
||||
ctx.lineTo(x, y)
|
||||
ctx.stroke()
|
||||
}
|
||||
}
|
||||
|
||||
const stopDrawing = () => {
|
||||
setIsDrawing(false)
|
||||
// Save canvas state after drawing
|
||||
saveCanvasToStorage()
|
||||
}
|
||||
|
||||
const clearCanvas = () => {
|
||||
const canvas = canvasRef.current
|
||||
const ctx = canvas.getContext('2d')
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
||||
// Clear saved state
|
||||
localStorage.removeItem('notes-canvas')
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="notes-page">
|
||||
<div className="notes-container">
|
||||
{/* Toolbar */}
|
||||
<div className="notes-toolbar">
|
||||
<div className="pen-tool-group">
|
||||
<button
|
||||
className={`tool-button ${tool === 'pen' ? 'active' : ''}`}
|
||||
onClick={() => setTool('pen')}
|
||||
title="Stift"
|
||||
style={{ backgroundColor: tool === 'pen' ? penColor + '20' : undefined }}
|
||||
>
|
||||
<FiEdit3 style={{ color: tool === 'pen' ? penColor : undefined }} />
|
||||
</button>
|
||||
<button
|
||||
className="color-picker-button"
|
||||
onClick={() => setShowColorPicker(!showColorPicker)}
|
||||
title="Farbe wählen"
|
||||
style={{ backgroundColor: penColor }}
|
||||
>
|
||||
<FiChevronDown />
|
||||
</button>
|
||||
{showColorPicker && (
|
||||
<div className="color-picker-popover">
|
||||
<div className="color-grid">
|
||||
{colors.map((color) => (
|
||||
<button
|
||||
key={color}
|
||||
className={`color-option ${penColor === color ? 'active' : ''}`}
|
||||
style={{ backgroundColor: color }}
|
||||
onClick={() => {
|
||||
setPenColor(color)
|
||||
setShowColorPicker(false)
|
||||
}}
|
||||
title={`Farbe: ${color}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<button
|
||||
className={`tool-button ${tool === 'eraser' ? 'active' : ''}`}
|
||||
onClick={() => setTool('eraser')}
|
||||
title="Radiergummi"
|
||||
>
|
||||
<TbEraser />
|
||||
</button>
|
||||
|
||||
<button
|
||||
className="tool-button clear-button"
|
||||
onClick={clearCanvas}
|
||||
title="Alles löschen"
|
||||
>
|
||||
<FiTrash />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Canvas Container */}
|
||||
<div className="canvas-container">
|
||||
<canvas
|
||||
ref={canvasRef}
|
||||
className="drawing-canvas"
|
||||
onMouseDown={startDrawing}
|
||||
onMouseMove={draw}
|
||||
onMouseUp={stopDrawing}
|
||||
onMouseLeave={stopDrawing}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Notes
|
249
dashboard/src/renderer/src/pages/Notes.sass
Normal file
249
dashboard/src/renderer/src/pages/Notes.sass
Normal file
@@ -0,0 +1,249 @@
|
||||
// Notes Page - Drawing Canvas with Glassmorphism (Matching Search Page Structure)
|
||||
.notes-page
|
||||
padding: 2rem 0.75rem 0.75rem 0.75rem
|
||||
height: calc(100vh - 6rem)
|
||||
width: 100%
|
||||
|
||||
.notes-container
|
||||
position: relative
|
||||
width: 100%
|
||||
height: 100%
|
||||
backdrop-filter: blur(60px) saturate(200%)
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.2))
|
||||
border-radius: 28px
|
||||
border: 1px solid rgba(255, 255, 255, 0.5)
|
||||
box-shadow: 0 16px 64px rgba(0, 0, 0, 0.1), 0 8px 32px rgba(0, 0, 0, 0.05), inset 0 2px 0 rgba(255, 255, 255, 0.6), inset 0 -1px 0 rgba(0, 0, 0, 0.1)
|
||||
padding: 1.5rem
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1)
|
||||
overflow: hidden
|
||||
|
||||
&:hover
|
||||
backdrop-filter: blur(80px) saturate(220%)
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.3))
|
||||
box-shadow: 0 20px 80px rgba(0, 0, 0, 0.15), 0 10px 40px rgba(0, 0, 0, 0.08), inset 0 2px 0 rgba(255, 255, 255, 0.7)
|
||||
transform: translateY(-2px)
|
||||
|
||||
.notes-toolbar
|
||||
position: absolute
|
||||
bottom: 1rem
|
||||
left: 50%
|
||||
transform: translateX(-50%)
|
||||
z-index: 10
|
||||
display: flex
|
||||
align-items: center
|
||||
gap: 0.75rem
|
||||
padding: 0.75rem 1rem
|
||||
backdrop-filter: blur(40px) saturate(180%)
|
||||
background: rgba(255, 255, 255, 0.2)
|
||||
border-radius: 16px
|
||||
border: 1px solid rgba(255, 255, 255, 0.3)
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.4)
|
||||
|
||||
.pen-tool-group
|
||||
position: relative
|
||||
display: flex
|
||||
align-items: center
|
||||
gap: 0.25rem
|
||||
|
||||
.color-picker-button
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
width: 24px
|
||||
height: 44px
|
||||
border: none
|
||||
border-radius: 0 14px 14px 0
|
||||
border: 1px solid rgba(255, 255, 255, 0.4)
|
||||
border-left: none
|
||||
cursor: pointer
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1)
|
||||
font-size: 0.875rem
|
||||
color: white
|
||||
|
||||
&:hover
|
||||
transform: translateY(-2px)
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15)
|
||||
|
||||
.color-picker-popover
|
||||
position: absolute
|
||||
bottom: calc(100% + 0.5rem)
|
||||
left: 0
|
||||
backdrop-filter: blur(40px) saturate(180%)
|
||||
background: rgba(255, 255, 255, 0.25)
|
||||
border-radius: 16px
|
||||
border: 1px solid rgba(255, 255, 255, 0.3)
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.4)
|
||||
padding: 0.75rem
|
||||
z-index: 20
|
||||
|
||||
.color-grid
|
||||
display: grid
|
||||
grid-template-columns: repeat(5, 1fr)
|
||||
gap: 0.5rem
|
||||
|
||||
.color-option
|
||||
width: 32px
|
||||
height: 32px
|
||||
border: 2px solid rgba(255, 255, 255, 0.3)
|
||||
border-radius: 12px
|
||||
cursor: pointer
|
||||
transition: all 0.2s ease
|
||||
position: relative
|
||||
|
||||
&:hover
|
||||
transform: scale(1.1)
|
||||
border-color: rgba(255, 255, 255, 0.6)
|
||||
|
||||
&.active
|
||||
transform: scale(1.15)
|
||||
border-color: rgba(255, 255, 255, 0.8)
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2)
|
||||
|
||||
&::after
|
||||
content: '✓'
|
||||
position: absolute
|
||||
top: 50%
|
||||
left: 50%
|
||||
transform: translate(-50%, -50%)
|
||||
color: white
|
||||
font-size: 0.875rem
|
||||
font-weight: bold
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8)
|
||||
|
||||
.toolbar-section
|
||||
display: flex
|
||||
align-items: center
|
||||
gap: 0.75rem
|
||||
|
||||
.tool-button
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
width: 44px
|
||||
height: 44px
|
||||
border: none
|
||||
border-radius: 14px
|
||||
background: rgba(255, 255, 255, 0.3)
|
||||
backdrop-filter: blur(20px)
|
||||
border: 1px solid rgba(255, 255, 255, 0.4)
|
||||
color: rgba(50, 50, 50, 0.8)
|
||||
cursor: pointer
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1)
|
||||
font-size: 1.125rem
|
||||
|
||||
&:hover
|
||||
background: rgba(255, 255, 255, 0.5)
|
||||
color: rgba(50, 50, 50, 1)
|
||||
transform: translateY(-2px)
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15)
|
||||
|
||||
&.active
|
||||
background: rgba(255, 255, 255, 0.6)
|
||||
color: rgba(50, 50, 50, 1)
|
||||
border-color: rgba(255, 255, 255, 0.6)
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2)
|
||||
|
||||
&.clear-button
|
||||
background: rgba(239, 68, 68, 0.3)
|
||||
border-color: rgba(239, 68, 68, 0.4)
|
||||
color: rgba(50, 50, 50, 0.8)
|
||||
|
||||
&:hover
|
||||
background: rgba(239, 68, 68, 0.5)
|
||||
color: rgba(50, 50, 50, 1)
|
||||
transform: translateY(-2px)
|
||||
box-shadow: 0 8px 24px rgba(239, 68, 68, 0.2)
|
||||
|
||||
// Special styling for pen tool in group
|
||||
.pen-tool-group &:first-child
|
||||
border-radius: 14px 0 0 14px
|
||||
border-right: none
|
||||
|
||||
.canvas-container
|
||||
width: 100%
|
||||
height: 100%
|
||||
border-radius: 20px
|
||||
background: rgba(255, 255, 255, 0.9)
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5)
|
||||
overflow: hidden
|
||||
|
||||
.drawing-canvas
|
||||
width: 100%
|
||||
height: 100%
|
||||
cursor: crosshair
|
||||
display: block
|
||||
background: #ffffff
|
||||
border-radius: 20px
|
||||
|
||||
&.eraser-mode
|
||||
cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><circle cx="10" cy="10" r="8" fill="none" stroke="black" stroke-width="2"/></svg>') 10 10, auto
|
||||
|
||||
// Responsive Design
|
||||
@media (max-width: 768px)
|
||||
.notes-page
|
||||
padding: 1.5rem 0.5rem 0.5rem 0.5rem
|
||||
|
||||
.notes-container
|
||||
border-radius: 24px
|
||||
padding: 1.25rem
|
||||
|
||||
.canvas-container
|
||||
border-radius: 16px
|
||||
|
||||
.drawing-canvas
|
||||
border-radius: 16px
|
||||
|
||||
.notes-toolbar
|
||||
bottom: 0.75rem
|
||||
padding: 0.625rem 0.875rem
|
||||
gap: 0.625rem
|
||||
|
||||
.tool-button
|
||||
width: 40px
|
||||
height: 40px
|
||||
font-size: 1rem
|
||||
|
||||
.color-picker-button
|
||||
width: 20px
|
||||
height: 40px
|
||||
|
||||
.color-option
|
||||
width: 28px
|
||||
height: 28px
|
||||
|
||||
@media (max-width: 480px)
|
||||
.notes-page
|
||||
padding: 1rem 0.375rem 0.375rem 0.375rem
|
||||
|
||||
.notes-container
|
||||
border-radius: 20px
|
||||
padding: 1rem
|
||||
|
||||
.canvas-container
|
||||
border-radius: 12px
|
||||
|
||||
.drawing-canvas
|
||||
border-radius: 12px
|
||||
|
||||
.notes-toolbar
|
||||
bottom: 0.5rem
|
||||
padding: 0.5rem 0.75rem
|
||||
gap: 0.5rem
|
||||
border-radius: 14px
|
||||
|
||||
.tool-button
|
||||
width: 36px
|
||||
height: 36px
|
||||
border-radius: 12px
|
||||
font-size: 0.875rem
|
||||
|
||||
.color-picker-button
|
||||
width: 18px
|
||||
height: 36px
|
||||
|
||||
.color-option
|
||||
width: 24px
|
||||
height: 24px
|
||||
|
||||
.color-grid
|
||||
grid-template-columns: repeat(4, 1fr)
|
20
dashboard/src/renderer/src/pages/Search.jsx
Normal file
20
dashboard/src/renderer/src/pages/Search.jsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import './Search.sass'
|
||||
|
||||
const Search = () => {
|
||||
return (
|
||||
<div className="search-page">
|
||||
<div className="search-container">
|
||||
<div className="google-embed-container">
|
||||
<iframe
|
||||
src="https://www.google.com/search?igu=1"
|
||||
className="google-iframe"
|
||||
title="Google Search"
|
||||
allow="microphone"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Search
|
58
dashboard/src/renderer/src/pages/Search.sass
Normal file
58
dashboard/src/renderer/src/pages/Search.sass
Normal file
@@ -0,0 +1,58 @@
|
||||
// Search Page - Full Screen Glassmorphism Google Embed
|
||||
.search-page
|
||||
padding: 2rem 0.75rem 0.75rem 0.75rem
|
||||
height: calc(100vh - 6rem)
|
||||
width: 100%
|
||||
|
||||
.search-container
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
.google-embed-container
|
||||
width: 100%
|
||||
height: 100%
|
||||
backdrop-filter: blur(60px) saturate(200%)
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.2))
|
||||
border-radius: 28px
|
||||
border: 1px solid rgba(255, 255, 255, 0.5)
|
||||
box-shadow: 0 16px 64px rgba(0, 0, 0, 0.1), 0 8px 32px rgba(0, 0, 0, 0.05), inset 0 2px 0 rgba(255, 255, 255, 0.6), inset 0 -1px 0 rgba(0, 0, 0, 0.1)
|
||||
padding: 1.5rem
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1)
|
||||
overflow: hidden
|
||||
|
||||
&:hover
|
||||
backdrop-filter: blur(80px) saturate(220%)
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.3))
|
||||
box-shadow: 0 20px 80px rgba(0, 0, 0, 0.15), 0 10px 40px rgba(0, 0, 0, 0.08), inset 0 2px 0 rgba(255, 255, 255, 0.7)
|
||||
transform: translateY(-2px)
|
||||
|
||||
.google-iframe
|
||||
width: 100%
|
||||
height: 100%
|
||||
border: none
|
||||
border-radius: 20px
|
||||
background: rgba(255, 255, 255, 0.9)
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5)
|
||||
|
||||
// Responsive Design
|
||||
@media (max-width: 768px)
|
||||
.search-page
|
||||
padding: 1.5rem 0.5rem 0.5rem 0.5rem
|
||||
|
||||
.google-embed-container
|
||||
border-radius: 24px
|
||||
padding: 1.25rem
|
||||
|
||||
.google-iframe
|
||||
border-radius: 16px
|
||||
|
||||
@media (max-width: 480px)
|
||||
.search-page
|
||||
padding: 1rem 0.375rem 0.375rem 0.375rem
|
||||
|
||||
.google-embed-container
|
||||
border-radius: 20px
|
||||
padding: 1rem
|
||||
|
||||
.google-iframe
|
||||
border-radius: 12px
|
9
dashboard/src/renderer/src/pages/Shopping.jsx
Normal file
9
dashboard/src/renderer/src/pages/Shopping.jsx
Normal file
@@ -0,0 +1,9 @@
|
||||
const Shopping = () => {
|
||||
return (
|
||||
<div>
|
||||
<h1>Einkaufen</h1>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Shopping
|
697
dashboard/src/renderer/src/pages/pages.sass
Normal file
697
dashboard/src/renderer/src/pages/pages.sass
Normal file
@@ -0,0 +1,697 @@
|
||||
// Pages Styles - Light Mode with Glass Effects
|
||||
|
||||
// Common page container
|
||||
.page-container
|
||||
padding: 2rem
|
||||
min-height: calc(100vh - 6rem)
|
||||
overflow-y: auto
|
||||
|
||||
// Calendar Styles
|
||||
.calendar-container
|
||||
max-width: 1200px
|
||||
margin: 0 auto
|
||||
|
||||
.calendar-header
|
||||
display: flex
|
||||
justify-content: space-between
|
||||
align-items: center
|
||||
margin-bottom: 2rem
|
||||
flex-wrap: wrap
|
||||
gap: 1rem
|
||||
|
||||
h1
|
||||
font-size: 2rem
|
||||
font-weight: 700
|
||||
color: #1e293b
|
||||
margin: 0
|
||||
|
||||
.calendar-nav
|
||||
display: flex
|
||||
align-items: center
|
||||
gap: 1rem
|
||||
background: rgba(255, 255, 255, 0.3)
|
||||
padding: 0.75rem 1.5rem
|
||||
border-radius: 16px
|
||||
backdrop-filter: blur(20px)
|
||||
border: 1px solid rgba(255, 255, 255, 0.4)
|
||||
|
||||
h2
|
||||
font-size: 1.25rem
|
||||
font-weight: 600
|
||||
color: #1e293b
|
||||
margin: 0
|
||||
min-width: 200px
|
||||
text-align: center
|
||||
|
||||
.nav-btn, .add-event-btn
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.2))
|
||||
border: 1px solid rgba(255, 255, 255, 0.5)
|
||||
border-radius: 12px
|
||||
padding: 0.75rem 1rem
|
||||
color: #475569
|
||||
cursor: pointer
|
||||
transition: all 0.3s ease
|
||||
backdrop-filter: blur(20px)
|
||||
font-weight: 500
|
||||
|
||||
&:hover
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 0.4))
|
||||
transform: translateY(-2px)
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1)
|
||||
|
||||
.add-event-btn
|
||||
display: flex
|
||||
align-items: center
|
||||
gap: 0.5rem
|
||||
font-size: 0.875rem
|
||||
|
||||
.calendar-grid
|
||||
background: rgba(255, 255, 255, 0.25)
|
||||
border-radius: 24px
|
||||
padding: 2rem
|
||||
margin-bottom: 2rem
|
||||
backdrop-filter: blur(40px)
|
||||
border: 1px solid rgba(255, 255, 255, 0.3)
|
||||
box-shadow: 0 16px 64px rgba(0, 0, 0, 0.1)
|
||||
|
||||
.calendar-days-header
|
||||
display: grid
|
||||
grid-template-columns: repeat(7, 1fr)
|
||||
gap: 1rem
|
||||
margin-bottom: 1rem
|
||||
|
||||
.day-header
|
||||
text-align: center
|
||||
font-weight: 600
|
||||
color: #475569
|
||||
padding: 0.75rem
|
||||
|
||||
.calendar-days
|
||||
display: grid
|
||||
grid-template-columns: repeat(7, 1fr)
|
||||
gap: 1rem
|
||||
|
||||
.calendar-day
|
||||
aspect-ratio: 1
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
border-radius: 12px
|
||||
cursor: pointer
|
||||
font-weight: 500
|
||||
transition: all 0.3s ease
|
||||
|
||||
&.empty
|
||||
cursor: default
|
||||
|
||||
&.active
|
||||
background: rgba(255, 255, 255, 0.2)
|
||||
color: #1e293b
|
||||
|
||||
&:hover
|
||||
background: rgba(255, 255, 255, 0.4)
|
||||
transform: scale(1.05)
|
||||
|
||||
&.today
|
||||
background: linear-gradient(135deg, rgba(59, 130, 246, 0.3), rgba(37, 99, 235, 0.3))
|
||||
color: white
|
||||
font-weight: 700
|
||||
|
||||
&.selected
|
||||
background: linear-gradient(135deg, rgba(168, 85, 247, 0.3), rgba(147, 51, 234, 0.3))
|
||||
color: white
|
||||
|
||||
// Shopping Styles
|
||||
.shopping-container
|
||||
max-width: 800px
|
||||
margin: 0 auto
|
||||
|
||||
.shopping-header
|
||||
display: flex
|
||||
justify-content: space-between
|
||||
align-items: center
|
||||
margin-bottom: 2rem
|
||||
|
||||
h1
|
||||
display: flex
|
||||
align-items: center
|
||||
gap: 0.75rem
|
||||
font-size: 2rem
|
||||
font-weight: 700
|
||||
color: #1e293b
|
||||
margin: 0
|
||||
|
||||
.shopping-stats
|
||||
display: flex
|
||||
gap: 1rem
|
||||
|
||||
span
|
||||
background: rgba(255, 255, 255, 0.3)
|
||||
padding: 0.5rem 1rem
|
||||
border-radius: 12px
|
||||
font-size: 0.875rem
|
||||
font-weight: 500
|
||||
color: #475569
|
||||
|
||||
.add-item-form
|
||||
background: rgba(255, 255, 255, 0.25)
|
||||
border-radius: 20px
|
||||
padding: 1.5rem
|
||||
margin-bottom: 2rem
|
||||
backdrop-filter: blur(40px)
|
||||
border: 1px solid rgba(255, 255, 255, 0.3)
|
||||
|
||||
.input-group
|
||||
display: flex
|
||||
gap: 1rem
|
||||
|
||||
input
|
||||
flex: 1
|
||||
padding: 0.75rem 1rem
|
||||
border: 1px solid rgba(255, 255, 255, 0.4)
|
||||
border-radius: 12px
|
||||
background: rgba(255, 255, 255, 0.3)
|
||||
color: #1e293b
|
||||
font-size: 1rem
|
||||
backdrop-filter: blur(20px)
|
||||
|
||||
&::placeholder
|
||||
color: rgba(30, 41, 59, 0.6)
|
||||
|
||||
&:focus
|
||||
outline: none
|
||||
border-color: rgba(59, 130, 246, 0.5)
|
||||
background: rgba(255, 255, 255, 0.4)
|
||||
|
||||
.add-btn
|
||||
background: linear-gradient(135deg, rgba(16, 185, 129, 0.3), rgba(5, 150, 105, 0.3))
|
||||
border: 1px solid rgba(255, 255, 255, 0.4)
|
||||
border-radius: 12px
|
||||
padding: 0.75rem 1rem
|
||||
color: white
|
||||
cursor: pointer
|
||||
transition: all 0.3s ease
|
||||
|
||||
&:hover
|
||||
background: linear-gradient(135deg, rgba(16, 185, 129, 0.4), rgba(5, 150, 105, 0.4))
|
||||
transform: translateY(-2px)
|
||||
|
||||
.shopping-section
|
||||
margin-bottom: 2rem
|
||||
|
||||
h3
|
||||
font-size: 1.25rem
|
||||
font-weight: 600
|
||||
color: #1e293b
|
||||
margin-bottom: 1rem
|
||||
|
||||
.items-list
|
||||
background: rgba(255, 255, 255, 0.25)
|
||||
border-radius: 20px
|
||||
padding: 1.5rem
|
||||
backdrop-filter: blur(40px)
|
||||
border: 1px solid rgba(255, 255, 255, 0.3)
|
||||
|
||||
.shopping-item
|
||||
display: flex
|
||||
align-items: center
|
||||
gap: 1rem
|
||||
padding: 1rem 0
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.2)
|
||||
|
||||
&:last-child
|
||||
border-bottom: none
|
||||
|
||||
&.completed
|
||||
opacity: 0.6
|
||||
|
||||
.item-name
|
||||
text-decoration: line-through
|
||||
|
||||
.check-btn
|
||||
width: 32px
|
||||
height: 32px
|
||||
border-radius: 50%
|
||||
border: 2px solid rgba(16, 185, 129, 0.5)
|
||||
background: transparent
|
||||
color: transparent
|
||||
cursor: pointer
|
||||
transition: all 0.3s ease
|
||||
|
||||
&.checked
|
||||
background: linear-gradient(135deg, rgba(16, 185, 129, 0.8), rgba(5, 150, 105, 0.8))
|
||||
color: white
|
||||
|
||||
&:hover
|
||||
border-color: rgba(16, 185, 129, 0.8)
|
||||
background: rgba(16, 185, 129, 0.1)
|
||||
|
||||
.item-details
|
||||
flex: 1
|
||||
display: flex
|
||||
flex-direction: column
|
||||
gap: 0.25rem
|
||||
|
||||
.item-name
|
||||
font-weight: 500
|
||||
color: #1e293b
|
||||
|
||||
.item-quantity, .item-category
|
||||
font-size: 0.875rem
|
||||
color: #64748b
|
||||
|
||||
.delete-btn
|
||||
background: transparent
|
||||
border: none
|
||||
color: #ef4444
|
||||
cursor: pointer
|
||||
padding: 0.5rem
|
||||
border-radius: 8px
|
||||
transition: all 0.3s ease
|
||||
|
||||
&:hover
|
||||
background: rgba(239, 68, 68, 0.1)
|
||||
color: #dc2626
|
||||
|
||||
// Notes Styles
|
||||
.notes-container
|
||||
max-width: 1200px
|
||||
margin: 0 auto
|
||||
|
||||
.notes-header
|
||||
display: flex
|
||||
justify-content: space-between
|
||||
align-items: center
|
||||
margin-bottom: 2rem
|
||||
|
||||
h1
|
||||
font-size: 2rem
|
||||
font-weight: 700
|
||||
color: #1e293b
|
||||
margin: 0
|
||||
|
||||
.add-note-btn
|
||||
display: flex
|
||||
align-items: center
|
||||
gap: 0.5rem
|
||||
background: linear-gradient(135deg, rgba(139, 92, 246, 0.3), rgba(124, 58, 237, 0.3))
|
||||
border: 1px solid rgba(255, 255, 255, 0.4)
|
||||
border-radius: 12px
|
||||
padding: 0.75rem 1.5rem
|
||||
color: white
|
||||
cursor: pointer
|
||||
font-weight: 500
|
||||
transition: all 0.3s ease
|
||||
|
||||
&:hover
|
||||
background: linear-gradient(135deg, rgba(139, 92, 246, 0.4), rgba(124, 58, 237, 0.4))
|
||||
transform: translateY(-2px)
|
||||
|
||||
.note-editor
|
||||
background: rgba(255, 255, 255, 0.25)
|
||||
border-radius: 20px
|
||||
padding: 2rem
|
||||
margin-bottom: 2rem
|
||||
backdrop-filter: blur(40px)
|
||||
border: 1px solid rgba(255, 255, 255, 0.3)
|
||||
|
||||
.editor-header
|
||||
display: flex
|
||||
justify-content: space-between
|
||||
align-items: center
|
||||
margin-bottom: 1rem
|
||||
gap: 1rem
|
||||
|
||||
.title-input
|
||||
flex: 1
|
||||
padding: 0.75rem 1rem
|
||||
border: 1px solid rgba(255, 255, 255, 0.4)
|
||||
border-radius: 12px
|
||||
background: rgba(255, 255, 255, 0.3)
|
||||
color: #1e293b
|
||||
font-size: 1.125rem
|
||||
font-weight: 600
|
||||
|
||||
&:focus
|
||||
outline: none
|
||||
border-color: rgba(59, 130, 246, 0.5)
|
||||
|
||||
.color-picker
|
||||
display: flex
|
||||
gap: 0.5rem
|
||||
|
||||
.color-option
|
||||
width: 32px
|
||||
height: 32px
|
||||
border-radius: 50%
|
||||
border: 2px solid transparent
|
||||
cursor: pointer
|
||||
transition: all 0.3s ease
|
||||
|
||||
&.selected
|
||||
border-color: rgba(255, 255, 255, 0.8)
|
||||
transform: scale(1.1)
|
||||
|
||||
.content-input
|
||||
width: 100%
|
||||
padding: 1rem
|
||||
border: 1px solid rgba(255, 255, 255, 0.4)
|
||||
border-radius: 12px
|
||||
background: rgba(255, 255, 255, 0.3)
|
||||
color: #1e293b
|
||||
font-size: 1rem
|
||||
line-height: 1.6
|
||||
resize: vertical
|
||||
margin-bottom: 1rem
|
||||
|
||||
&:focus
|
||||
outline: none
|
||||
border-color: rgba(59, 130, 246, 0.5)
|
||||
|
||||
.editor-actions
|
||||
display: flex
|
||||
gap: 1rem
|
||||
|
||||
.save-btn, .cancel-btn
|
||||
display: flex
|
||||
align-items: center
|
||||
gap: 0.5rem
|
||||
padding: 0.75rem 1.5rem
|
||||
border-radius: 12px
|
||||
cursor: pointer
|
||||
font-weight: 500
|
||||
transition: all 0.3s ease
|
||||
|
||||
.save-btn
|
||||
background: linear-gradient(135deg, rgba(16, 185, 129, 0.3), rgba(5, 150, 105, 0.3))
|
||||
border: 1px solid rgba(255, 255, 255, 0.4)
|
||||
color: white
|
||||
|
||||
&:hover
|
||||
background: linear-gradient(135deg, rgba(16, 185, 129, 0.4), rgba(5, 150, 105, 0.4))
|
||||
|
||||
.cancel-btn
|
||||
background: rgba(255, 255, 255, 0.3)
|
||||
border: 1px solid rgba(255, 255, 255, 0.4)
|
||||
color: #475569
|
||||
|
||||
&:hover
|
||||
background: rgba(255, 255, 255, 0.4)
|
||||
|
||||
.notes-grid
|
||||
display: grid
|
||||
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr))
|
||||
gap: 1.5rem
|
||||
|
||||
.note-card
|
||||
background: rgba(255, 255, 255, 0.25)
|
||||
border-radius: 20px
|
||||
padding: 1.5rem
|
||||
backdrop-filter: blur(40px)
|
||||
border: 1px solid rgba(255, 255, 255, 0.3)
|
||||
border-left: 4px solid #3b82f6
|
||||
transition: all 0.3s ease
|
||||
|
||||
&:hover
|
||||
transform: translateY(-4px)
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15)
|
||||
|
||||
.note-header
|
||||
display: flex
|
||||
justify-content: space-between
|
||||
align-items: flex-start
|
||||
margin-bottom: 1rem
|
||||
|
||||
h3
|
||||
font-size: 1.125rem
|
||||
font-weight: 600
|
||||
color: #1e293b
|
||||
margin: 0
|
||||
|
||||
.note-actions
|
||||
display: flex
|
||||
gap: 0.5rem
|
||||
|
||||
button
|
||||
background: transparent
|
||||
border: none
|
||||
color: #64748b
|
||||
cursor: pointer
|
||||
padding: 0.25rem
|
||||
border-radius: 6px
|
||||
transition: all 0.3s ease
|
||||
|
||||
&:hover
|
||||
background: rgba(100, 116, 139, 0.1)
|
||||
color: #475569
|
||||
|
||||
.note-content
|
||||
margin-bottom: 1rem
|
||||
|
||||
p
|
||||
color: #475569
|
||||
line-height: 1.6
|
||||
margin-bottom: 0.5rem
|
||||
|
||||
&:last-child
|
||||
margin-bottom: 0
|
||||
|
||||
.note-footer
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.2)
|
||||
padding-top: 1rem
|
||||
|
||||
.note-date
|
||||
font-size: 0.875rem
|
||||
color: #64748b
|
||||
|
||||
// Search Styles
|
||||
.search-container
|
||||
max-width: 800px
|
||||
margin: 0 auto
|
||||
|
||||
.search-header
|
||||
margin-bottom: 2rem
|
||||
|
||||
h1
|
||||
font-size: 2rem
|
||||
font-weight: 700
|
||||
color: #1e293b
|
||||
margin-bottom: 1.5rem
|
||||
|
||||
.search-input-container
|
||||
position: relative
|
||||
background: rgba(255, 255, 255, 0.25)
|
||||
border-radius: 20px
|
||||
padding: 1.5rem
|
||||
backdrop-filter: blur(40px)
|
||||
border: 1px solid rgba(255, 255, 255, 0.3)
|
||||
|
||||
.search-icon
|
||||
position: absolute
|
||||
left: 2.5rem
|
||||
top: 50%
|
||||
transform: translateY(-50%)
|
||||
color: #64748b
|
||||
font-size: 1.25rem
|
||||
|
||||
.search-input
|
||||
width: 100%
|
||||
padding: 1rem 1rem 1rem 3rem
|
||||
border: none
|
||||
background: transparent
|
||||
color: #1e293b
|
||||
font-size: 1.125rem
|
||||
outline: none
|
||||
|
||||
&::placeholder
|
||||
color: rgba(30, 41, 59, 0.6)
|
||||
|
||||
.search-suggestions
|
||||
display: grid
|
||||
grid-template-columns: 1fr 1fr
|
||||
gap: 2rem
|
||||
|
||||
.recent-searches, .quick-actions
|
||||
background: rgba(255, 255, 255, 0.25)
|
||||
border-radius: 20px
|
||||
padding: 1.5rem
|
||||
backdrop-filter: blur(40px)
|
||||
border: 1px solid rgba(255, 255, 255, 0.3)
|
||||
|
||||
h3
|
||||
font-size: 1.125rem
|
||||
font-weight: 600
|
||||
color: #1e293b
|
||||
margin-bottom: 1rem
|
||||
|
||||
.recent-list
|
||||
display: flex
|
||||
flex-direction: column
|
||||
gap: 0.75rem
|
||||
|
||||
.recent-item
|
||||
display: flex
|
||||
align-items: center
|
||||
gap: 0.75rem
|
||||
padding: 0.75rem 1rem
|
||||
background: rgba(255, 255, 255, 0.3)
|
||||
border: 1px solid rgba(255, 255, 255, 0.4)
|
||||
border-radius: 12px
|
||||
color: #475569
|
||||
cursor: pointer
|
||||
transition: all 0.3s ease
|
||||
|
||||
&:hover
|
||||
background: rgba(255, 255, 255, 0.4)
|
||||
transform: translateX(4px)
|
||||
|
||||
.actions-grid
|
||||
display: grid
|
||||
grid-template-columns: 1fr 1fr
|
||||
gap: 1rem
|
||||
|
||||
.quick-action
|
||||
display: flex
|
||||
flex-direction: column
|
||||
align-items: center
|
||||
gap: 0.5rem
|
||||
padding: 1rem
|
||||
background: rgba(255, 255, 255, 0.3)
|
||||
border: 1px solid rgba(255, 255, 255, 0.4)
|
||||
border-radius: 12px
|
||||
color: #475569
|
||||
cursor: pointer
|
||||
transition: all 0.3s ease
|
||||
text-align: center
|
||||
|
||||
&:hover
|
||||
background: rgba(255, 255, 255, 0.4)
|
||||
transform: translateY(-2px)
|
||||
|
||||
svg
|
||||
font-size: 1.5rem
|
||||
|
||||
span
|
||||
font-size: 0.875rem
|
||||
font-weight: 500
|
||||
|
||||
.search-results
|
||||
.results-header
|
||||
margin-bottom: 1.5rem
|
||||
|
||||
h3
|
||||
font-size: 1.125rem
|
||||
font-weight: 600
|
||||
color: #1e293b
|
||||
|
||||
.results-list
|
||||
display: flex
|
||||
flex-direction: column
|
||||
gap: 1rem
|
||||
|
||||
.result-item
|
||||
display: flex
|
||||
align-items: flex-start
|
||||
gap: 1rem
|
||||
padding: 1.5rem
|
||||
background: rgba(255, 255, 255, 0.25)
|
||||
border-radius: 16px
|
||||
backdrop-filter: blur(40px)
|
||||
border: 1px solid rgba(255, 255, 255, 0.3)
|
||||
cursor: pointer
|
||||
transition: all 0.3s ease
|
||||
|
||||
&:hover
|
||||
transform: translateY(-2px)
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1)
|
||||
|
||||
.result-icon
|
||||
width: 48px
|
||||
height: 48px
|
||||
border-radius: 12px
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
color: white
|
||||
font-size: 1.25rem
|
||||
|
||||
.result-content
|
||||
flex: 1
|
||||
|
||||
.result-header
|
||||
display: flex
|
||||
justify-content: space-between
|
||||
align-items: center
|
||||
margin-bottom: 0.5rem
|
||||
|
||||
h4
|
||||
font-size: 1.125rem
|
||||
font-weight: 600
|
||||
color: #1e293b
|
||||
margin: 0
|
||||
|
||||
.result-type
|
||||
font-size: 0.875rem
|
||||
font-weight: 500
|
||||
|
||||
.result-description
|
||||
color: #475569
|
||||
line-height: 1.5
|
||||
margin-bottom: 0.5rem
|
||||
|
||||
.result-date
|
||||
font-size: 0.875rem
|
||||
color: #64748b
|
||||
|
||||
.no-results
|
||||
text-align: center
|
||||
padding: 3rem
|
||||
color: #64748b
|
||||
|
||||
svg
|
||||
margin-bottom: 1rem
|
||||
opacity: 0.5
|
||||
|
||||
h3
|
||||
font-size: 1.25rem
|
||||
font-weight: 600
|
||||
margin-bottom: 0.5rem
|
||||
|
||||
p
|
||||
font-size: 1rem
|
||||
|
||||
// Responsive Design
|
||||
@media (max-width: 768px)
|
||||
.page-container
|
||||
padding: 1.5rem
|
||||
|
||||
.calendar-header, .shopping-header, .notes-header
|
||||
flex-direction: column
|
||||
align-items: flex-start
|
||||
gap: 1rem
|
||||
|
||||
.search-suggestions
|
||||
grid-template-columns: 1fr
|
||||
|
||||
.actions-grid
|
||||
grid-template-columns: 1fr
|
||||
|
||||
.notes-grid
|
||||
grid-template-columns: 1fr
|
||||
|
||||
.editor-header
|
||||
flex-direction: column
|
||||
align-items: stretch
|
||||
|
||||
@media (max-width: 480px)
|
||||
.page-container
|
||||
padding: 1rem
|
||||
|
||||
.calendar-days
|
||||
gap: 0.5rem
|
||||
|
||||
.input-group
|
||||
flex-direction: column
|
||||
|
||||
.result-item
|
||||
padding: 1rem
|
Reference in New Issue
Block a user