@shellui/core 0.2.0 → 0.3.0-beta.1
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/package.json +9 -4
- package/src/app.tsx +12 -9
- package/src/components/ui/badge.tsx +35 -0
- package/src/components/ui/dropdown-menu.tsx +94 -0
- package/src/components/ui/sidebar.tsx +1 -1
- package/src/constants/urls.ts +8 -0
- package/src/features/admin/AdminView.tsx +154 -0
- package/src/features/admin/components/AdminForbiddenAccess.tsx +10 -0
- package/src/features/auth/AuthProvider.tsx +464 -0
- package/src/features/auth/backends/index.ts +41 -0
- package/src/features/auth/backends/shellui.ts +278 -0
- package/src/features/auth/backends/supabase.ts +300 -0
- package/src/features/auth/backends/types.ts +30 -0
- package/src/features/auth/components/LoginButton.tsx +360 -0
- package/src/features/auth/components/LoginButtonIcons.tsx +48 -0
- package/src/features/auth/components/LoginView.tsx +721 -0
- package/src/features/auth/components/OAuthCallbackView.tsx +119 -0
- package/src/features/auth/hooks/useAuth.tsx +37 -0
- package/src/features/auth/types.ts +51 -0
- package/src/features/auth/utils/buildSessionFromParams.spec.ts +61 -0
- package/src/features/auth/utils/buildSessionFromParams.ts +79 -0
- package/src/features/auth/utils/clearStoredAuthSession.spec.ts +23 -0
- package/src/features/auth/utils/clearStoredAuthSession.ts +10 -0
- package/src/features/auth/utils/clientLoginContext.spec.ts +83 -0
- package/src/features/auth/utils/clientLoginContext.ts +89 -0
- package/src/features/auth/utils/decodeJwtPayload.spec.ts +17 -0
- package/src/features/auth/utils/decodeJwtPayload.ts +24 -0
- package/src/features/auth/utils/formatProviderLabel.spec.ts +19 -0
- package/src/features/auth/utils/formatProviderLabel.ts +11 -0
- package/src/features/auth/utils/getOAuthProviderCandidates.spec.ts +16 -0
- package/src/features/auth/utils/getOAuthProviderCandidates.ts +15 -0
- package/src/features/auth/utils/getPreferredBackendProvider.spec.ts +15 -0
- package/src/features/auth/utils/getPreferredBackendProvider.ts +10 -0
- package/src/features/auth/utils/getProviderVisual.spec.ts +30 -0
- package/src/features/auth/utils/getProviderVisual.ts +83 -0
- package/src/features/auth/utils/getUserFromSdkSettings.spec.ts +32 -0
- package/src/features/auth/utils/getUserFromSdkSettings.ts +13 -0
- package/src/features/auth/utils/index.ts +21 -0
- package/src/features/auth/utils/isLoginMethod.spec.ts +18 -0
- package/src/features/auth/utils/isLoginMethod.ts +5 -0
- package/src/features/auth/utils/isSessionExpired.spec.ts +23 -0
- package/src/features/auth/utils/isSessionExpired.ts +5 -0
- package/src/features/auth/utils/normalizeAuthSettings.spec.ts +60 -0
- package/src/features/auth/utils/normalizeAuthSettings.ts +71 -0
- package/src/features/auth/utils/normalizeNextPath.spec.ts +21 -0
- package/src/features/auth/utils/normalizeNextPath.ts +12 -0
- package/src/features/auth/utils/normalizeRedirectPath.spec.ts +12 -0
- package/src/features/auth/utils/normalizeRedirectPath.ts +3 -0
- package/src/features/auth/utils/persistAuthSession.spec.ts +35 -0
- package/src/features/auth/utils/persistAuthSession.ts +12 -0
- package/src/features/auth/utils/readStoredAuthSession.spec.ts +34 -0
- package/src/features/auth/utils/readStoredAuthSession.ts +14 -0
- package/src/features/auth/utils/toAuthSessionFromSettingsUser.spec.ts +76 -0
- package/src/features/auth/utils/toAuthSessionFromSettingsUser.ts +36 -0
- package/src/features/config/types.ts +55 -0
- package/src/features/layouts/AppLayout.tsx +8 -6
- package/src/features/layouts/appbar/AppBarLayout.tsx +42 -23
- package/src/features/layouts/fullscreen/FullscreenLayout.tsx +3 -2
- package/src/features/layouts/sidebar/SidebarInner.tsx +7 -5
- package/src/features/layouts/sidebar/SidebarLayout.tsx +16 -3
- package/src/features/layouts/utils.ts +54 -0
- package/src/features/layouts/windows/WindowsLayout.tsx +22 -4
- package/src/features/legal/LegalDocumentContent.tsx +102 -0
- package/src/features/legal/LegalDocumentView.tsx +42 -0
- package/src/features/legal/LegalDocumentsIndexView.tsx +51 -0
- package/src/features/legal/LegalDocumentsLinks.tsx +29 -0
- package/src/features/legal/legalDocuments.ts +62 -0
- package/src/features/settings/SettingsIcons.tsx +20 -0
- package/src/features/settings/SettingsProvider.tsx +347 -245
- package/src/features/settings/SettingsRoutes.tsx +8 -0
- package/src/features/settings/SettingsView.tsx +43 -8
- package/src/features/settings/components/Develop.tsx +2 -2
- package/src/features/settings/components/LegalDocumentsPanel.tsx +46 -0
- package/src/features/settings/components/UserIcon.tsx +20 -0
- package/src/features/settings/components/UserSettingsPanel.tsx +438 -0
- package/src/features/settings/components/createUserSettingsRoute.tsx +43 -0
- package/src/features/settings/utils/buildSettingsForPropagation.spec.ts +167 -0
- package/src/features/settings/utils/buildSettingsForPropagation.ts +61 -0
- package/src/features/settings/utils/flattenNavigationItems.spec.ts +17 -0
- package/src/features/settings/utils/flattenNavigationItems.ts +12 -0
- package/src/features/settings/utils/getAvailableThemesForSettings.spec.ts +15 -0
- package/src/features/settings/utils/getAvailableThemesForSettings.ts +16 -0
- package/src/features/settings/utils/getBrowserTimezone.spec.ts +11 -0
- package/src/features/settings/utils/getBrowserTimezone.ts +7 -0
- package/src/features/settings/utils/getPreferenceSnapshot.spec.ts +35 -0
- package/src/features/settings/utils/getPreferenceSnapshot.ts +10 -0
- package/src/features/settings/utils/getResolvedAppearanceForSettings.spec.ts +97 -0
- package/src/features/settings/utils/getResolvedAppearanceForSettings.ts +48 -0
- package/src/features/settings/utils/index.ts +12 -0
- package/src/features/settings/utils/isSameUser.spec.ts +35 -0
- package/src/features/settings/utils/isSameUser.ts +17 -0
- package/src/features/settings/utils/mergePreferencesIntoSettings.spec.ts +108 -0
- package/src/features/settings/utils/mergePreferencesIntoSettings.ts +47 -0
- package/src/features/settings/utils/resolveColorMode.spec.ts +29 -0
- package/src/features/settings/utils/resolveColorMode.ts +6 -0
- package/src/features/settings/utils/resolveLabel.spec.ts +17 -0
- package/src/features/settings/utils/resolveLabel.ts +7 -0
- package/src/features/settings/utils/toAbsoluteFontUrls.spec.ts +26 -0
- package/src/features/settings/utils/toAbsoluteFontUrls.ts +15 -0
- package/src/features/settings/utils/toSettingsUser.spec.ts +49 -0
- package/src/features/settings/utils/toSettingsUser.ts +15 -0
- package/src/i18n/translations/en/common.json +14 -0
- package/src/i18n/translations/en/settings.json +45 -0
- package/src/i18n/translations/fr/common.json +14 -0
- package/src/i18n/translations/fr/settings.json +45 -0
- package/src/index.css +37 -0
- package/src/index.ts +6 -0
- package/src/routes/components/NavigationItemRoute.tsx +32 -1
- package/src/routes/components/NotFoundView.tsx +13 -3
- package/src/routes/hooks/useNavigationItems.ts +19 -4
- package/src/routes/routes.tsx +87 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Link, useLocation } from 'react-router';
|
|
2
|
+
import { useConfig } from '../config/useConfig';
|
|
3
|
+
import { getLegalDocuments } from './legalDocuments';
|
|
4
|
+
import { LegalDocumentContent } from './LegalDocumentContent';
|
|
5
|
+
import urls from '../../constants/urls';
|
|
6
|
+
|
|
7
|
+
export const LegalDocumentView = () => {
|
|
8
|
+
const { config } = useConfig();
|
|
9
|
+
const location = useLocation();
|
|
10
|
+
const legalDocuments = getLegalDocuments(config);
|
|
11
|
+
const selectedDocument = legalDocuments.find((item) => item.path === location.pathname);
|
|
12
|
+
|
|
13
|
+
if (!selectedDocument) {
|
|
14
|
+
return (
|
|
15
|
+
<main className="mx-auto w-full max-w-4xl p-6">
|
|
16
|
+
<h1
|
|
17
|
+
className="text-2xl font-semibold"
|
|
18
|
+
style={{ fontFamily: 'var(--heading-font-family, inherit)' }}
|
|
19
|
+
>
|
|
20
|
+
Legal documents
|
|
21
|
+
</h1>
|
|
22
|
+
<p className="mt-2 text-sm text-muted-foreground">
|
|
23
|
+
No legal document is configured for this page.
|
|
24
|
+
</p>
|
|
25
|
+
</main>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<main className="mx-auto w-full max-w-4xl p-6">
|
|
31
|
+
<div className="mb-4">
|
|
32
|
+
<Link
|
|
33
|
+
to={urls.login}
|
|
34
|
+
className="text-sm text-primary hover:underline"
|
|
35
|
+
>
|
|
36
|
+
Back to login
|
|
37
|
+
</Link>
|
|
38
|
+
</div>
|
|
39
|
+
<LegalDocumentContent document={selectedDocument} />
|
|
40
|
+
</main>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Link } from 'react-router';
|
|
2
|
+
import urls from '../../constants/urls';
|
|
3
|
+
import { useConfig } from '../config/useConfig';
|
|
4
|
+
import { getLegalDocuments } from './legalDocuments';
|
|
5
|
+
|
|
6
|
+
export const LegalDocumentsIndexView = () => {
|
|
7
|
+
const { config } = useConfig();
|
|
8
|
+
const legalDocuments = getLegalDocuments(config);
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<main className="mx-auto w-full max-w-4xl p-6">
|
|
12
|
+
<div className="space-y-2">
|
|
13
|
+
<h1
|
|
14
|
+
className="text-2xl font-semibold tracking-tight"
|
|
15
|
+
style={{ fontFamily: 'var(--heading-font-family, inherit)' }}
|
|
16
|
+
>
|
|
17
|
+
Legal documents
|
|
18
|
+
</h1>
|
|
19
|
+
<p className="text-sm text-muted-foreground">Select a document to view its full content.</p>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
{legalDocuments.length === 0 ? (
|
|
23
|
+
<p className="mt-6 text-sm text-muted-foreground">
|
|
24
|
+
No legal document is currently configured.
|
|
25
|
+
</p>
|
|
26
|
+
) : (
|
|
27
|
+
<ul className="mt-6 space-y-2">
|
|
28
|
+
{legalDocuments.map((document) => (
|
|
29
|
+
<li key={document.path}>
|
|
30
|
+
<Link
|
|
31
|
+
to={document.path}
|
|
32
|
+
className="text-sm font-medium text-primary underline-offset-4 hover:underline"
|
|
33
|
+
>
|
|
34
|
+
{document.title}
|
|
35
|
+
</Link>
|
|
36
|
+
</li>
|
|
37
|
+
))}
|
|
38
|
+
</ul>
|
|
39
|
+
)}
|
|
40
|
+
|
|
41
|
+
<div className="mt-8">
|
|
42
|
+
<Link
|
|
43
|
+
to={urls.login}
|
|
44
|
+
className="text-sm text-primary hover:underline"
|
|
45
|
+
>
|
|
46
|
+
Back to login
|
|
47
|
+
</Link>
|
|
48
|
+
</div>
|
|
49
|
+
</main>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Link } from 'react-router';
|
|
2
|
+
import { useConfig } from '../config/useConfig';
|
|
3
|
+
import { getLegalDocuments } from './legalDocuments';
|
|
4
|
+
|
|
5
|
+
export const LegalDocumentsLinks = () => {
|
|
6
|
+
const { config } = useConfig();
|
|
7
|
+
const legalDocuments = getLegalDocuments(config);
|
|
8
|
+
|
|
9
|
+
if (legalDocuments.length === 0) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<nav
|
|
15
|
+
aria-label="Legal links"
|
|
16
|
+
className="flex flex-wrap gap-x-4 gap-y-2 text-xs text-muted-foreground"
|
|
17
|
+
>
|
|
18
|
+
{legalDocuments.map((document) => (
|
|
19
|
+
<Link
|
|
20
|
+
key={document.path}
|
|
21
|
+
to={document.path}
|
|
22
|
+
className="hover:text-foreground hover:underline"
|
|
23
|
+
>
|
|
24
|
+
{document.title}
|
|
25
|
+
</Link>
|
|
26
|
+
))}
|
|
27
|
+
</nav>
|
|
28
|
+
);
|
|
29
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { ShellUIConfig } from '../config/types';
|
|
2
|
+
import urls from '../../constants/urls';
|
|
3
|
+
|
|
4
|
+
export type LegalDocumentKey =
|
|
5
|
+
| 'privacyPolicy'
|
|
6
|
+
| 'termsOfService'
|
|
7
|
+
| 'legalNotice'
|
|
8
|
+
| 'dataProcessingAgreement';
|
|
9
|
+
|
|
10
|
+
export type LegalDocumentDescriptor = {
|
|
11
|
+
key: LegalDocumentKey;
|
|
12
|
+
title: string;
|
|
13
|
+
path: string;
|
|
14
|
+
filename: string;
|
|
15
|
+
content: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type LegalDocumentDefinition = Omit<LegalDocumentDescriptor, 'content'>;
|
|
19
|
+
|
|
20
|
+
const LEGAL_DOCUMENT_DEFINITIONS: LegalDocumentDefinition[] = [
|
|
21
|
+
{
|
|
22
|
+
key: 'privacyPolicy',
|
|
23
|
+
title: 'Privacy Policy',
|
|
24
|
+
path: urls.legalPrivacyPolicy,
|
|
25
|
+
filename: 'privacy-policy.md',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
key: 'termsOfService',
|
|
29
|
+
title: 'Terms of Service',
|
|
30
|
+
path: urls.legalTermsOfService,
|
|
31
|
+
filename: 'terms-of-service.md',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
key: 'legalNotice',
|
|
35
|
+
title: 'Legal Notice',
|
|
36
|
+
path: urls.legalNotice,
|
|
37
|
+
filename: 'legal-notice.md',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
key: 'dataProcessingAgreement',
|
|
41
|
+
title: 'Data Processing Agreement',
|
|
42
|
+
path: urls.legalDataProcessingAgreement,
|
|
43
|
+
filename: 'data-processing-agreement.md',
|
|
44
|
+
},
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
export const getLegalDocuments = (config: ShellUIConfig): LegalDocumentDescriptor[] => {
|
|
48
|
+
const legalConfig = config.legalDocuments;
|
|
49
|
+
if (!legalConfig) return [];
|
|
50
|
+
const documents: LegalDocumentDescriptor[] = [];
|
|
51
|
+
for (const definition of LEGAL_DOCUMENT_DEFINITIONS) {
|
|
52
|
+
const content = legalConfig[definition.key];
|
|
53
|
+
if (typeof content !== 'string') continue;
|
|
54
|
+
const trimmedContent = content.trim();
|
|
55
|
+
if (!trimmedContent) continue;
|
|
56
|
+
documents.push({
|
|
57
|
+
...definition,
|
|
58
|
+
content: trimmedContent,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return documents;
|
|
62
|
+
};
|
|
@@ -450,3 +450,23 @@ export const PackageIcon = () => (
|
|
|
450
450
|
<path d="M12 22V12" />
|
|
451
451
|
</svg>
|
|
452
452
|
);
|
|
453
|
+
|
|
454
|
+
export const FileTextIcon = () => (
|
|
455
|
+
<svg
|
|
456
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
457
|
+
width="16"
|
|
458
|
+
height="16"
|
|
459
|
+
viewBox="0 0 24 24"
|
|
460
|
+
fill="none"
|
|
461
|
+
stroke="currentColor"
|
|
462
|
+
strokeWidth="2"
|
|
463
|
+
strokeLinecap="round"
|
|
464
|
+
strokeLinejoin="round"
|
|
465
|
+
>
|
|
466
|
+
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
|
|
467
|
+
<path d="M14 2v6h6" />
|
|
468
|
+
<path d="M16 13H8" />
|
|
469
|
+
<path d="M16 17H8" />
|
|
470
|
+
<path d="M10 9H8" />
|
|
471
|
+
</svg>
|
|
472
|
+
);
|