@mr.dj2u/library-registry 0.1.0 → 0.3.0

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.
Files changed (91) hide show
  1. package/README.md +3 -0
  2. package/assets/mds/env/convex.env.example +1 -0
  3. package/assets/mds/env/firebase.env.example +6 -0
  4. package/assets/mds/env/supabase.env.example +3 -0
  5. package/assets/mds/project/auth-base.md +17 -0
  6. package/assets/mds/project/auth-convex.md +33 -0
  7. package/assets/mds/project/auth-firebase.md +22 -0
  8. package/assets/mds/project/auth-supabase.md +46 -0
  9. package/assets/mds/src/app/(auth)/reset-password.tsx +5 -0
  10. package/assets/mds/src/app/(auth)/sign-in.tsx +5 -0
  11. package/assets/mds/src/app/(auth)/sign-up.tsx +5 -0
  12. package/assets/mds/src/app/legal/updates.tsx +1 -0
  13. package/assets/mds/src/app/onboarding/complete.tsx +2 -0
  14. package/assets/mds/src/app/onboarding/features.tsx +1 -0
  15. package/assets/mds/src/app/onboarding/legal-agreement.tsx +9 -0
  16. package/assets/mds/src/app/onboarding/legal.tsx +2 -0
  17. package/assets/mds/src/app/onboarding.tsx +1 -1
  18. package/assets/mds/src/app/privacy.tsx +5 -0
  19. package/assets/mds/src/app/settings.tsx +10 -1
  20. package/assets/mds/src/app/terms.tsx +5 -0
  21. package/assets/mds/src/db/adapter.ts +195 -0
  22. package/assets/mds/src/db/firebase.ts +77 -0
  23. package/assets/mds/src/db/index.firebase.ts +19 -0
  24. package/assets/mds/src/db/index.supabase.ts +22 -0
  25. package/assets/mds/src/db/supabase.ts +337 -0
  26. package/assets/mds/src/features/auth/adapters/base-auth-adapter.tsx +82 -0
  27. package/assets/mds/src/features/auth/adapters/convex-auth-adapter.tsx +156 -0
  28. package/assets/mds/src/features/auth/adapters/firebase-auth-adapter.tsx +147 -0
  29. package/assets/mds/src/features/auth/adapters/supabase-auth-adapter.tsx +166 -0
  30. package/assets/mds/src/features/auth/auth-guard-logic.ts +19 -0
  31. package/assets/mds/src/features/auth/auth-guard.tsx +77 -0
  32. package/assets/mds/src/features/auth/auth-provider.tsx +60 -0
  33. package/assets/mds/src/features/auth/auth-screen.tsx +265 -0
  34. package/assets/mds/src/features/auth/auth-types.ts +45 -0
  35. package/assets/mds/src/features/exposition/data-screen.tsx +4 -2
  36. package/assets/mds/src/features/exposition/expo-sdk-56-screen.tsx +119 -76
  37. package/assets/mds/src/features/exposition/exposition-screen.tsx +10 -11
  38. package/assets/mds/src/features/exposition/stylist-screen.tsx +62 -11
  39. package/assets/mds/src/features/legal/legal-acceptance-adapter.ts +190 -0
  40. package/assets/mds/src/features/legal/legal-acceptance-config.ts +79 -0
  41. package/assets/mds/src/features/legal/legal-agreement-screen.tsx +203 -0
  42. package/assets/mds/src/features/legal/legal-document-links.tsx +85 -0
  43. package/assets/mds/src/features/legal/legal-document-modal.tsx +121 -0
  44. package/assets/mds/src/features/legal/legal-document-view.tsx +231 -0
  45. package/assets/mds/src/features/legal/legal-documents.ts +148 -0
  46. package/assets/mds/src/features/legal/legal-page-route.tsx +10 -0
  47. package/assets/mds/src/features/legal/legal-update-screen.tsx +297 -0
  48. package/assets/mds/src/features/legal/use-legal-acceptance.ts +5 -0
  49. package/assets/mds/src/features/onboarding/complete-screen.tsx +138 -0
  50. package/assets/mds/src/features/onboarding/features-screen.tsx +129 -0
  51. package/assets/mds/src/features/onboarding/legal-review-screen.tsx +242 -0
  52. package/assets/mds/src/features/onboarding/onboarding-config-with-legal.ts +104 -0
  53. package/assets/mds/src/features/onboarding/onboarding-config.ts +104 -0
  54. package/assets/mds/src/features/onboarding/onboarding-persistence-sync.tsx +1 -0
  55. package/assets/mds/src/features/onboarding/welcome-screen.tsx +130 -0
  56. package/assets/mds/src/features/onboarding-state/adapters/memory-onboarding-state-adapter.ts +15 -0
  57. package/assets/mds/src/features/onboarding-state/adapters/supabase-onboarding-state-adapter.ts +45 -0
  58. package/assets/mds/src/features/onboarding-state/adapters/zustand-onboarding-state-adapter.ts +16 -0
  59. package/assets/mds/src/features/onboarding-state/adapters/zustand-supabase-onboarding-state-adapter.ts +53 -0
  60. package/assets/mds/src/features/onboarding-state/onboarding-state-core.ts +108 -0
  61. package/assets/mds/src/features/onboarding-state/onboarding-state-memory.ts +106 -0
  62. package/assets/mds/src/features/onboarding-state/onboarding-state-supabase.ts +246 -0
  63. package/assets/mds/src/features/onboarding-state/onboarding-state-types.ts +64 -0
  64. package/assets/mds/src/features/onboarding-state/onboarding-state-zustand-supabase.ts +120 -0
  65. package/assets/mds/src/features/onboarding-state/onboarding-state-zustand.ts +71 -0
  66. package/assets/mds/src/features/onboarding-state/onboarding-state.ts +22 -0
  67. package/assets/mds/src/features/onboarding-state/onboarding-store.ts +39 -0
  68. package/assets/mds/src/features/settings/settings-screen-logic.ts +122 -0
  69. package/assets/mds/src/features/settings/settings-screen.tsx +274 -28
  70. package/assets/mds/src/services/convex.ts +40 -0
  71. package/assets/mds/src/services/firebase.ts +70 -0
  72. package/assets/mds/src/services/supabase.ts +50 -0
  73. package/assets/mds/src/theme/color-utils.ts +42 -0
  74. package/assets/mds/src/theme/provider.tsx +51 -6
  75. package/assets/mds/src/types/database.ts +13 -0
  76. package/assets/mds/supabase/migrations/0001_mds_auth_onboarding.sql +107 -0
  77. package/dist/catalog.d.ts.map +1 -1
  78. package/dist/catalog.js +535 -25
  79. package/dist/catalog.js.map +1 -1
  80. package/dist/types.d.ts +5 -1
  81. package/dist/types.d.ts.map +1 -1
  82. package/package.json +1 -1
  83. package/assets/mds/src/app/onboarding/account-setup.tsx +0 -1
  84. package/assets/mds/src/app/onboarding/agreement.tsx +0 -1
  85. package/assets/mds/src/app/onboarding/terms.tsx +0 -1
  86. package/assets/mds/src/features/onboarding/account-setup-screen.tsx +0 -54
  87. package/assets/mds/src/features/onboarding/agreement-screen.tsx +0 -6
  88. package/assets/mds/src/features/onboarding/components/legal-document-view.tsx +0 -103
  89. package/assets/mds/src/features/onboarding/legal-documents.ts +0 -80
  90. package/assets/mds/src/features/onboarding/onboarding-screen.tsx +0 -167
  91. package/assets/mds/src/features/onboarding/terms-screen.tsx +0 -6
@@ -0,0 +1,121 @@
1
+ import { Modal, Pressable, StyleSheet, Text, View } from 'react-native';
2
+ import { SafeAreaView } from 'react-native-safe-area-context';
3
+
4
+ import { getReadableTextColor } from '../../theme/color-utils';
5
+ import { useAppTheme } from '../../theme/provider';
6
+ import { LegalDocumentView } from './legal-document-view';
7
+ import { getLegalDocument, type LegalDocumentId } from './legal-documents';
8
+
9
+ interface LegalDocumentModalProps {
10
+ documentId: LegalDocumentId;
11
+ visible: boolean;
12
+ onClose: () => void;
13
+ onPrimaryAction?: () => void;
14
+ primaryActionLabel?: string;
15
+ }
16
+
17
+ export function LegalDocumentModal({
18
+ documentId,
19
+ visible,
20
+ onClose,
21
+ onPrimaryAction,
22
+ primaryActionLabel = 'Done',
23
+ }: LegalDocumentModalProps) {
24
+ const theme = useAppTheme();
25
+ const colors = theme.activeColors;
26
+ const document = getLegalDocument(documentId);
27
+ const primaryForeground = getReadableTextColor(colors.primary, theme.colors.light.text);
28
+
29
+ return (
30
+ <Modal animationType="slide" presentationStyle="pageSheet" visible={visible}>
31
+ <SafeAreaView style={[styles.screen, { backgroundColor: colors.background }]}>
32
+ <View style={[styles.header, { borderBottomColor: colors.surface }]}>
33
+ <View style={styles.headerText}>
34
+ <Text style={[styles.title, { color: colors.text }]}>{document.title}</Text>
35
+ <Text style={[styles.updated, { color: colors.text }]}>
36
+ Last updated: {document.lastUpdated}
37
+ </Text>
38
+ </View>
39
+ <Pressable
40
+ accessibilityLabel={`Close ${document.title}`}
41
+ accessibilityRole="button"
42
+ onPress={onClose}
43
+ style={[
44
+ styles.closeButton,
45
+ {
46
+ backgroundColor: colors.surface,
47
+ borderRadius: Math.max(8, theme.layout.radius - 4),
48
+ },
49
+ ]}>
50
+ <Text style={[styles.closeText, { color: colors.text }]}>X</Text>
51
+ </Pressable>
52
+ </View>
53
+ <LegalDocumentView document={document} showHeader={false} />
54
+ <View style={[styles.footer, { borderTopColor: colors.surface }]}>
55
+ <Pressable
56
+ accessibilityRole="button"
57
+ onPress={onPrimaryAction ?? onClose}
58
+ style={[
59
+ styles.primaryButton,
60
+ {
61
+ backgroundColor: colors.primary,
62
+ borderRadius: theme.layout.radius,
63
+ },
64
+ ]}>
65
+ <Text style={[styles.primaryButtonText, { color: primaryForeground }]}>
66
+ {primaryActionLabel}
67
+ </Text>
68
+ </Pressable>
69
+ </View>
70
+ </SafeAreaView>
71
+ </Modal>
72
+ );
73
+ }
74
+
75
+ const styles = StyleSheet.create({
76
+ screen: {
77
+ flex: 1,
78
+ },
79
+ header: {
80
+ alignItems: 'center',
81
+ borderBottomWidth: 1,
82
+ flexDirection: 'row',
83
+ gap: 12,
84
+ paddingHorizontal: 20,
85
+ paddingVertical: 16,
86
+ },
87
+ headerText: {
88
+ flex: 1,
89
+ gap: 3,
90
+ },
91
+ title: {
92
+ fontSize: 22,
93
+ fontWeight: '900',
94
+ },
95
+ updated: {
96
+ fontSize: 13,
97
+ lineHeight: 18,
98
+ },
99
+ closeButton: {
100
+ alignItems: 'center',
101
+ height: 40,
102
+ justifyContent: 'center',
103
+ width: 40,
104
+ },
105
+ closeText: {
106
+ fontSize: 15,
107
+ fontWeight: '900',
108
+ },
109
+ footer: {
110
+ borderTopWidth: 1,
111
+ padding: 20,
112
+ },
113
+ primaryButton: {
114
+ alignItems: 'center',
115
+ paddingVertical: 14,
116
+ },
117
+ primaryButtonText: {
118
+ fontSize: 15,
119
+ fontWeight: '900',
120
+ },
121
+ });
@@ -0,0 +1,231 @@
1
+ import type { ReactNode } from 'react';
2
+ import { ScrollView, StyleSheet, Text, View } from 'react-native';
3
+
4
+ import { useAppTheme } from '../../theme/provider';
5
+ import {
6
+ legalDocumentReplacementWarning,
7
+ type LegalDocument,
8
+ } from './legal-documents';
9
+
10
+ interface LegalDocumentViewProps {
11
+ document: LegalDocument;
12
+ footer?: ReactNode;
13
+ showHeader?: boolean;
14
+ }
15
+
16
+ function LegalDocumentMeta({ label, value }: { label: string; value: string }) {
17
+ const theme = useAppTheme();
18
+ const colors = theme.activeColors;
19
+
20
+ return (
21
+ <View
22
+ style={[
23
+ styles.metaItem,
24
+ {
25
+ backgroundColor: colors.surface,
26
+ borderColor: colors.surface,
27
+ borderRadius: theme.layout.radius,
28
+ },
29
+ ]}>
30
+ <Text style={[styles.metaLabel, { color: colors.text }]}>{label}</Text>
31
+ <Text style={[styles.metaValue, { color: colors.text }]}>{value}</Text>
32
+ </View>
33
+ );
34
+ }
35
+
36
+ function LegalSectionItem({ title, body }: { title: string; body: string[] }) {
37
+ const theme = useAppTheme();
38
+ const colors = theme.activeColors;
39
+
40
+ return (
41
+ <View
42
+ style={[
43
+ styles.section,
44
+ {
45
+ backgroundColor: colors.surface,
46
+ borderColor: colors.primary,
47
+ borderRadius: theme.layout.radius,
48
+ },
49
+ ]}>
50
+ <Text
51
+ style={[
52
+ styles.sectionTitle,
53
+ {
54
+ color: colors.text,
55
+ fontFamily: theme.typography.fontFamily,
56
+ },
57
+ ]}>
58
+ {title}
59
+ </Text>
60
+ <View style={styles.paragraphs}>
61
+ {body.map((paragraph, index) => (
62
+ <Text
63
+ key={`${title}-${index}`}
64
+ style={[
65
+ styles.sectionBody,
66
+ {
67
+ color: colors.text,
68
+ fontFamily: theme.typography.fontBody,
69
+ fontSize: theme.typography.bodySize,
70
+ },
71
+ ]}>
72
+ {paragraph}
73
+ </Text>
74
+ ))}
75
+ </View>
76
+ </View>
77
+ );
78
+ }
79
+
80
+ export function LegalDocumentView({
81
+ document,
82
+ footer,
83
+ showHeader = true,
84
+ }: LegalDocumentViewProps) {
85
+ const theme = useAppTheme();
86
+ const colors = theme.activeColors;
87
+
88
+ return (
89
+ <ScrollView
90
+ contentContainerStyle={styles.content}
91
+ style={[styles.screen, { backgroundColor: colors.background }]}>
92
+ <View style={styles.document}>
93
+ {showHeader ? (
94
+ <View style={styles.header}>
95
+ <Text
96
+ style={[
97
+ styles.title,
98
+ {
99
+ color: colors.text,
100
+ fontFamily: theme.typography.fontFamily,
101
+ },
102
+ ]}>
103
+ {document.title}
104
+ </Text>
105
+ <Text
106
+ style={[
107
+ styles.summary,
108
+ {
109
+ color: colors.text,
110
+ fontFamily: theme.typography.fontBody,
111
+ fontSize: theme.typography.bodySize,
112
+ },
113
+ ]}>
114
+ {document.summary}
115
+ </Text>
116
+ <View style={styles.metaRow}>
117
+ <LegalDocumentMeta label="Effective" value={document.effectiveDate} />
118
+ <LegalDocumentMeta label="Last updated" value={document.lastUpdated} />
119
+ <LegalDocumentMeta label="Acceptance version" value={document.acceptanceVersion} />
120
+ </View>
121
+ </View>
122
+ ) : null}
123
+
124
+ <View
125
+ style={[
126
+ styles.warning,
127
+ {
128
+ backgroundColor: colors.surface,
129
+ borderColor: colors.warning,
130
+ borderRadius: theme.layout.radius,
131
+ },
132
+ ]}>
133
+ <Text style={[styles.warningTitle, { color: colors.text }]}>Replacement required</Text>
134
+ <Text
135
+ style={[
136
+ styles.warningBody,
137
+ {
138
+ color: colors.text,
139
+ fontFamily: theme.typography.fontBody,
140
+ },
141
+ ]}>
142
+ {legalDocumentReplacementWarning}
143
+ </Text>
144
+ </View>
145
+
146
+ {document.sections.map((section) => (
147
+ <LegalSectionItem key={section.id} title={section.title} body={section.body} />
148
+ ))}
149
+ {footer}
150
+ </View>
151
+ </ScrollView>
152
+ );
153
+ }
154
+
155
+ const styles = StyleSheet.create({
156
+ screen: {
157
+ flex: 1,
158
+ },
159
+ content: {
160
+ alignItems: 'center',
161
+ flexGrow: 1,
162
+ padding: 24,
163
+ paddingBottom: 48,
164
+ paddingTop: 48,
165
+ },
166
+ document: {
167
+ gap: 16,
168
+ maxWidth: 920,
169
+ width: '100%',
170
+ },
171
+ header: {
172
+ gap: 12,
173
+ },
174
+ title: {
175
+ fontSize: 30,
176
+ fontWeight: '900',
177
+ },
178
+ summary: {
179
+ fontSize: 15,
180
+ lineHeight: 22,
181
+ },
182
+ metaRow: {
183
+ flexDirection: 'row',
184
+ flexWrap: 'wrap',
185
+ gap: 10,
186
+ },
187
+ metaItem: {
188
+ borderWidth: 1,
189
+ gap: 2,
190
+ paddingHorizontal: 12,
191
+ paddingVertical: 9,
192
+ },
193
+ metaLabel: {
194
+ fontSize: 11,
195
+ fontWeight: '800',
196
+ textTransform: 'uppercase',
197
+ },
198
+ metaValue: {
199
+ fontSize: 13,
200
+ fontWeight: '800',
201
+ },
202
+ warning: {
203
+ borderWidth: 1,
204
+ gap: 6,
205
+ padding: 14,
206
+ },
207
+ warningTitle: {
208
+ fontSize: 14,
209
+ fontWeight: '900',
210
+ },
211
+ warningBody: {
212
+ fontSize: 14,
213
+ lineHeight: 20,
214
+ },
215
+ section: {
216
+ borderWidth: 1,
217
+ gap: 10,
218
+ padding: 16,
219
+ },
220
+ sectionTitle: {
221
+ fontSize: 18,
222
+ fontWeight: '900',
223
+ },
224
+ paragraphs: {
225
+ gap: 10,
226
+ },
227
+ sectionBody: {
228
+ fontSize: 15,
229
+ lineHeight: 23,
230
+ },
231
+ });
@@ -0,0 +1,148 @@
1
+ export type LegalDocumentId = 'terms' | 'privacy';
2
+
3
+ export interface LegalDocumentSection {
4
+ id: string;
5
+ title: string;
6
+ body: string[];
7
+ }
8
+
9
+ export interface LegalDocument {
10
+ id: LegalDocumentId;
11
+ title: string;
12
+ summary: string;
13
+ effectiveDate: string;
14
+ lastUpdated: string;
15
+ acceptanceVersion: string;
16
+ requiresReacceptance: boolean;
17
+ changeSummary: string;
18
+ sections: LegalDocumentSection[];
19
+ }
20
+
21
+ export const legalDocumentReplacementWarning =
22
+ 'This placeholder legal text is not legal advice. Replace it with documents reviewed by qualified counsel before production use.';
23
+
24
+ export const legalDocuments: Record<LegalDocumentId, LegalDocument> = {
25
+ terms: {
26
+ id: 'terms',
27
+ title: 'Terms of Service',
28
+ summary:
29
+ 'Starter terms for __MDS_APP_NAME__ with common sections your legal reviewer can replace.',
30
+ effectiveDate: '2026-08-10',
31
+ lastUpdated: '2026-08-10',
32
+ acceptanceVersion: '2026-08-10',
33
+ requiresReacceptance: true,
34
+ changeSummary:
35
+ 'Initial material Terms of Service version that should be accepted before protected app access.',
36
+ sections: [
37
+ {
38
+ id: 'acceptance',
39
+ title: 'Acceptance of Terms',
40
+ body: [
41
+ 'By accessing or using __MDS_APP_NAME__, you agree to these Terms of Service.',
42
+ 'If you do not agree to these terms, do not use the app or service.',
43
+ ],
44
+ },
45
+ {
46
+ id: 'service-scope',
47
+ title: 'Service Scope',
48
+ body: [
49
+ '__MDS_APP_NAME__ provides the app features, content, workflows, and connected services described in your product documentation.',
50
+ 'Replace this section with a specific description of what your app does and what it does not provide.',
51
+ ],
52
+ },
53
+ {
54
+ id: 'accounts',
55
+ title: 'Accounts and Responsibilities',
56
+ body: [
57
+ 'You are responsible for the accuracy of information you provide and for activity that occurs through your account or device.',
58
+ 'If your app does not use accounts, replace this section with your guest, device, or local-profile expectations.',
59
+ ],
60
+ },
61
+ {
62
+ id: 'acceptable-use',
63
+ title: 'Acceptable Use',
64
+ body: [
65
+ 'Do not misuse the service, attempt unauthorized access, interfere with app operation, or use the app for unlawful activity.',
66
+ 'Add any app-specific content, community, billing, safety, or platform rules before release.',
67
+ ],
68
+ },
69
+ {
70
+ id: 'third-parties',
71
+ title: 'Third-Party Services',
72
+ body: [
73
+ 'The app may link to, integrate with, or depend on third-party services that are governed by their own terms and policies.',
74
+ 'List the providers your app actually uses, including payment, analytics, authentication, storage, or AI services.',
75
+ ],
76
+ },
77
+ {
78
+ id: 'changes-contact',
79
+ title: 'Changes and Contact',
80
+ body: [
81
+ 'These terms may be updated as product functionality, business requirements, or legal obligations change.',
82
+ '__MDS_LEGAL_BUSINESS_NAME__ is the business responsible for these terms. Direct legal questions to __MDS_LEGAL_CONTACT_EMAIL__ and replace this line with your reviewed notice workflow.',
83
+ 'Replace this placeholder with your business address, jurisdiction, and local notice requirements: __MDS_LEGAL_ADDRESS_OR_REGION_NOTE__.',
84
+ ],
85
+ },
86
+ ],
87
+ },
88
+ privacy: {
89
+ id: 'privacy',
90
+ title: 'Privacy Policy',
91
+ summary:
92
+ 'Starter privacy policy for __MDS_APP_NAME__ with common data and rights sections to replace.',
93
+ effectiveDate: '2026-08-10',
94
+ lastUpdated: '2026-08-10',
95
+ acceptanceVersion: '2026-08-10',
96
+ requiresReacceptance: true,
97
+ changeSummary:
98
+ 'Initial material Privacy Policy version that should be accepted before protected app access.',
99
+ sections: [
100
+ {
101
+ id: 'data-processed',
102
+ title: 'Data We Process',
103
+ body: [
104
+ '__MDS_APP_NAME__ may process information needed to provide app functionality, support, security, and product improvement.',
105
+ 'Replace this placeholder with the exact categories of personal, device, account, payment, analytics, and content data your app processes.',
106
+ ],
107
+ },
108
+ {
109
+ id: 'use-of-data',
110
+ title: 'How Data Is Used',
111
+ body: [
112
+ 'Data should be used only to operate the app, provide requested features, maintain security, support users, and meet legal obligations.',
113
+ 'Document any analytics, personalization, AI processing, advertising, or business communications that apply to your app.',
114
+ ],
115
+ },
116
+ {
117
+ id: 'sharing',
118
+ title: 'Sharing and Third Parties',
119
+ body: [
120
+ 'Do not claim data is never shared unless that is true for every provider and operational workflow.',
121
+ 'List the third-party processors, infrastructure providers, payment providers, analytics tools, and integrations your app uses.',
122
+ ],
123
+ },
124
+ {
125
+ id: 'retention-security',
126
+ title: 'Retention and Security',
127
+ body: [
128
+ 'Explain how long data is kept, what controls protect it, and how users or administrators can delete data when appropriate.',
129
+ 'Replace this section with retention periods, backup behavior, account deletion behavior, and incident-response commitments.',
130
+ ],
131
+ },
132
+ {
133
+ id: 'rights-contact',
134
+ title: 'Your Choices and Contact',
135
+ body: [
136
+ 'Users may have rights to access, correct, delete, export, restrict, or object to processing depending on jurisdiction, including GDPR and comparable privacy laws.',
137
+ 'For GDPR-facing flows, document your lawful bases, cross-border transfer process, retention rules, and response timelines for data-subject requests.',
138
+ 'Route privacy requests to __MDS_LEGAL_CONTACT_EMAIL__ on behalf of __MDS_LEGAL_BUSINESS_NAME__, and replace this placeholder workflow before production use.',
139
+ 'Replace this location or jurisdiction note with the reviewed business address, EU representative, or regional contact process that applies: __MDS_LEGAL_ADDRESS_OR_REGION_NOTE__.',
140
+ ],
141
+ },
142
+ ],
143
+ },
144
+ };
145
+
146
+ export function getLegalDocument(documentId: LegalDocumentId): LegalDocument {
147
+ return legalDocuments[documentId];
148
+ }
@@ -0,0 +1,10 @@
1
+ import { LegalDocumentView } from './legal-document-view';
2
+ import { getLegalDocument, type LegalDocumentId } from './legal-documents';
3
+
4
+ interface LegalDocumentRouteProps {
5
+ documentId: LegalDocumentId;
6
+ }
7
+
8
+ export function LegalDocumentRoute({ documentId }: LegalDocumentRouteProps) {
9
+ return <LegalDocumentView document={getLegalDocument(documentId)} />;
10
+ }