Skip to content

Commit 3aa280a

Browse files
Radical Minimalism: UI modernization (16px radius, HeroCard glow, ProfileCard 64px), and TS build fixes
1 parent 74b6268 commit 3aa280a

8 files changed

Lines changed: 133 additions & 77 deletions

File tree

web/src/components/home/DashboardBar.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@ export const DashboardBar: React.FC<DashboardBarProps> = ({ realTime, isVirtual,
2121
display: 'flex',
2222
justifyContent: 'space-between',
2323
alignItems: 'center',
24-
background: '#FFFFFF',
25-
borderRadius: '8px',
24+
background: 'rgba(255, 255, 255, 0.85)',
25+
backdropFilter: 'blur(12px)',
26+
WebkitBackdropFilter: 'blur(12px)',
27+
borderRadius: '16px',
2628
padding: '16px 24px',
2729
margin: '12px 20px',
28-
boxShadow: '0 8px 24px rgba(0,0,0,0.04)',
29-
border: '1px solid rgba(0,0,0,0.02)',
30+
boxShadow: '0 4px 24px rgba(0,0,0,0.04)',
31+
border: '1px solid rgba(238, 114, 33, 0.15)',
3032
transition: 'all 0.3s ease'
3133
}}>
3234
{/* Date Segment */}

web/src/pages/Cabinet/Cabinet.module.css

Lines changed: 73 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
letter-spacing: 0.05em;
4242
color: #71717a;
4343
padding: 0 12px; /* Align with internal card content (12px from card edge) */
44-
margin-top: 8px;
44+
margin-top: 4px;
4545
margin-bottom: 0px;
4646
}
4747

@@ -56,28 +56,44 @@
5656
overflow: hidden;
5757
}
5858

59+
.standaloneRowWrap {
60+
margin-top: 4px;
61+
margin-bottom: 0px;
62+
transition: all 0.2s ease;
63+
cursor: pointer;
64+
}
65+
66+
.standaloneRowWrap:active {
67+
opacity: 0.7;
68+
transform: scale(0.99);
69+
}
70+
71+
.controlPanelRow {
72+
padding-left: 16px !important;
73+
}
74+
5975
/* ============================================
6076
PROFILE CARD
6177
============================================ */
6278
.profileHeader {
6379
display: flex;
64-
align-items: center;
65-
gap: 12px; /* Tightened from 16px */
66-
padding: 10px 12px; /* Compact vertical padding */
80+
align-items: flex-start;
81+
gap: 12px;
82+
padding: 10px;
6783
}
6884

6985
.avatarWrap {
70-
width: 52px;
71-
height: 52px;
86+
width: 64px;
87+
height: 64px;
7288
border-radius: 50%;
7389
background: #ffffff; /* Inner ring gap */
7490
display: flex;
7591
align-items: center;
7692
justify-content: center;
7793
flex-shrink: 0;
7894
overflow: hidden;
79-
padding: 2px; /* The 'Double Ring' gap */
80-
border: 1px solid #e4e4e7; /* Outer ring */
95+
padding: 2.5px; /* Double Ring gap */
96+
border: 1px solid #e4e4e7; /* Restored grey outer ring */
8197
box-shadow: 0 2px 4px rgba(0,0,0,0.02);
8298
}
8399

@@ -96,7 +112,31 @@
96112
.profileText {
97113
display: flex;
98114
flex-direction: column;
99-
gap: 2px;
115+
justify-content: space-between;
116+
height: 64px; /* Match new 64px standard */
117+
}
118+
119+
.statusIconWrap {
120+
width: 28px;
121+
height: 28px;
122+
border-radius: 50%;
123+
display: flex;
124+
align-items: center;
125+
justify-content: center;
126+
box-sizing: border-box;
127+
flex-shrink: 0;
128+
}
129+
130+
.statusIconAnon {
131+
background: rgba(113, 113, 122, 0.08);
132+
border: 1px solid rgba(113, 113, 122, 0.15);
133+
color: #71717a;
134+
}
135+
136+
.statusIconReg {
137+
background: rgba(238, 114, 33, 0.08);
138+
border: 1px solid rgba(238, 114, 33, 0.2);
139+
color: #EE7221;
100140
}
101141

102142
.profileName {
@@ -106,29 +146,31 @@
106146
line-height: 1.2;
107147
}
108148

109-
.profileSub {
110-
font-size: 13px;
111-
color: #71717a;
112-
}
113149

114150
.brandIconWrap {
115-
width: 52px;
116-
height: 52px;
151+
width: 64px;
152+
height: 64px;
117153
border-radius: 50%;
118-
/* Glassmorphism Effect */
119-
background: linear-gradient(135deg, rgba(238, 114, 33, 0.15) 0%, rgba(238, 114, 33, 0.05) 100%);
120-
backdrop-filter: blur(4px);
121-
-webkit-backdrop-filter: blur(4px);
122-
123-
border: 1.5px solid #EE7221;
154+
background: #ffffff; /* Consistent inner white ring */
155+
padding: 2.5px;
156+
border: 1px solid #e4e4e7; /* Restored grey outer ring for sync */
124157
display: flex;
125158
align-items: center;
126159
justify-content: center;
127160
box-sizing: border-box;
128161
color: #EE7221;
129-
130-
/* Subtle Outer Glow */
131-
box-shadow: 0 0 10px rgba(238, 114, 33, 0.1);
162+
flex-shrink: 0;
163+
box-shadow: 0 2px 4px rgba(0,0,0,0.02);
164+
}
165+
166+
.brandIconInner {
167+
width: 100%;
168+
height: 100%;
169+
border-radius: 50%;
170+
background: linear-gradient(135deg, rgba(238, 114, 33, 0.1) 0%, rgba(238, 114, 33, 0.05) 100%);
171+
display: flex;
172+
align-items: center;
173+
justify-content: center;
132174
}
133175

134176
/* ============================================
@@ -229,6 +271,13 @@
229271
min-height: 52px;
230272
box-sizing: border-box;
231273
width: 100%;
274+
transition: all 0.2s ease;
275+
-webkit-tap-highlight-color: transparent;
276+
}
277+
278+
.cabinetRow:active {
279+
opacity: 0.7;
280+
transform: scale(0.99);
232281
}
233282

234283
.cabinetRow:not(:last-child)::after {

web/src/pages/Cabinet/Cabinet.tsx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { useStore } from '@/store/useStore';
33
import { ProfileCard } from './components/ProfileCard';
44
import { NotificationSlots } from './components/NotificationSlots';
55
import { GeneralSettings } from './components/GeneralSettings';
6+
import { CabinetRow } from './components/CabinetPrimitives';
7+
import { Hash, ChevronRight } from 'lucide-react';
68
import { AboutSection } from './components/AboutSection';
79
import { SubGroupSheet } from './components/SubGroupSheet';
810
import { NotificationEditorSheet } from './components/NotificationEditorSheet';
@@ -94,6 +96,20 @@ export const Cabinet: React.FC = () => {
9496
onSignOut={() => setSignOutSheetOpen(true)}
9597
/>
9698

99+
<div className={styles.standaloneRowWrap}>
100+
<CabinetRow
101+
icon={<Hash size={18} strokeWidth={2.5} />}
102+
label="Стартова підчерга"
103+
onClick={() => setSubGroupSheetOpen(true)}
104+
rightElement={
105+
<>
106+
<span className={styles.settingValueOrange}>{userConfig.startGroup}</span>
107+
<ChevronRight size={16} color="#d4d4d8" />
108+
</>
109+
}
110+
/>
111+
</div>
112+
97113
<NotificationSlots
98114
slots={slots}
99115
isLocked={isAnon}
@@ -105,7 +121,6 @@ export const Cabinet: React.FC = () => {
105121
config={userConfig}
106122
isLocked={isAnon}
107123
onToggleTomorrow={handleToggleTomorrow}
108-
onChangeStartGroup={() => setSubGroupSheetOpen(true)}
109124
onRequireAuth={() => setAuthSheetOpen(true)}
110125
/>
111126

web/src/pages/Cabinet/components/AboutSection.tsx

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,26 @@ interface AboutSectionProps {
1212
export const AboutSection: React.FC<AboutSectionProps> = ({ onShare, onFeedback, onAbout }) => {
1313
return (
1414
<div className={styles.section}>
15-
<div className={styles.solidCard}>
16-
<CabinetRow
17-
icon={<Info size={18} strokeWidth={2.5} />}
18-
label="Про застосунок"
19-
onClick={onAbout}
20-
rightElement={<ChevronRight size={16} color="#d4d4d8" />}
21-
/>
15+
<CabinetRow
16+
icon={<Info size={18} strokeWidth={2.5} />}
17+
label="Про застосунок"
18+
onClick={onAbout}
19+
rightElement={<ChevronRight size={16} color="#d4d4d8" />}
20+
/>
2221

23-
<CabinetRow
24-
icon={<Share2 size={18} strokeWidth={2.5} />}
25-
label="Поділитись"
26-
onClick={onShare}
27-
rightElement={<ChevronRight size={16} color="#d4d4d8" />}
28-
/>
22+
<CabinetRow
23+
icon={<Share2 size={18} strokeWidth={2.5} />}
24+
label="Поділитись"
25+
onClick={onShare}
26+
rightElement={<ChevronRight size={16} color="#d4d4d8" />}
27+
/>
2928

30-
<CabinetRow
31-
icon={<MessageSquare size={18} strokeWidth={2.5} />}
32-
label="Зворотній зв'язок"
33-
onClick={onFeedback}
34-
rightElement={<ChevronRight size={16} color="#d4d4d8" />}
35-
/>
36-
</div>
29+
<CabinetRow
30+
icon={<MessageSquare size={18} strokeWidth={2.5} />}
31+
label="Зворотній зв'язок"
32+
onClick={onFeedback}
33+
rightElement={<ChevronRight size={16} color="#d4d4d8" />}
34+
/>
3735
</div>
3836
);
3937
};

web/src/pages/Cabinet/components/GeneralSettings.tsx

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React from 'react';
2-
import { Hash, Clock, ChevronRight } from 'lucide-react';
32
import { CabinetRow } from './CabinetPrimitives';
43
import styles from '../Cabinet.module.css';
54

@@ -10,36 +9,23 @@ interface GeneralSettingsProps {
109
};
1110
isLocked?: boolean;
1211
onToggleTomorrow: () => void;
13-
onChangeStartGroup: () => void;
1412
onRequireAuth?: () => void;
1513
}
1614

1715
export const GeneralSettings: React.FC<GeneralSettingsProps> = ({
1816
config,
1917
isLocked,
2018
onToggleTomorrow,
21-
onChangeStartGroup,
2219
onRequireAuth
2320
}) => {
2421
return (
2522
<div className={styles.section}>
2623
<div className={styles.solidCard}>
27-
<CabinetRow
28-
icon={<Hash size={18} strokeWidth={2.5} />}
29-
label="Стартова підчерга"
30-
onClick={onChangeStartGroup}
31-
rightElement={
32-
<>
33-
<span className={styles.settingValueOrange}>{config.startGroup}</span>
34-
<ChevronRight size={16} color="#d4d4d8" />
35-
</>
36-
}
37-
/>
3824

3925
<CabinetRow
40-
icon={<Clock size={18} strokeWidth={2.5} />}
41-
label="Графік на завтра"
26+
label={<span className={styles.slotTitle}>Графік на завтра</span>}
4227
onClick={isLocked ? onRequireAuth : onToggleTomorrow}
28+
className={styles.controlPanelRow}
4329
rightElement={
4430
<div className={`${styles.toggle} ${config.tomorrowPush ? styles.toggleActive : ''}`} />
4531
}

web/src/pages/Cabinet/components/ProfileCard.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import { BrandIcon } from '../../../assets/brand/BrandIcon';
3+
import { Plus, Minus } from 'lucide-react';
34
import styles from '../Cabinet.module.css';
45

56
// ── SVG Icons ──────────────────────────────────────────────────────────────────
@@ -58,23 +59,24 @@ export const ProfileCard: React.FC<ProfileCardProps> = ({ user, onClick, onSignO
5859
<img src={user.avatarUrl} alt="Avatar" className={styles.avatarImg} />
5960
) : (
6061
isAnon
61-
? <BrandIcon variant="solid" size={32} />
62+
? <div className={styles.brandIconInner}><BrandIcon variant="solid" size={42} /></div>
6263
: <span style={{ fontSize: '22px' }}>👤</span>
6364
)}
6465
</div>
6566

6667
{/* Name block */}
6768
<div className={styles.profileText}>
69+
<div className={`${styles.statusIconWrap} ${isAnon ? styles.statusIconAnon : styles.statusIconReg}`}>
70+
{isAnon
71+
? <Minus size={16} strokeWidth={3} />
72+
: <Plus size={16} strokeWidth={3} />
73+
}
74+
</div>
6875
<div className={styles.profileName}>
6976
{isAnon && user.id
7077
? `Користувач #${user.id.slice(-4).toUpperCase()}`
7178
: user.name}
7279
</div>
73-
{isAnon && (
74-
<div className={`${styles.profileSub} ${styles.settingValueOrange}`}>
75-
Натисніть, щоб авторизуватись
76-
</div>
77-
)}
7880
</div>
7981

8082
{/* Sync icons — always in top-right */}

web/src/styles/index.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
font-family: 'Inter', -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif;
55

66
/* SvitloSk Design Tokens */
7-
--radius-main: 8px;
7+
--radius-main: 16px;
88
--radius-inner: 6px;
99
--page-top-gap: 20px;
1010

web/src/styles/legacy/tech-ui.css

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -277,12 +277,12 @@
277277
row-gap: 2px !important;
278278
padding: 16px 14px 18px !important;
279279
height: 160px !important;
280-
border-radius: 8px !important;
280+
border-radius: 16px !important;
281281
background: var(--hero-bg) !important;
282282
backdrop-filter: blur(12px) !important;
283283
-webkit-backdrop-filter: blur(12px) !important;
284-
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08) !important;
285-
border: 1px solid rgba(0, 0, 0, 0.1) !important;
284+
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.08) !important;
285+
border: 2.5px solid transparent !important;
286286
-webkit-font-smoothing: antialiased !important;
287287
transform: translateY(-2px) !important;
288288
margin: 0 20px !important;
@@ -291,11 +291,15 @@
291291
}
292292

293293
.hero-card.status-on {
294-
border-color: #FF7A00 !important;
294+
border-color: rgba(255, 122, 0, 0.35) !important;
295+
box-shadow: 0 12px 45px rgba(255, 122, 0, 0.16) !important;
296+
background: linear-gradient(135deg, rgba(255, 122, 0, 0.03) 0%, #ffffff 100%) !important;
295297
}
296298

297299
.hero-card.status-off {
298-
border-color: rgba(154, 160, 166, 0.4) !important;
300+
border-color: rgba(113, 113, 122, 0.3) !important;
301+
box-shadow: 0 10px 35px rgba(0, 0, 0, 0.07) !important;
302+
background: linear-gradient(135deg, rgba(113, 113, 122, 0.03) 0%, #ffffff 100%) !important;
299303
}
300304

301305
@media (max-width: 360px) {

0 commit comments

Comments
 (0)