Improve mobile calendar
This commit is contained in:
@@ -121,12 +121,19 @@ const App = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const formatDate = (dateString) => {
|
const formatDate = (dateString) => {
|
||||||
const date = new Date(dateString);
|
// Parse the date string ensuring we don't have timezone issues
|
||||||
return date.toLocaleDateString('de-DE', {
|
const dateParts = dateString.split('-');
|
||||||
weekday: 'short',
|
const date = new Date(parseInt(dateParts[0]), parseInt(dateParts[1]) - 1, parseInt(dateParts[2]));
|
||||||
day: '2-digit',
|
const today = new Date();
|
||||||
month: '2-digit'
|
today.setHours(0, 0, 0, 0); // Reset time for comparison
|
||||||
});
|
|
||||||
|
return {
|
||||||
|
dayNumber: date.getDate(),
|
||||||
|
dayName: date.toLocaleDateString('de-DE', { weekday: 'long' }),
|
||||||
|
monthYear: date.toLocaleDateString('de-DE', { month: 'long', year: 'numeric' }),
|
||||||
|
isToday: date.getTime() === today.getTime(),
|
||||||
|
isThisMonth: date.getMonth() === currentDate.getMonth() && date.getFullYear() === currentDate.getFullYear()
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const getCurrentMonthYear = () => {
|
const getCurrentMonthYear = () => {
|
||||||
@@ -320,29 +327,43 @@ const App = () => {
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="events-list">
|
<div className="events-list">
|
||||||
{Object.entries(groupedEvents).map(([date, dayEvents]) => (
|
{Object.entries(groupedEvents).map(([date, dayEvents]) => {
|
||||||
<div key={date} className="day-section">
|
const dateInfo = formatDate(date);
|
||||||
<div className="day-header">
|
return (
|
||||||
<h3>{formatDate(date)}</h3>
|
<div key={date} className={`day-section ${dateInfo.isToday ? 'today' : ''} ${!dateInfo.isThisMonth ? 'other-month' : ''}`}>
|
||||||
<span className="event-count">{dayEvents.length} Termin{dayEvents.length !== 1 ? 'e' : ''}</span>
|
<div className="day-header">
|
||||||
|
<div className="day-info">
|
||||||
|
<div className="day-number">{dateInfo.dayNumber}</div>
|
||||||
|
<div className="day-details">
|
||||||
|
<div className="day-name">{dateInfo.dayName}</div>
|
||||||
|
{!dateInfo.isThisMonth && (
|
||||||
|
<div className="month-indicator">{dateInfo.monthYear}</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="event-count">
|
||||||
|
<span className="count-number">{dayEvents.length}</span>
|
||||||
|
<span className="count-label">Termin{dayEvents.length !== 1 ? 'e' : ''}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="day-events">
|
||||||
|
{dayEvents.map(event => (
|
||||||
|
<CalendarEvent
|
||||||
|
key={event.id}
|
||||||
|
event={event}
|
||||||
|
onUpdate={handleUpdateEvent}
|
||||||
|
onDelete={handleDeleteEvent}
|
||||||
|
editingEvent={editingEvent}
|
||||||
|
setEditingEvent={setEditingEvent}
|
||||||
|
userColor={getUserColor(event.user)}
|
||||||
|
showUser={viewType === 'family'}
|
||||||
|
users={users}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="day-events">
|
);
|
||||||
{dayEvents.map(event => (
|
})}
|
||||||
<CalendarEvent
|
|
||||||
key={event.id}
|
|
||||||
event={event}
|
|
||||||
onUpdate={handleUpdateEvent}
|
|
||||||
onDelete={handleDeleteEvent}
|
|
||||||
editingEvent={editingEvent}
|
|
||||||
setEditingEvent={setEditingEvent}
|
|
||||||
userColor={getUserColor(event.user)}
|
|
||||||
showUser={viewType === 'family'}
|
|
||||||
users={users}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@@ -51,13 +51,15 @@ body
|
|||||||
|
|
||||||
// Header
|
// Header
|
||||||
.header
|
.header
|
||||||
background: var(--surface-color)
|
background: linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(248, 249, 250, 0.98) 100%)
|
||||||
border-bottom: 1px solid var(--border-color)
|
backdrop-filter: blur(20px)
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.2)
|
||||||
padding: var(--spacing-sm) var(--spacing-md)
|
padding: var(--spacing-sm) var(--spacing-md)
|
||||||
position: sticky
|
position: sticky
|
||||||
top: 0
|
top: 0
|
||||||
z-index: 100
|
z-index: 100
|
||||||
box-shadow: var(--shadow-light)
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1)
|
||||||
|
border-radius: 0 0 var(--border-radius) var(--border-radius)
|
||||||
|
|
||||||
.header-content
|
.header-content
|
||||||
display: flex
|
display: flex
|
||||||
@@ -68,16 +70,18 @@ body
|
|||||||
|
|
||||||
h1
|
h1
|
||||||
font-size: 1.5rem
|
font-size: 1.5rem
|
||||||
font-weight: 600
|
font-weight: 700
|
||||||
color: var(--text-primary)
|
color: var(--text-primary)
|
||||||
display: flex
|
display: flex
|
||||||
align-items: center
|
align-items: center
|
||||||
gap: var(--spacing-sm)
|
gap: var(--spacing-sm)
|
||||||
justify-content: center
|
justify-content: center
|
||||||
|
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1)
|
||||||
|
|
||||||
svg
|
svg
|
||||||
color: var(--primary-color)
|
color: var(--primary-color)
|
||||||
font-size: 1.25rem
|
font-size: 1.25rem
|
||||||
|
filter: drop-shadow(0 2px 4px rgba(0, 122, 255, 0.3))
|
||||||
|
|
||||||
.month-navigation
|
.month-navigation
|
||||||
display: flex
|
display: flex
|
||||||
@@ -92,21 +96,27 @@ body
|
|||||||
margin: 0
|
margin: 0
|
||||||
min-width: 140px
|
min-width: 140px
|
||||||
text-align: center
|
text-align: center
|
||||||
|
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1)
|
||||||
|
|
||||||
.btn-icon
|
.btn-icon
|
||||||
width: 40px
|
width: 44px
|
||||||
height: 40px
|
height: 44px
|
||||||
border-radius: 50%
|
border-radius: 50%
|
||||||
display: flex
|
display: flex
|
||||||
align-items: center
|
align-items: center
|
||||||
justify-content: center
|
justify-content: center
|
||||||
background: var(--background-color)
|
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%)
|
||||||
border: 1px solid var(--border-color)
|
border: none
|
||||||
|
color: white
|
||||||
|
transition: all 0.3s ease
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 122, 255, 0.3)
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
background: var(--primary-color)
|
transform: translateY(-2px) scale(1.05)
|
||||||
color: white
|
box-shadow: 0 6px 20px rgba(0, 122, 255, 0.4)
|
||||||
border-color: var(--primary-color)
|
|
||||||
|
&:active
|
||||||
|
transform: translateY(0) scale(0.95)
|
||||||
|
|
||||||
.view-controls
|
.view-controls
|
||||||
display: flex
|
display: flex
|
||||||
@@ -114,32 +124,56 @@ body
|
|||||||
justify-content: space-between
|
justify-content: space-between
|
||||||
gap: var(--spacing-md)
|
gap: var(--spacing-md)
|
||||||
padding-top: var(--spacing-sm)
|
padding-top: var(--spacing-sm)
|
||||||
border-top: 1px solid var(--border-color)
|
border-top: 1px solid rgba(255, 255, 255, 0.3)
|
||||||
|
|
||||||
.view-type-toggle
|
.view-type-toggle
|
||||||
display: flex
|
display: flex
|
||||||
gap: var(--spacing-xs)
|
gap: 4px
|
||||||
background: var(--background-color)
|
background: rgba(255, 255, 255, 0.7)
|
||||||
padding: 4px
|
padding: 4px
|
||||||
border-radius: var(--border-radius-small)
|
border-radius: var(--border-radius)
|
||||||
|
backdrop-filter: blur(10px)
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.3)
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1)
|
||||||
|
|
||||||
.btn
|
.btn
|
||||||
padding: var(--spacing-xs) var(--spacing-md)
|
padding: var(--spacing-xs) var(--spacing-md)
|
||||||
border-radius: var(--border-radius-small)
|
border-radius: var(--border-radius-small)
|
||||||
font-size: 0.875rem
|
font-size: 0.875rem
|
||||||
|
font-weight: 600
|
||||||
|
transition: all 0.3s ease
|
||||||
|
border: none
|
||||||
|
|
||||||
|
&.btn-primary
|
||||||
|
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%)
|
||||||
|
color: white
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 122, 255, 0.3)
|
||||||
|
|
||||||
|
&.btn-secondary
|
||||||
|
background: transparent
|
||||||
|
color: var(--text-secondary)
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background: rgba(255, 255, 255, 0.5)
|
||||||
|
color: var(--text-primary)
|
||||||
|
|
||||||
.user-select
|
.user-select
|
||||||
padding: var(--spacing-sm)
|
padding: var(--spacing-sm) var(--spacing-md)
|
||||||
border: 1px solid var(--border-color)
|
border: 1px solid rgba(255, 255, 255, 0.3)
|
||||||
border-radius: var(--border-radius-small)
|
border-radius: var(--border-radius)
|
||||||
background: var(--surface-color)
|
background: rgba(255, 255, 255, 0.7)
|
||||||
|
backdrop-filter: blur(10px)
|
||||||
font-size: 0.875rem
|
font-size: 0.875rem
|
||||||
|
font-weight: 500
|
||||||
min-width: 120px
|
min-width: 120px
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1)
|
||||||
|
transition: all 0.3s ease
|
||||||
|
|
||||||
&:focus
|
&:focus
|
||||||
outline: none
|
outline: none
|
||||||
border-color: var(--primary-color)
|
border-color: var(--primary-color)
|
||||||
box-shadow: 0 0 0 3px rgba(0, 122, 255, 0.1)
|
box-shadow: 0 0 0 3px rgba(0, 122, 255, 0.2)
|
||||||
|
background: rgba(255, 255, 255, 0.9)
|
||||||
|
|
||||||
// Main Content
|
// Main Content
|
||||||
.main
|
.main
|
||||||
@@ -152,32 +186,47 @@ body
|
|||||||
|
|
||||||
// Error Message
|
// Error Message
|
||||||
.error-message
|
.error-message
|
||||||
background: var(--danger-color)
|
background: linear-gradient(135deg, var(--danger-color) 0%, #dc3545 100%)
|
||||||
color: white
|
color: white
|
||||||
padding: var(--spacing-md)
|
padding: var(--spacing-md) var(--spacing-lg)
|
||||||
border-radius: var(--border-radius-small)
|
border-radius: var(--border-radius)
|
||||||
margin-bottom: var(--spacing-md)
|
margin-bottom: var(--spacing-md)
|
||||||
display: flex
|
display: flex
|
||||||
align-items: center
|
align-items: center
|
||||||
justify-content: space-between
|
justify-content: space-between
|
||||||
font-weight: 500
|
font-weight: 500
|
||||||
|
box-shadow: 0 4px 15px rgba(255, 59, 48, 0.3)
|
||||||
|
backdrop-filter: blur(10px)
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.1)
|
||||||
|
animation: slideInFromTop 0.3s ease
|
||||||
|
|
||||||
button
|
button
|
||||||
background: none
|
background: rgba(255, 255, 255, 0.2)
|
||||||
border: none
|
border: none
|
||||||
color: white
|
color: white
|
||||||
font-size: 1.25rem
|
font-size: 1.25rem
|
||||||
cursor: pointer
|
cursor: pointer
|
||||||
padding: 0
|
padding: 0
|
||||||
width: 24px
|
width: 28px
|
||||||
height: 24px
|
height: 28px
|
||||||
border-radius: 50%
|
border-radius: 50%
|
||||||
display: flex
|
display: flex
|
||||||
align-items: center
|
align-items: center
|
||||||
justify-content: center
|
justify-content: center
|
||||||
|
transition: all 0.3s ease
|
||||||
|
backdrop-filter: blur(10px)
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
background: rgba(255, 255, 255, 0.1)
|
background: rgba(255, 255, 255, 0.3)
|
||||||
|
transform: scale(1.1)
|
||||||
|
|
||||||
|
@keyframes slideInFromTop
|
||||||
|
from
|
||||||
|
opacity: 0
|
||||||
|
transform: translateY(-10px)
|
||||||
|
to
|
||||||
|
opacity: 1
|
||||||
|
transform: translateY(0)
|
||||||
|
|
||||||
// Loading State
|
// Loading State
|
||||||
.loading
|
.loading
|
||||||
@@ -189,14 +238,24 @@ body
|
|||||||
color: var(--text-secondary)
|
color: var(--text-secondary)
|
||||||
|
|
||||||
.loading-icon
|
.loading-icon
|
||||||
font-size: 3rem
|
font-size: 3.5rem
|
||||||
color: var(--primary-color)
|
color: var(--primary-color)
|
||||||
margin-bottom: var(--spacing-md)
|
margin-bottom: var(--spacing-lg)
|
||||||
animation: pulse 2s infinite
|
animation: pulse-glow 2s infinite
|
||||||
|
filter: drop-shadow(0 0 20px rgba(0, 122, 255, 0.3))
|
||||||
|
|
||||||
p
|
p
|
||||||
font-size: 1.1rem
|
font-size: 1.125rem
|
||||||
font-weight: 500
|
font-weight: 600
|
||||||
|
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1)
|
||||||
|
|
||||||
|
@keyframes pulse-glow
|
||||||
|
0%, 100%
|
||||||
|
opacity: 1
|
||||||
|
transform: scale(1)
|
||||||
|
50%
|
||||||
|
opacity: 0.7
|
||||||
|
transform: scale(1.05)
|
||||||
|
|
||||||
@keyframes pulse
|
@keyframes pulse
|
||||||
0%, 100%
|
0%, 100%
|
||||||
@@ -204,6 +263,14 @@ body
|
|||||||
50%
|
50%
|
||||||
opacity: 0.5
|
opacity: 0.5
|
||||||
|
|
||||||
|
@keyframes pulse-today
|
||||||
|
0%, 100%
|
||||||
|
transform: scale(1)
|
||||||
|
box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.7)
|
||||||
|
50%
|
||||||
|
transform: scale(1.05)
|
||||||
|
box-shadow: 0 0 0 10px rgba(255, 255, 255, 0)
|
||||||
|
|
||||||
// Calendar Content
|
// Calendar Content
|
||||||
.calendar-content
|
.calendar-content
|
||||||
display: flex
|
display: flex
|
||||||
@@ -221,12 +288,19 @@ body
|
|||||||
border-radius: var(--border-radius)
|
border-radius: var(--border-radius)
|
||||||
box-shadow: var(--shadow-light)
|
box-shadow: var(--shadow-light)
|
||||||
text-align: center
|
text-align: center
|
||||||
|
border: 2px dashed var(--border-color)
|
||||||
|
transition: all 0.3s ease
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
border-color: var(--primary-color)
|
||||||
|
box-shadow: var(--shadow-medium)
|
||||||
|
|
||||||
svg
|
svg
|
||||||
font-size: 3rem
|
font-size: 3rem
|
||||||
margin-bottom: var(--spacing-md)
|
margin-bottom: var(--spacing-md)
|
||||||
color: var(--primary-color)
|
color: var(--primary-color)
|
||||||
opacity: 0.5
|
opacity: 0.5
|
||||||
|
animation: float 3s ease-in-out infinite
|
||||||
|
|
||||||
p
|
p
|
||||||
font-size: 1.1rem
|
font-size: 1.1rem
|
||||||
@@ -238,6 +312,12 @@ body
|
|||||||
color: var(--text-secondary)
|
color: var(--text-secondary)
|
||||||
line-height: 1.4
|
line-height: 1.4
|
||||||
|
|
||||||
|
@keyframes float
|
||||||
|
0%, 100%
|
||||||
|
transform: translateY(0)
|
||||||
|
50%
|
||||||
|
transform: translateY(-10px)
|
||||||
|
|
||||||
// Events List
|
// Events List
|
||||||
.events-list
|
.events-list
|
||||||
display: flex
|
display: flex
|
||||||
@@ -249,32 +329,120 @@ body
|
|||||||
border-radius: var(--border-radius)
|
border-radius: var(--border-radius)
|
||||||
box-shadow: var(--shadow-light)
|
box-shadow: var(--shadow-light)
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
|
transition: all 0.3s ease
|
||||||
|
border: 2px solid transparent
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
box-shadow: var(--shadow-medium)
|
||||||
|
transform: translateY(-2px)
|
||||||
|
|
||||||
|
&.today
|
||||||
|
border-color: var(--primary-color)
|
||||||
|
box-shadow: 0 4px 20px rgba(0, 122, 255, 0.2)
|
||||||
|
|
||||||
|
.day-header
|
||||||
|
background: linear-gradient(135deg, var(--primary-color) 0%, #0056b3 100%)
|
||||||
|
|
||||||
|
.day-number
|
||||||
|
background: rgba(255, 255, 255, 0.2)
|
||||||
|
color: white
|
||||||
|
animation: pulse-today 2s infinite
|
||||||
|
|
||||||
|
&.other-month
|
||||||
|
opacity: 0.7
|
||||||
|
|
||||||
|
.day-header
|
||||||
|
background: linear-gradient(135deg, var(--text-muted) 0%, #6c757d 100%)
|
||||||
|
|
||||||
.day-header
|
.day-header
|
||||||
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%)
|
background: linear-gradient(135deg, var(--secondary-color) 0%, #4c46a6 100%)
|
||||||
color: white
|
color: white
|
||||||
padding: var(--spacing-md)
|
padding: var(--spacing-md) var(--spacing-lg)
|
||||||
display: flex
|
display: flex
|
||||||
align-items: center
|
align-items: center
|
||||||
justify-content: space-between
|
justify-content: space-between
|
||||||
|
position: relative
|
||||||
|
overflow: hidden
|
||||||
|
|
||||||
h3
|
&::before
|
||||||
font-size: 1.125rem
|
content: ''
|
||||||
font-weight: 600
|
position: absolute
|
||||||
margin: 0
|
top: 0
|
||||||
|
left: 0
|
||||||
|
right: 0
|
||||||
|
bottom: 0
|
||||||
|
background: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23ffffff' fill-opacity='0.05'%3E%3Ccircle cx='30' cy='30' r='2'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E") repeat
|
||||||
|
opacity: 0.3
|
||||||
|
|
||||||
|
.day-info
|
||||||
|
display: flex
|
||||||
|
align-items: center
|
||||||
|
gap: var(--spacing-md)
|
||||||
|
position: relative
|
||||||
|
z-index: 1
|
||||||
|
|
||||||
|
.day-number
|
||||||
|
background: rgba(255, 255, 255, 0.15)
|
||||||
|
border: 2px solid rgba(255, 255, 255, 0.3)
|
||||||
|
border-radius: 50%
|
||||||
|
width: 64px
|
||||||
|
height: 64px
|
||||||
|
display: flex
|
||||||
|
align-items: center
|
||||||
|
justify-content: center
|
||||||
|
font-size: 1.75rem
|
||||||
|
font-weight: 700
|
||||||
|
color: white
|
||||||
|
transition: all 0.3s ease
|
||||||
|
backdrop-filter: blur(10px)
|
||||||
|
|
||||||
|
.day-details
|
||||||
|
display: flex
|
||||||
|
flex-direction: column
|
||||||
|
gap: 2px
|
||||||
|
|
||||||
|
.day-name
|
||||||
|
font-size: 1.125rem
|
||||||
|
font-weight: 600
|
||||||
|
text-transform: capitalize
|
||||||
|
letter-spacing: 0.5px
|
||||||
|
|
||||||
|
.month-indicator
|
||||||
|
font-size: 0.75rem
|
||||||
|
opacity: 0.9
|
||||||
|
font-weight: 400
|
||||||
|
|
||||||
.event-count
|
.event-count
|
||||||
background: rgba(255, 255, 255, 0.2)
|
display: flex
|
||||||
padding: 4px 8px
|
flex-direction: column
|
||||||
border-radius: 12px
|
align-items: center
|
||||||
font-size: 0.75rem
|
gap: 2px
|
||||||
font-weight: 500
|
background: rgba(255, 255, 255, 0.15)
|
||||||
|
padding: var(--spacing-sm) var(--spacing-md)
|
||||||
|
border-radius: var(--border-radius-small)
|
||||||
|
backdrop-filter: blur(10px)
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.2)
|
||||||
|
position: relative
|
||||||
|
z-index: 1
|
||||||
|
|
||||||
|
.count-number
|
||||||
|
font-size: 1.25rem
|
||||||
|
font-weight: 700
|
||||||
|
line-height: 1
|
||||||
|
|
||||||
|
.count-label
|
||||||
|
font-size: 0.625rem
|
||||||
|
font-weight: 500
|
||||||
|
opacity: 0.9
|
||||||
|
text-transform: uppercase
|
||||||
|
letter-spacing: 0.5px
|
||||||
|
|
||||||
.day-events
|
.day-events
|
||||||
padding: var(--spacing-sm)
|
padding: var(--spacing-md)
|
||||||
display: flex
|
display: flex
|
||||||
flex-direction: column
|
flex-direction: column
|
||||||
gap: var(--spacing-sm)
|
gap: var(--spacing-sm)
|
||||||
|
background: linear-gradient(to bottom, rgba(248, 249, 250, 0.5), rgba(255, 255, 255, 1))
|
||||||
|
|
||||||
// Calendar Event
|
// Calendar Event
|
||||||
.calendar-event
|
.calendar-event
|
||||||
@@ -287,15 +455,33 @@ body
|
|||||||
align-items: flex-start
|
align-items: flex-start
|
||||||
justify-content: space-between
|
justify-content: space-between
|
||||||
gap: var(--spacing-md)
|
gap: var(--spacing-md)
|
||||||
transition: all 0.2s ease
|
transition: all 0.3s ease
|
||||||
|
position: relative
|
||||||
|
overflow: hidden
|
||||||
|
|
||||||
|
&::before
|
||||||
|
content: ''
|
||||||
|
position: absolute
|
||||||
|
top: 0
|
||||||
|
left: 0
|
||||||
|
width: 4px
|
||||||
|
height: 100%
|
||||||
|
background: linear-gradient(to bottom, var(--primary-color), rgba(0, 122, 255, 0.3))
|
||||||
|
transition: width 0.3s ease
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
box-shadow: var(--shadow-medium)
|
box-shadow: var(--shadow-medium)
|
||||||
transform: translateY(-1px)
|
transform: translateY(-2px)
|
||||||
|
border-color: transparent
|
||||||
|
|
||||||
|
&::before
|
||||||
|
width: 8px
|
||||||
|
|
||||||
.event-content
|
.event-content
|
||||||
flex: 1
|
flex: 1
|
||||||
min-width: 0
|
min-width: 0
|
||||||
|
position: relative
|
||||||
|
z-index: 1
|
||||||
|
|
||||||
.event-text
|
.event-text
|
||||||
font-weight: 500
|
font-weight: 500
|
||||||
@@ -303,22 +489,38 @@ body
|
|||||||
font-size: 1rem
|
font-size: 1rem
|
||||||
margin-bottom: var(--spacing-xs)
|
margin-bottom: var(--spacing-xs)
|
||||||
word-break: break-word
|
word-break: break-word
|
||||||
|
line-height: 1.4
|
||||||
|
|
||||||
.event-user
|
.event-user
|
||||||
font-size: 0.875rem
|
font-size: 0.875rem
|
||||||
font-weight: 600
|
font-weight: 600
|
||||||
opacity: 0.8
|
opacity: 0.8
|
||||||
|
display: flex
|
||||||
|
align-items: center
|
||||||
|
gap: var(--spacing-xs)
|
||||||
|
|
||||||
|
&::before
|
||||||
|
content: ''
|
||||||
|
width: 8px
|
||||||
|
height: 8px
|
||||||
|
border-radius: 50%
|
||||||
|
background: currentColor
|
||||||
|
opacity: 0.6
|
||||||
|
|
||||||
.event-actions
|
.event-actions
|
||||||
display: flex
|
display: flex
|
||||||
gap: var(--spacing-xs)
|
gap: var(--spacing-xs)
|
||||||
flex-shrink: 0
|
flex-shrink: 0
|
||||||
|
position: relative
|
||||||
|
z-index: 1
|
||||||
|
|
||||||
.edit-form
|
.edit-form
|
||||||
width: 100%
|
width: 100%
|
||||||
display: flex
|
display: flex
|
||||||
flex-direction: column
|
flex-direction: column
|
||||||
gap: var(--spacing-sm)
|
gap: var(--spacing-sm)
|
||||||
|
position: relative
|
||||||
|
z-index: 1
|
||||||
|
|
||||||
.form-group
|
.form-group
|
||||||
display: flex
|
display: flex
|
||||||
@@ -337,6 +539,7 @@ body
|
|||||||
border-radius: var(--border-radius-small)
|
border-radius: var(--border-radius-small)
|
||||||
font-size: 0.875rem
|
font-size: 0.875rem
|
||||||
background: var(--surface-color)
|
background: var(--surface-color)
|
||||||
|
transition: all 0.2s ease
|
||||||
|
|
||||||
&:focus
|
&:focus
|
||||||
outline: none
|
outline: none
|
||||||
@@ -352,55 +555,86 @@ body
|
|||||||
// Buttons
|
// Buttons
|
||||||
.btn
|
.btn
|
||||||
border: none
|
border: none
|
||||||
border-radius: var(--border-radius-small)
|
border-radius: var(--border-radius)
|
||||||
padding: var(--spacing-sm) var(--spacing-md)
|
padding: var(--spacing-sm) var(--spacing-md)
|
||||||
font-size: 0.875rem
|
font-size: 0.875rem
|
||||||
font-weight: 500
|
font-weight: 600
|
||||||
cursor: pointer
|
cursor: pointer
|
||||||
display: flex
|
display: flex
|
||||||
align-items: center
|
align-items: center
|
||||||
justify-content: center
|
justify-content: center
|
||||||
gap: var(--spacing-xs)
|
gap: var(--spacing-xs)
|
||||||
transition: all 0.2s ease
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1)
|
||||||
text-decoration: none
|
text-decoration: none
|
||||||
|
position: relative
|
||||||
|
overflow: hidden
|
||||||
|
|
||||||
|
&::before
|
||||||
|
content: ''
|
||||||
|
position: absolute
|
||||||
|
top: 0
|
||||||
|
left: -100%
|
||||||
|
width: 100%
|
||||||
|
height: 100%
|
||||||
|
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent)
|
||||||
|
transition: left 0.5s ease
|
||||||
|
|
||||||
|
&:hover::before
|
||||||
|
left: 100%
|
||||||
|
|
||||||
&:disabled
|
&:disabled
|
||||||
opacity: 0.5
|
opacity: 0.5
|
||||||
cursor: not-allowed
|
cursor: not-allowed
|
||||||
|
transform: none !important
|
||||||
|
|
||||||
|
&:hover::before
|
||||||
|
left: -100%
|
||||||
|
|
||||||
&.btn-primary
|
&.btn-primary
|
||||||
background: var(--primary-color)
|
background: linear-gradient(135deg, var(--primary-color) 0%, #0056b3 100%)
|
||||||
color: white
|
color: white
|
||||||
|
box-shadow: 0 4px 15px rgba(0, 122, 255, 0.3)
|
||||||
|
|
||||||
&:hover:not(:disabled)
|
&:hover:not(:disabled)
|
||||||
background: #0056b3
|
transform: translateY(-2px)
|
||||||
transform: translateY(-1px)
|
box-shadow: 0 6px 20px rgba(0, 122, 255, 0.4)
|
||||||
|
|
||||||
|
&:active:not(:disabled)
|
||||||
|
transform: translateY(0)
|
||||||
|
|
||||||
&.btn-secondary
|
&.btn-secondary
|
||||||
background: var(--border-color)
|
background: linear-gradient(135deg, rgba(255, 255, 255, 0.9) 0%, rgba(248, 249, 250, 0.9) 100%)
|
||||||
color: var(--text-primary)
|
color: var(--text-primary)
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.1)
|
||||||
|
backdrop-filter: blur(10px)
|
||||||
|
|
||||||
&:hover:not(:disabled)
|
&:hover:not(:disabled)
|
||||||
background: #d1d5db
|
background: linear-gradient(135deg, rgba(255, 255, 255, 1) 0%, rgba(240, 242, 245, 1) 100%)
|
||||||
|
transform: translateY(-1px)
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1)
|
||||||
|
|
||||||
&.btn-danger
|
&.btn-danger
|
||||||
background: var(--danger-color)
|
background: linear-gradient(135deg, var(--danger-color) 0%, #dc3545 100%)
|
||||||
color: white
|
color: white
|
||||||
|
box-shadow: 0 4px 15px rgba(255, 59, 48, 0.3)
|
||||||
|
|
||||||
&:hover:not(:disabled)
|
&:hover:not(:disabled)
|
||||||
background: #dc3545
|
transform: translateY(-2px)
|
||||||
|
box-shadow: 0 6px 20px rgba(255, 59, 48, 0.4)
|
||||||
|
|
||||||
&.btn-small
|
&.btn-small
|
||||||
padding: var(--spacing-xs)
|
padding: var(--spacing-xs)
|
||||||
font-size: 0.75rem
|
font-size: 0.75rem
|
||||||
width: 32px
|
width: 36px
|
||||||
height: 32px
|
height: 36px
|
||||||
|
border-radius: 50%
|
||||||
|
|
||||||
svg
|
svg
|
||||||
font-size: 0.875rem
|
font-size: 0.875rem
|
||||||
|
|
||||||
svg
|
svg
|
||||||
font-size: 1rem
|
font-size: 1rem
|
||||||
|
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.1))
|
||||||
|
|
||||||
// Add Form Overlay
|
// Add Form Overlay
|
||||||
.add-form-overlay
|
.add-form-overlay
|
||||||
@@ -409,59 +643,75 @@ body
|
|||||||
left: 0
|
left: 0
|
||||||
right: 0
|
right: 0
|
||||||
bottom: 0
|
bottom: 0
|
||||||
background: rgba(0, 0, 0, 0.5)
|
background: rgba(0, 0, 0, 0.6)
|
||||||
|
backdrop-filter: blur(8px)
|
||||||
display: flex
|
display: flex
|
||||||
align-items: center
|
align-items: center
|
||||||
justify-content: center
|
justify-content: center
|
||||||
z-index: 1000
|
z-index: 1000
|
||||||
padding: var(--spacing-md)
|
padding: var(--spacing-md)
|
||||||
|
animation: fadeIn 0.3s ease
|
||||||
|
|
||||||
.add-form
|
.add-form
|
||||||
background: var(--surface-color)
|
background: linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(248, 249, 250, 0.98) 100%)
|
||||||
|
backdrop-filter: blur(20px)
|
||||||
border-radius: var(--border-radius)
|
border-radius: var(--border-radius)
|
||||||
padding: var(--spacing-lg)
|
padding: var(--spacing-xl)
|
||||||
width: 100%
|
width: 100%
|
||||||
max-width: 400px
|
max-width: 420px
|
||||||
box-shadow: var(--shadow-medium)
|
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2)
|
||||||
max-height: 80vh
|
max-height: 80vh
|
||||||
overflow-y: auto
|
overflow-y: auto
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.3)
|
||||||
|
animation: slideIn 0.3s ease
|
||||||
|
|
||||||
h3
|
h3
|
||||||
font-size: 1.25rem
|
font-size: 1.375rem
|
||||||
font-weight: 600
|
font-weight: 700
|
||||||
margin-bottom: var(--spacing-md)
|
margin-bottom: var(--spacing-lg)
|
||||||
color: var(--text-primary)
|
color: var(--text-primary)
|
||||||
text-align: center
|
text-align: center
|
||||||
|
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1)
|
||||||
|
|
||||||
.form-group
|
.form-group
|
||||||
display: flex
|
display: flex
|
||||||
flex-direction: column
|
flex-direction: column
|
||||||
margin-bottom: var(--spacing-md)
|
margin-bottom: var(--spacing-lg)
|
||||||
|
|
||||||
label
|
label
|
||||||
font-size: 0.875rem
|
font-size: 0.875rem
|
||||||
font-weight: 500
|
font-weight: 600
|
||||||
color: var(--text-secondary)
|
color: var(--text-secondary)
|
||||||
margin-bottom: var(--spacing-xs)
|
margin-bottom: var(--spacing-sm)
|
||||||
|
text-transform: uppercase
|
||||||
|
letter-spacing: 0.5px
|
||||||
|
|
||||||
input, select
|
input, select
|
||||||
width: 100%
|
width: 100%
|
||||||
padding: var(--spacing-md)
|
padding: var(--spacing-md)
|
||||||
border: 1px solid var(--border-color)
|
border: 2px solid rgba(255, 255, 255, 0.3)
|
||||||
border-radius: var(--border-radius-small)
|
border-radius: var(--border-radius)
|
||||||
font-size: 1rem
|
font-size: 1rem
|
||||||
background: var(--surface-color)
|
background: rgba(255, 255, 255, 0.7)
|
||||||
|
backdrop-filter: blur(10px)
|
||||||
|
transition: all 0.3s ease
|
||||||
|
font-weight: 500
|
||||||
|
|
||||||
&:focus
|
&:focus
|
||||||
outline: none
|
outline: none
|
||||||
border-color: var(--primary-color)
|
border-color: var(--primary-color)
|
||||||
box-shadow: 0 0 0 3px rgba(0, 122, 255, 0.1)
|
box-shadow: 0 0 0 4px rgba(0, 122, 255, 0.15)
|
||||||
|
background: rgba(255, 255, 255, 0.9)
|
||||||
|
|
||||||
|
&::placeholder
|
||||||
|
color: var(--text-muted)
|
||||||
|
font-weight: 400
|
||||||
|
|
||||||
.form-actions
|
.form-actions
|
||||||
display: flex
|
display: flex
|
||||||
gap: var(--spacing-sm)
|
gap: var(--spacing-md)
|
||||||
justify-content: flex-end
|
justify-content: flex-end
|
||||||
margin-top: var(--spacing-lg)
|
margin-top: var(--spacing-xl)
|
||||||
|
|
||||||
// Floating Action Button
|
// Floating Action Button
|
||||||
.fab-container
|
.fab-container
|
||||||
@@ -471,27 +721,59 @@ body
|
|||||||
z-index: 100
|
z-index: 100
|
||||||
|
|
||||||
.fab
|
.fab
|
||||||
width: 56px
|
width: 64px
|
||||||
height: 56px
|
height: 64px
|
||||||
border-radius: 50%
|
border-radius: 50%
|
||||||
background: var(--primary-color)
|
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%)
|
||||||
color: white
|
color: white
|
||||||
border: none
|
border: none
|
||||||
cursor: pointer
|
cursor: pointer
|
||||||
display: flex
|
display: flex
|
||||||
align-items: center
|
align-items: center
|
||||||
justify-content: center
|
justify-content: center
|
||||||
font-size: 1.25rem
|
font-size: 1.5rem
|
||||||
box-shadow: var(--shadow-medium)
|
box-shadow: 0 8px 32px rgba(0, 122, 255, 0.4)
|
||||||
transition: all 0.2s ease
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1)
|
||||||
|
position: relative
|
||||||
|
overflow: hidden
|
||||||
|
|
||||||
|
&::before
|
||||||
|
content: ''
|
||||||
|
position: absolute
|
||||||
|
top: 0
|
||||||
|
left: 0
|
||||||
|
right: 0
|
||||||
|
bottom: 0
|
||||||
|
background: linear-gradient(45deg, transparent 30%, rgba(255, 255, 255, 0.2) 50%, transparent 70%)
|
||||||
|
transform: translateX(-100%)
|
||||||
|
transition: transform 0.6s ease
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
background: #0056b3
|
transform: translateY(-4px) scale(1.1)
|
||||||
transform: translateY(-2px)
|
box-shadow: 0 12px 40px rgba(0, 122, 255, 0.5)
|
||||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2)
|
|
||||||
|
&::before
|
||||||
|
transform: translateX(100%)
|
||||||
|
|
||||||
&:active
|
&:active
|
||||||
transform: translateY(0)
|
transform: translateY(-2px) scale(1.05)
|
||||||
|
|
||||||
|
svg
|
||||||
|
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2))
|
||||||
|
|
||||||
|
@keyframes fadeIn
|
||||||
|
from
|
||||||
|
opacity: 0
|
||||||
|
to
|
||||||
|
opacity: 1
|
||||||
|
|
||||||
|
@keyframes slideIn
|
||||||
|
from
|
||||||
|
opacity: 0
|
||||||
|
transform: translateY(20px) scale(0.95)
|
||||||
|
to
|
||||||
|
opacity: 1
|
||||||
|
transform: translateY(0) scale(1)
|
||||||
|
|
||||||
// Responsive Design
|
// Responsive Design
|
||||||
@media (max-width: 480px)
|
@media (max-width: 480px)
|
||||||
@@ -500,6 +782,7 @@ body
|
|||||||
|
|
||||||
.header
|
.header
|
||||||
padding: var(--spacing-xs) var(--spacing-sm)
|
padding: var(--spacing-xs) var(--spacing-sm)
|
||||||
|
border-radius: 0
|
||||||
|
|
||||||
.header-content
|
.header-content
|
||||||
gap: var(--spacing-sm)
|
gap: var(--spacing-sm)
|
||||||
@@ -513,8 +796,8 @@ body
|
|||||||
min-width: 120px
|
min-width: 120px
|
||||||
|
|
||||||
.btn-icon
|
.btn-icon
|
||||||
width: 36px
|
width: 40px
|
||||||
height: 36px
|
height: 40px
|
||||||
|
|
||||||
.view-controls
|
.view-controls
|
||||||
flex-direction: column
|
flex-direction: column
|
||||||
@@ -527,33 +810,88 @@ body
|
|||||||
.user-select
|
.user-select
|
||||||
width: 100%
|
width: 100%
|
||||||
|
|
||||||
.day-header
|
.day-section
|
||||||
padding: var(--spacing-sm)
|
.day-header
|
||||||
|
padding: var(--spacing-sm) var(--spacing-md)
|
||||||
|
|
||||||
h3
|
.day-info
|
||||||
font-size: 1rem
|
gap: var(--spacing-sm)
|
||||||
|
|
||||||
|
.day-number
|
||||||
|
width: 52px
|
||||||
|
height: 52px
|
||||||
|
font-size: 1.375rem
|
||||||
|
|
||||||
|
.day-details
|
||||||
|
.day-name
|
||||||
|
font-size: 0.9rem
|
||||||
|
|
||||||
|
.month-indicator
|
||||||
|
font-size: 0.65rem
|
||||||
|
|
||||||
|
.event-count
|
||||||
|
padding: var(--spacing-xs) var(--spacing-sm)
|
||||||
|
|
||||||
|
.count-number
|
||||||
|
font-size: 1rem
|
||||||
|
|
||||||
|
.count-label
|
||||||
|
font-size: 0.5rem
|
||||||
|
|
||||||
|
.day-events
|
||||||
|
padding: var(--spacing-sm)
|
||||||
|
|
||||||
.calendar-event
|
.calendar-event
|
||||||
padding: var(--spacing-sm)
|
padding: var(--spacing-sm)
|
||||||
flex-direction: column
|
flex-direction: column
|
||||||
align-items: stretch
|
align-items: stretch
|
||||||
|
gap: var(--spacing-sm)
|
||||||
|
|
||||||
|
.event-content
|
||||||
|
.event-text
|
||||||
|
font-size: 0.9rem
|
||||||
|
|
||||||
|
.event-user
|
||||||
|
font-size: 0.8rem
|
||||||
|
|
||||||
.event-actions
|
.event-actions
|
||||||
justify-content: flex-end
|
justify-content: flex-end
|
||||||
margin-top: var(--spacing-sm)
|
margin-top: var(--spacing-xs)
|
||||||
|
|
||||||
|
.btn-small
|
||||||
|
width: 32px
|
||||||
|
height: 32px
|
||||||
|
|
||||||
.add-form-overlay
|
.add-form-overlay
|
||||||
padding: var(--spacing-sm)
|
padding: var(--spacing-sm)
|
||||||
|
|
||||||
.add-form
|
.add-form
|
||||||
padding: var(--spacing-md)
|
padding: var(--spacing-lg)
|
||||||
max-height: 90vh
|
max-height: 90vh
|
||||||
|
|
||||||
|
h3
|
||||||
|
font-size: 1.25rem
|
||||||
|
|
||||||
|
.form-group
|
||||||
|
margin-bottom: var(--spacing-md)
|
||||||
|
|
||||||
|
input, select
|
||||||
|
padding: var(--spacing-sm)
|
||||||
|
|
||||||
.fab-container
|
.fab-container
|
||||||
bottom: var(--spacing-md)
|
bottom: var(--spacing-md)
|
||||||
right: var(--spacing-md)
|
right: var(--spacing-md)
|
||||||
|
|
||||||
.fab
|
.fab
|
||||||
width: 48px
|
width: 56px
|
||||||
height: 48px
|
height: 56px
|
||||||
font-size: 1.125rem
|
font-size: 1.25rem
|
||||||
|
|
||||||
|
.empty-state
|
||||||
|
padding: var(--spacing-lg)
|
||||||
|
|
||||||
|
svg
|
||||||
|
font-size: 2.5rem
|
||||||
|
|
||||||
|
p
|
||||||
|
font-size: 1rem
|
||||||
|
Reference in New Issue
Block a user