@chrryai/chrry 1.1.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/About.module.scss +112 -0
- package/Account.module.scss +159 -0
- package/AddToHomeScreen.module.scss +126 -0
- package/Affiliate.module.scss +245 -0
- package/AffiliateDashboard.module.scss +269 -0
- package/Agent.module.scss +197 -0
- package/AnimatedWrapper.module.scss +0 -0
- package/App.module.scss +283 -0
- package/Bookmark.module.scss +15 -0
- package/Calendar.module.scss +824 -0
- package/CharacterProfiles.module.scss +29 -0
- package/Chat.module.scss +932 -0
- package/Checkbox.module.scss +67 -0
- package/Chrry.module.scss +69 -0
- package/Collaborate.module.scss +22 -0
- package/CollaborationStatus.module.scss +17 -0
- package/CollaborationTooltip.module.scss +257 -0
- package/ColorScheme.module.scss +24 -0
- package/EditThread.module.scss +51 -0
- package/EmptyStateTips.module.scss +52 -0
- package/EnableNotifications.module.scss +20 -0
- package/EventModal.module.scss +277 -0
- package/Img.module.scss +48 -0
- package/Instructions.module.scss +333 -0
- package/LICENSE +664 -0
- package/LanguageSwitcher.module.scss +21 -0
- package/Loading.module.scss +32 -0
- package/MarkdownContent.module.scss +161 -0
- package/MemoryConsent.module.scss +41 -0
- package/Menu.module.scss +272 -0
- package/Message.module.scss +470 -0
- package/Messages.module.scss +86 -0
- package/Modal.module.scss +118 -0
- package/README.md +112 -0
- package/Search.module.scss +26 -0
- package/Select.module.scss +32 -0
- package/Share.module.scss +84 -0
- package/Sidebar.module.scss +69 -0
- package/SignIn.module.scss +129 -0
- package/Skeleton.module.scss +232 -0
- package/SplashScreen.module.scss +189 -0
- package/Star.module.scss +15 -0
- package/Store.module.scss +240 -0
- package/Subscribe.module.scss +219 -0
- package/Testimonials.module.scss +33 -0
- package/Thread.module.scss +111 -0
- package/Threads.module.scss +105 -0
- package/TypingIndicator.module.scss +93 -0
- package/Users.module.scss +98 -0
- package/Version.module.scss +22 -0
- package/Weather.module.scss +31 -0
- package/Why.module.scss +79 -0
- package/__tests__/README.md +126 -0
- package/__tests__/TestComponent.module.scss +236 -0
- package/animations.scss +163 -0
- package/breakpoints.scss +8 -0
- package/context/AppContext.module.scss +22 -0
- package/context/providers/README.md +329 -0
- package/dist/About.module-RPTFOKG6.scss +112 -0
- package/dist/Account.module-AA2NOD5S.scss +159 -0
- package/dist/AddToHomeScreen.module-P6HAQ4QD.scss +126 -0
- package/dist/Affiliate.module-YM7MG54E.scss +245 -0
- package/dist/AffiliateDashboard.module-SZQJJBME.scss +269 -0
- package/dist/Agent.module-66YIBDMM.scss +197 -0
- package/dist/App.module-TOWYJFPB.scss +283 -0
- package/dist/Bookmark.module-UVMQ4TED.scss +15 -0
- package/dist/Calendar.module-HHEIXJEA.scss +824 -0
- package/dist/CharacterProfiles.module-KABR34TV.scss +29 -0
- package/dist/Chat.module-Y4TGJLBQ.scss +932 -0
- package/dist/Checkbox.module-RNW2YOC5.scss +67 -0
- package/dist/Chrry.module-SLPTRY52.scss +69 -0
- package/dist/Collaborate.module-MLRE23FZ.scss +22 -0
- package/dist/CollaborationStatus.module-CRGOOW56.scss +17 -0
- package/dist/ColorScheme.module-N7SJ5N52.scss +24 -0
- package/dist/EditThread.module-L3HOEGS3.scss +51 -0
- package/dist/EmptyStateTips.module-JLNPQ4OO.scss +52 -0
- package/dist/EnableNotifications.module-C4MYQTUA.scss +20 -0
- package/dist/EventModal.module-K7VNKTCE.scss +277 -0
- package/dist/Instructions.module-JMFWEXAP.scss +333 -0
- package/dist/LanguageSwitcher.module-MT2SIZ4L.scss +21 -0
- package/dist/Loading.module-OU42QILE.scss +32 -0
- package/dist/MarkdownContent.module-64GHE3YP.scss +161 -0
- package/dist/MemoryConsent.module-FZL3REH4.scss +41 -0
- package/dist/Menu.module-RVXPXILR.scss +272 -0
- package/dist/Message.module-5UUYCVY2.scss +470 -0
- package/dist/Messages.module-GBPUAPAI.scss +86 -0
- package/dist/Modal.module-TOU4YLFQ.scss +118 -0
- package/dist/Search.module-GU3BRADG.scss +26 -0
- package/dist/Select.module-R7QM256C.scss +32 -0
- package/dist/Share.module-VQBCBSA5.scss +84 -0
- package/dist/Sidebar.module-AUSDVTCY.scss +69 -0
- package/dist/SignIn.module-53SOSG63.scss +129 -0
- package/dist/Skeleton.module-REMEBLDY.scss +232 -0
- package/dist/Store.module-NP6776GY.scss +240 -0
- package/dist/Subscribe.module-NVGQ57RA.scss +219 -0
- package/dist/Thread.module-QAJI6KOQ.scss +111 -0
- package/dist/Threads.module-J54DFQQZ.scss +105 -0
- package/dist/Users.module-ZRHCY63D.scss +98 -0
- package/dist/Version.module-MLMD7GW5.scss +22 -0
- package/dist/Weather.module-NT6XFKA7.scss +31 -0
- package/dist/Why.module-UVZJCJF7.scss +79 -0
- package/dist/index.d.mts +1408 -0
- package/dist/index.d.ts +1408 -0
- package/dist/index.js +44600 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +44575 -0
- package/dist/index.mjs.map +1 -0
- package/dist/react-tooltip.min-LLVNRY3Z.css +1 -0
- package/globals.css +91 -0
- package/globals.scss +585 -0
- package/icons/README.md +150 -0
- package/package.json +118 -0
- package/styles/view-transitions.css +207 -0
- package/toRem.scss +6 -0
- package/utils.module.scss +116 -0
- package/utils.scss +88 -0
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
# Provider Architecture
|
|
2
|
+
|
|
3
|
+
## 🎯 Entry Point: DataProvider
|
|
4
|
+
|
|
5
|
+
`DataProvider` is now the **main entry point** that accepts a `token` prop and provides all app-wide context.
|
|
6
|
+
|
|
7
|
+
## 📦 Usage
|
|
8
|
+
|
|
9
|
+
### Basic Setup
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import { DataProvider } from "chrry/context/providers"
|
|
13
|
+
|
|
14
|
+
function App() {
|
|
15
|
+
const [token, setToken] = useState<string | null>(null)
|
|
16
|
+
|
|
17
|
+
// Get token from your auth system
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
const authToken = localStorage.getItem("authToken")
|
|
20
|
+
setToken(authToken)
|
|
21
|
+
}, [])
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<DataProvider token={token}>
|
|
25
|
+
<YourApp />
|
|
26
|
+
</DataProvider>
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### With Authentication Flow
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
import { DataProvider } from "chrry/context/providers"
|
|
35
|
+
|
|
36
|
+
function App() {
|
|
37
|
+
const [token, setToken] = useState<string | null>(null)
|
|
38
|
+
|
|
39
|
+
const handleLogin = async (email: string, password: string) => {
|
|
40
|
+
const response = await fetch("/api/auth/login", {
|
|
41
|
+
method: "POST",
|
|
42
|
+
body: JSON.stringify({ email, password }),
|
|
43
|
+
})
|
|
44
|
+
const { token } = await response.json()
|
|
45
|
+
setToken(token)
|
|
46
|
+
localStorage.setItem("authToken", token)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const handleLogout = () => {
|
|
50
|
+
setToken(null)
|
|
51
|
+
localStorage.removeItem("authToken")
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<DataProvider token={token}>
|
|
56
|
+
{token ? (
|
|
57
|
+
<AuthenticatedApp onLogout={handleLogout} />
|
|
58
|
+
) : (
|
|
59
|
+
<LoginScreen onLogin={handleLogin} />
|
|
60
|
+
)}
|
|
61
|
+
</DataProvider>
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Accessing Context
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
import { useData } from "chrry/context/providers"
|
|
70
|
+
|
|
71
|
+
function MyComponent() {
|
|
72
|
+
const {
|
|
73
|
+
// Auth
|
|
74
|
+
token,
|
|
75
|
+
|
|
76
|
+
// Environment
|
|
77
|
+
env,
|
|
78
|
+
setEnv,
|
|
79
|
+
isDevelopment,
|
|
80
|
+
|
|
81
|
+
// URLs
|
|
82
|
+
API_URL,
|
|
83
|
+
WS_URL,
|
|
84
|
+
FRONTEND_URL,
|
|
85
|
+
setApiUrl,
|
|
86
|
+
setWsUrl,
|
|
87
|
+
setFrontendUrl,
|
|
88
|
+
|
|
89
|
+
// Regional Routing
|
|
90
|
+
enableRegionalRouting,
|
|
91
|
+
setRegion,
|
|
92
|
+
currentRegion,
|
|
93
|
+
|
|
94
|
+
// Configuration
|
|
95
|
+
PROMPT_LIMITS,
|
|
96
|
+
setPromptLimits,
|
|
97
|
+
|
|
98
|
+
// API Actions (all typed!)
|
|
99
|
+
actions,
|
|
100
|
+
} = useData()
|
|
101
|
+
|
|
102
|
+
// Use actions
|
|
103
|
+
const loadThreads = async () => {
|
|
104
|
+
const threads = await actions.getThreads({ pageSize: 20 })
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return <div>...</div>
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## 🌍 Regional Routing
|
|
112
|
+
|
|
113
|
+
### Automatic Detection
|
|
114
|
+
|
|
115
|
+
```tsx
|
|
116
|
+
function App() {
|
|
117
|
+
const { enableRegionalRouting } = useData()
|
|
118
|
+
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
// Auto-detect and route to nearest server
|
|
121
|
+
enableRegionalRouting()
|
|
122
|
+
}, [])
|
|
123
|
+
|
|
124
|
+
return <YourApp />
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Manual Region Selection
|
|
129
|
+
|
|
130
|
+
```tsx
|
|
131
|
+
function RegionSelector() {
|
|
132
|
+
const { setRegion, currentRegion } = useData()
|
|
133
|
+
|
|
134
|
+
return (
|
|
135
|
+
<select
|
|
136
|
+
value={currentRegion || ""}
|
|
137
|
+
onChange={(e) => setRegion(e.target.value as Region)}
|
|
138
|
+
>
|
|
139
|
+
<option value="us">🇺🇸 United States</option>
|
|
140
|
+
<option value="eu">🇪🇺 Europe</option>
|
|
141
|
+
<option value="asia">🇨🇳 Asia</option>
|
|
142
|
+
<option value="oceania">🇦🇺 Oceania</option>
|
|
143
|
+
<option value="africa">🇿🇦 Africa</option>
|
|
144
|
+
<option value="south-america">🇧🇷 South America</option>
|
|
145
|
+
</select>
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## ⚙️ Admin Panel Features
|
|
151
|
+
|
|
152
|
+
### Environment Switching
|
|
153
|
+
|
|
154
|
+
```tsx
|
|
155
|
+
function AdminPanel() {
|
|
156
|
+
const { env, setEnv, API_URL } = useData()
|
|
157
|
+
|
|
158
|
+
return (
|
|
159
|
+
<div>
|
|
160
|
+
<h2>Environment</h2>
|
|
161
|
+
<select value={env} onChange={(e) => setEnv(e.target.value)}>
|
|
162
|
+
<option value="development">Development</option>
|
|
163
|
+
<option value="staging">Staging</option>
|
|
164
|
+
<option value="production">Production</option>
|
|
165
|
+
</select>
|
|
166
|
+
<p>Current API: {API_URL}</p>
|
|
167
|
+
</div>
|
|
168
|
+
)
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Custom Endpoints
|
|
173
|
+
|
|
174
|
+
```tsx
|
|
175
|
+
function CustomEndpoints() {
|
|
176
|
+
const { setApiUrl, setWsUrl, API_URL, WS_URL } = useData()
|
|
177
|
+
|
|
178
|
+
return (
|
|
179
|
+
<div>
|
|
180
|
+
<h2>Custom Endpoints</h2>
|
|
181
|
+
<input
|
|
182
|
+
placeholder="API URL"
|
|
183
|
+
onChange={(e) => setApiUrl(e.target.value || null)}
|
|
184
|
+
/>
|
|
185
|
+
<input
|
|
186
|
+
placeholder="WebSocket URL"
|
|
187
|
+
onChange={(e) => setWsUrl(e.target.value || null)}
|
|
188
|
+
/>
|
|
189
|
+
<p>Active API: {API_URL}</p>
|
|
190
|
+
<p>Active WS: {WS_URL}</p>
|
|
191
|
+
</div>
|
|
192
|
+
)
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Prompt Limits Configuration
|
|
197
|
+
|
|
198
|
+
```tsx
|
|
199
|
+
function PromptLimitsConfig() {
|
|
200
|
+
const { PROMPT_LIMITS, setPromptLimits } = useData()
|
|
201
|
+
|
|
202
|
+
const handleUpdate = () => {
|
|
203
|
+
setPromptLimits({
|
|
204
|
+
INPUT: 10000,
|
|
205
|
+
INSTRUCTIONS: 3000,
|
|
206
|
+
TOTAL: 50000,
|
|
207
|
+
WARNING_THRESHOLD: 7000,
|
|
208
|
+
THREAD_TITLE: 150,
|
|
209
|
+
})
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return (
|
|
213
|
+
<div>
|
|
214
|
+
<h2>Prompt Limits</h2>
|
|
215
|
+
<p>Input: {PROMPT_LIMITS.INPUT}</p>
|
|
216
|
+
<p>Instructions: {PROMPT_LIMITS.INSTRUCTIONS}</p>
|
|
217
|
+
<p>Total: {PROMPT_LIMITS.TOTAL}</p>
|
|
218
|
+
<button onClick={handleUpdate}>Update Limits</button>
|
|
219
|
+
</div>
|
|
220
|
+
)
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## 🚀 API Actions
|
|
225
|
+
|
|
226
|
+
All API actions are fully typed and automatically include the auth token:
|
|
227
|
+
|
|
228
|
+
```tsx
|
|
229
|
+
function Example() {
|
|
230
|
+
const { actions } = useData()
|
|
231
|
+
|
|
232
|
+
// Thread operations
|
|
233
|
+
await actions.getThreads({ pageSize: 20, sort: "date" })
|
|
234
|
+
await actions.getThread({ id: "thread-id" })
|
|
235
|
+
await actions.updateThread({ id: "thread-id", title: "New Title" })
|
|
236
|
+
|
|
237
|
+
// User operations
|
|
238
|
+
await actions.getUser()
|
|
239
|
+
await actions.updateUser({ name: "John Doe" })
|
|
240
|
+
await actions.uploadUserImage(file)
|
|
241
|
+
|
|
242
|
+
// Message operations
|
|
243
|
+
await actions.updateMessage({ messageId: "msg-id", like: true })
|
|
244
|
+
await actions.deleteMessage("msg-id")
|
|
245
|
+
|
|
246
|
+
// Calendar operations
|
|
247
|
+
await actions.createCalendarEvent(eventData)
|
|
248
|
+
await actions.getCalendarEvents({ startDate: "2024-01-01" })
|
|
249
|
+
|
|
250
|
+
// App operations
|
|
251
|
+
await actions.createApp(appData)
|
|
252
|
+
await actions.updateApp("app-id", appData)
|
|
253
|
+
await actions.deleteApp("app-id")
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## 🎨 Complete Example
|
|
258
|
+
|
|
259
|
+
```tsx
|
|
260
|
+
import { DataProvider, useData } from "chrry/context/providers"
|
|
261
|
+
import { useState, useEffect } from "react"
|
|
262
|
+
|
|
263
|
+
// Root App Component
|
|
264
|
+
function App() {
|
|
265
|
+
const [token, setToken] = useState<string | null>(null)
|
|
266
|
+
|
|
267
|
+
useEffect(() => {
|
|
268
|
+
// Load token from storage
|
|
269
|
+
const savedToken = localStorage.getItem("authToken")
|
|
270
|
+
setToken(savedToken)
|
|
271
|
+
}, [])
|
|
272
|
+
|
|
273
|
+
const handleLogin = async (credentials: any) => {
|
|
274
|
+
const response = await fetch("/api/auth/login", {
|
|
275
|
+
method: "POST",
|
|
276
|
+
body: JSON.stringify(credentials),
|
|
277
|
+
})
|
|
278
|
+
const { token } = await response.json()
|
|
279
|
+
setToken(token)
|
|
280
|
+
localStorage.setItem("authToken", token)
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return (
|
|
284
|
+
<DataProvider token={token}>
|
|
285
|
+
{token ? <Dashboard /> : <Login onLogin={handleLogin} />}
|
|
286
|
+
</DataProvider>
|
|
287
|
+
)
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Dashboard Component
|
|
291
|
+
function Dashboard() {
|
|
292
|
+
const { actions, enableRegionalRouting, API_URL, currentRegion } = useData()
|
|
293
|
+
|
|
294
|
+
useEffect(() => {
|
|
295
|
+
// Auto-route to nearest server
|
|
296
|
+
enableRegionalRouting()
|
|
297
|
+
|
|
298
|
+
// Load initial data
|
|
299
|
+
loadData()
|
|
300
|
+
}, [])
|
|
301
|
+
|
|
302
|
+
const loadData = async () => {
|
|
303
|
+
const threads = await actions.getThreads({ pageSize: 20 })
|
|
304
|
+
const user = await actions.getUser()
|
|
305
|
+
console.log({ threads, user })
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return (
|
|
309
|
+
<div>
|
|
310
|
+
<h1>Dashboard</h1>
|
|
311
|
+
<p>Region: {currentRegion}</p>
|
|
312
|
+
<p>API: {API_URL}</p>
|
|
313
|
+
{/* Your app content */}
|
|
314
|
+
</div>
|
|
315
|
+
)
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
export default App
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## 🔥 Benefits
|
|
322
|
+
|
|
323
|
+
✅ **Single Entry Point** - One provider to rule them all
|
|
324
|
+
✅ **Type-Safe** - Full TypeScript support throughout
|
|
325
|
+
✅ **Flexible URLs** - Switch environments/regions on the fly
|
|
326
|
+
✅ **Regional Routing** - Automatic geo-based server selection
|
|
327
|
+
✅ **Admin Controls** - Runtime configuration without rebuilds
|
|
328
|
+
✅ **Zero Boilerplate** - All API calls pre-configured with auth
|
|
329
|
+
✅ **Production Ready** - Enterprise-grade architecture
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
@use "./breakpoints.scss";
|
|
2
|
+
@use "./toRem.scss";
|
|
3
|
+
|
|
4
|
+
.ossLink,
|
|
5
|
+
.oss {
|
|
6
|
+
display: flex;
|
|
7
|
+
align-items: center;
|
|
8
|
+
gap: 5px;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.ossWrapper {
|
|
12
|
+
margin-bottom: toRem.toRem(20);
|
|
13
|
+
display: flex;
|
|
14
|
+
flex-direction: column;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.ossContainer {
|
|
18
|
+
display: flex;
|
|
19
|
+
gap: 15px;
|
|
20
|
+
flex-direction: column;
|
|
21
|
+
|
|
22
|
+
@media (min-width: breakpoints.$breakpoint-mobile) {
|
|
23
|
+
flex-direction: row;
|
|
24
|
+
align-items: center;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.apps {
|
|
29
|
+
display: flex;
|
|
30
|
+
flex-wrap: wrap;
|
|
31
|
+
gap: toRem.toRem(15);
|
|
32
|
+
margin: toRem.toRem(15) 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.app {
|
|
36
|
+
flex: 1;
|
|
37
|
+
min-width: toRem.toRem(200);
|
|
38
|
+
padding: toRem.toRem(15);
|
|
39
|
+
border: 1px dashed var(--shade-2);
|
|
40
|
+
border-radius: toRem.toRem(20);
|
|
41
|
+
|
|
42
|
+
transition: border-color 0.3s ease;
|
|
43
|
+
|
|
44
|
+
&:hover {
|
|
45
|
+
border: 1px solid var(--accent-1);
|
|
46
|
+
background-color: var(--shade-1);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
h4 {
|
|
50
|
+
margin: 0;
|
|
51
|
+
font-size: toRem.toRem(15);
|
|
52
|
+
margin-bottom: toRem.toRem(8);
|
|
53
|
+
display: flex;
|
|
54
|
+
align-items: center;
|
|
55
|
+
gap: toRem.toRem(5);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.signInButton {
|
|
60
|
+
margin-left: auto;
|
|
61
|
+
font-size: 13px;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.appDescription {
|
|
65
|
+
font-size: toRem.toRem(13);
|
|
66
|
+
color: var(--shade-6);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.video {
|
|
70
|
+
width: 100%;
|
|
71
|
+
max-width: 100%;
|
|
72
|
+
margin-top: toRem.toRem(10);
|
|
73
|
+
border-radius: toRem.toRem(10);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.copyright {
|
|
77
|
+
margin-bottom: toRem.toRem(20);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.about {
|
|
81
|
+
section {
|
|
82
|
+
font-size: toRem.toRem(15);
|
|
83
|
+
h2,
|
|
84
|
+
h3 {
|
|
85
|
+
display: flex;
|
|
86
|
+
align-items: center;
|
|
87
|
+
gap: 5px;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.oss {
|
|
93
|
+
flex-direction: row;
|
|
94
|
+
flex-wrap: wrap;
|
|
95
|
+
gap: 20px;
|
|
96
|
+
> li {
|
|
97
|
+
> a {
|
|
98
|
+
svg {
|
|
99
|
+
color: var(--foreground);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.lastUpdated {
|
|
106
|
+
font-size: toRem.toRem(13);
|
|
107
|
+
color: var(--shade-6);
|
|
108
|
+
display: flex;
|
|
109
|
+
align-items: center;
|
|
110
|
+
gap: toRem.toRem(5);
|
|
111
|
+
margin-top: toRem.toRem(20);
|
|
112
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
@use "./toRem.scss";
|
|
2
|
+
|
|
3
|
+
.accountButton {
|
|
4
|
+
display: flex;
|
|
5
|
+
align-items: center;
|
|
6
|
+
gap: toRem.toRem(5);
|
|
7
|
+
padding: toRem.toRem(5) toRem.toRem(10);
|
|
8
|
+
background-color: var(--background);
|
|
9
|
+
border: toRem.toRem(1) solid var(--shade-2);
|
|
10
|
+
box-shadow: none;
|
|
11
|
+
color: var(--foreground);
|
|
12
|
+
svg {
|
|
13
|
+
stroke: var(--accent-6);
|
|
14
|
+
}
|
|
15
|
+
&:hover,
|
|
16
|
+
&:disabled {
|
|
17
|
+
background-color: var(--background);
|
|
18
|
+
|
|
19
|
+
svg {
|
|
20
|
+
stroke: var(--accent-5);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
color: var(--shade-6);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.userNameContainer {
|
|
28
|
+
display: flex;
|
|
29
|
+
align-items: center;
|
|
30
|
+
gap: toRem.toRem(5);
|
|
31
|
+
margin: toRem.toRem(10) 0 toRem.toRem(5) 0;
|
|
32
|
+
|
|
33
|
+
input {
|
|
34
|
+
flex: 1;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.email {
|
|
39
|
+
display: flex;
|
|
40
|
+
align-items: center;
|
|
41
|
+
gap: toRem.toRem(10);
|
|
42
|
+
}
|
|
43
|
+
.deleteAccountButton {
|
|
44
|
+
margin-left: auto;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.userImageContainer {
|
|
48
|
+
position: relative;
|
|
49
|
+
display: flex;
|
|
50
|
+
align-items: center;
|
|
51
|
+
gap: toRem.toRem(10);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.userImageWrapper {
|
|
55
|
+
display: flex;
|
|
56
|
+
align-items: center;
|
|
57
|
+
gap: toRem.toRem(10);
|
|
58
|
+
position: relative;
|
|
59
|
+
cursor: pointer;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.userImage {
|
|
63
|
+
border-radius: 50%;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.editImageButton {
|
|
67
|
+
padding: toRem.toRem(3) !important;
|
|
68
|
+
position: absolute;
|
|
69
|
+
bottom: toRem.toRem(-4);
|
|
70
|
+
right: toRem.toRem(-5);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.deleteAccount {
|
|
74
|
+
display: flex;
|
|
75
|
+
align-items: flex-end;
|
|
76
|
+
justify-content: flex-end;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.accountContainer {
|
|
80
|
+
display: flex;
|
|
81
|
+
flex-direction: column;
|
|
82
|
+
gap: toRem.toRem(10);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.header {
|
|
86
|
+
display: flex;
|
|
87
|
+
align-items: center;
|
|
88
|
+
flex-direction: row;
|
|
89
|
+
gap: toRem.toRem(15);
|
|
90
|
+
margin: 0;
|
|
91
|
+
flex: 1;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.title {
|
|
95
|
+
font-size: toRem.toRem(22);
|
|
96
|
+
flex: 1;
|
|
97
|
+
line-height: 1.2;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.close {
|
|
101
|
+
margin-left: auto;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.accounts {
|
|
105
|
+
margin-top: toRem.toRem(5);
|
|
106
|
+
display: flex;
|
|
107
|
+
align-items: flex-start;
|
|
108
|
+
flex-direction: column;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.linkAccount,
|
|
112
|
+
.accountLinked {
|
|
113
|
+
margin-bottom: toRem.toRem(10);
|
|
114
|
+
display: flex;
|
|
115
|
+
align-items: center;
|
|
116
|
+
gap: toRem.toRem(5);
|
|
117
|
+
justify-content: center;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.linkAccount {
|
|
121
|
+
margin-left: auto;
|
|
122
|
+
}
|
|
123
|
+
.cookieConsent {
|
|
124
|
+
max-width: toRem.toRem(400);
|
|
125
|
+
padding: 0;
|
|
126
|
+
border: none;
|
|
127
|
+
margin-bottom: toRem.toRem(10);
|
|
128
|
+
}
|
|
129
|
+
.accountLinked {
|
|
130
|
+
justify-content: flex-start;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.logoutButton {
|
|
134
|
+
display: flex;
|
|
135
|
+
align-items: center;
|
|
136
|
+
flex-direction: row;
|
|
137
|
+
gap: toRem.toRem(5);
|
|
138
|
+
margin-left: auto;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.actions {
|
|
142
|
+
display: flex;
|
|
143
|
+
align-items: center;
|
|
144
|
+
align-self: flex-end;
|
|
145
|
+
gap: toRem.toRem(15);
|
|
146
|
+
margin-top: toRem.toRem(5);
|
|
147
|
+
font-size: toRem.toRem(14);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@keyframes slideUp {
|
|
151
|
+
from {
|
|
152
|
+
opacity: 0;
|
|
153
|
+
transform: translateY(toRem.toRem(20)); /* Start slightly below */
|
|
154
|
+
}
|
|
155
|
+
to {
|
|
156
|
+
opacity: 1;
|
|
157
|
+
transform: translateY(0); /* End at original position */
|
|
158
|
+
}
|
|
159
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
@use "./breakpoints.scss";
|
|
2
|
+
@use "./utils.scss";
|
|
3
|
+
|
|
4
|
+
.addToHomeScreen {
|
|
5
|
+
height: 100vh;
|
|
6
|
+
width: 100vw;
|
|
7
|
+
display: flex;
|
|
8
|
+
top: 0;
|
|
9
|
+
left: 0;
|
|
10
|
+
flex-direction: column;
|
|
11
|
+
justify-content: center;
|
|
12
|
+
align-items: center;
|
|
13
|
+
z-index: 1001;
|
|
14
|
+
position: fixed;
|
|
15
|
+
background: var(--overlay);
|
|
16
|
+
|
|
17
|
+
.main {
|
|
18
|
+
margin: 0 auto;
|
|
19
|
+
width: auto;
|
|
20
|
+
padding: 0 10px;
|
|
21
|
+
z-index: 3;
|
|
22
|
+
position: relative;
|
|
23
|
+
flex: 1;
|
|
24
|
+
flex-direction: column;
|
|
25
|
+
display: flex;
|
|
26
|
+
justify-content: center;
|
|
27
|
+
width: 100%;
|
|
28
|
+
|
|
29
|
+
@media (min-width: breakpoints.$breakpoint-mobile) {
|
|
30
|
+
max-width: breakpoints.$breakpoint-mobile;
|
|
31
|
+
width: inherit;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.inner {
|
|
35
|
+
animation: slideUp 0.4s ease forwards;
|
|
36
|
+
background-color: var(--background);
|
|
37
|
+
padding: 20px;
|
|
38
|
+
border-radius: 20px;
|
|
39
|
+
border: 1px solid var(--shade-2);
|
|
40
|
+
position: relative;
|
|
41
|
+
min-width: 100%;
|
|
42
|
+
display: flex;
|
|
43
|
+
flex-direction: column;
|
|
44
|
+
gap: 10px;
|
|
45
|
+
box-shadow: var(--shadow);
|
|
46
|
+
|
|
47
|
+
@media (min-width: breakpoints.$breakpoint-mobile) {
|
|
48
|
+
flex-direction: row;
|
|
49
|
+
gap: 20px;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@media (min-width: breakpoints.$breakpoint-mobile) {
|
|
53
|
+
min-width: 320px;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.close {
|
|
57
|
+
position: absolute;
|
|
58
|
+
top: 10px;
|
|
59
|
+
right: 10px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.logoContainer {
|
|
63
|
+
display: inline-flex;
|
|
64
|
+
border-radius: 10px;
|
|
65
|
+
padding: 10px;
|
|
66
|
+
border: 1px solid var(--shade-2);
|
|
67
|
+
background-color: var(--background);
|
|
68
|
+
height: fit-content;
|
|
69
|
+
width: fit-content;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.content {
|
|
73
|
+
.icon {
|
|
74
|
+
width: 24px;
|
|
75
|
+
height: 24px;
|
|
76
|
+
}
|
|
77
|
+
> p {
|
|
78
|
+
margin: 0 0 10px 0;
|
|
79
|
+
display: flex;
|
|
80
|
+
gap: 10px;
|
|
81
|
+
align-items: center;
|
|
82
|
+
}
|
|
83
|
+
> div {
|
|
84
|
+
margin: 0 0 10px 0;
|
|
85
|
+
}
|
|
86
|
+
.addHomeScreen,
|
|
87
|
+
.addHomeScreenAndroid,
|
|
88
|
+
.share {
|
|
89
|
+
display: flex;
|
|
90
|
+
gap: 10px;
|
|
91
|
+
align-items: center;
|
|
92
|
+
border: 1px solid var(--shade-2);
|
|
93
|
+
background-color: var(--background);
|
|
94
|
+
margin-top: 10px;
|
|
95
|
+
border-radius: 10px;
|
|
96
|
+
width: fit-content;
|
|
97
|
+
padding: 5px 8px;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.addHomeScreenAndroid {
|
|
101
|
+
margin-top: 0;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.selectAddToHomeScreen {
|
|
105
|
+
display: flex;
|
|
106
|
+
gap: 10px;
|
|
107
|
+
align-items: center;
|
|
108
|
+
}
|
|
109
|
+
.quickAccess {
|
|
110
|
+
font-size: 14px;
|
|
111
|
+
}
|
|
112
|
+
.scrollDown {
|
|
113
|
+
font-weight: bold;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
@include utils.respect-reduced-motion;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.title {
|
|
122
|
+
font-size: 20px;
|
|
123
|
+
font-weight: bold;
|
|
124
|
+
margin: 0 0 10px 0;
|
|
125
|
+
}
|
|
126
|
+
}
|