@jmruthers/pace-core 0.5.57 → 0.5.58
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/dist/{DataTable-GABLO6H5.js → DataTable-PEAEZ7DL.js} +5 -5
- package/dist/{chunk-77TYN5B4.js → chunk-73T26Z27.js} +3 -3
- package/dist/{chunk-CACNKQ3B.js → chunk-E4FPK232.js} +3 -3
- package/dist/{chunk-CACNKQ3B.js.map → chunk-E4FPK232.js.map} +1 -1
- package/dist/{chunk-JO3Y2BOW.js → chunk-HLMLK5RD.js} +5 -5
- package/dist/{chunk-DH7VDOQQ.js → chunk-HSK6AJKC.js} +3 -3
- package/dist/{chunk-D3X2CGAG.js → chunk-ITPVFKDH.js} +2 -2
- package/dist/{chunk-VY3DOGPU.js → chunk-N53OLPMT.js} +4 -4
- package/dist/{chunk-S3MPG3BA.js → chunk-NT3NC4Y4.js} +5 -5
- package/dist/{chunk-S3MPG3BA.js.map → chunk-NT3NC4Y4.js.map} +1 -1
- package/dist/{chunk-E3ITLZBM.js → chunk-RYRGIDBD.js} +3 -3
- package/dist/{chunk-TCX7STCC.js → chunk-W7PPXKTZ.js} +2 -2
- package/dist/{chunk-YI25YXER.js → chunk-ZIC232OO.js} +28 -13
- package/dist/chunk-ZIC232OO.js.map +1 -0
- package/dist/components.js +7 -7
- package/dist/hooks.js +4 -4
- package/dist/index.js +10 -10
- package/dist/providers.js +3 -3
- package/dist/rbac/index.js +5 -5
- package/dist/types.d.ts +7 -1
- package/dist/utils.js +1 -1
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.md +1 -1
- package/docs/api/classes/MissingUserContextError.md +1 -1
- package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
- package/docs/api/classes/PermissionDeniedError.md +1 -1
- package/docs/api/classes/PublicErrorBoundary.md +1 -1
- package/docs/api/classes/RBACAuditManager.md +1 -1
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +1 -1
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +1 -1
- package/docs/api/classes/SecureSupabaseClient.md +1 -1
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +1 -1
- package/docs/api/interfaces/ButtonProps.md +1 -1
- package/docs/api/interfaces/CardProps.md +1 -1
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/DataAccessRecord.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +1 -1
- package/docs/api/interfaces/DataTableColumn.md +1 -1
- package/docs/api/interfaces/DataTableProps.md +1 -1
- package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
- package/docs/api/interfaces/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventContextType.md +1 -1
- package/docs/api/interfaces/EventLogoProps.md +1 -1
- package/docs/api/interfaces/EventProviderProps.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadProps.md +1 -1
- package/docs/api/interfaces/FooterProps.md +1 -1
- package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
- package/docs/api/interfaces/InputProps.md +1 -1
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
- package/docs/api/interfaces/NavigationContextType.md +1 -1
- package/docs/api/interfaces/NavigationGuardProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +1 -1
- package/docs/api/interfaces/NavigationMenuProps.md +1 -1
- package/docs/api/interfaces/NavigationProviderProps.md +1 -1
- package/docs/api/interfaces/Organisation.md +1 -1
- package/docs/api/interfaces/OrganisationContextType.md +1 -1
- package/docs/api/interfaces/OrganisationMembership.md +1 -1
- package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
- package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
- package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
- package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
- package/docs/api/interfaces/PageAccessRecord.md +1 -1
- package/docs/api/interfaces/PagePermissionContextType.md +1 -1
- package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
- package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
- package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
- package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
- package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
- package/docs/api/interfaces/RBACConfig.md +1 -1
- package/docs/api/interfaces/RBACContextType.md +1 -1
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RBACProviderProps.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +1 -1
- package/docs/api/interfaces/RouteConfig.md +1 -1
- package/docs/api/interfaces/SecureDataContextType.md +1 -1
- package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
- package/docs/api/interfaces/StorageConfig.md +1 -1
- package/docs/api/interfaces/StorageFileInfo.md +1 -1
- package/docs/api/interfaces/StorageFileMetadata.md +1 -1
- package/docs/api/interfaces/StorageListOptions.md +1 -1
- package/docs/api/interfaces/StorageListResult.md +1 -1
- package/docs/api/interfaces/StorageUploadOptions.md +1 -1
- package/docs/api/interfaces/StorageUploadResult.md +1 -1
- package/docs/api/interfaces/StorageUrlOptions.md +1 -1
- package/docs/api/interfaces/StyleImport.md +1 -1
- package/docs/api/interfaces/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +1 -1
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +2 -2
- package/docs/getting-started/quick-start.md +21 -3
- package/docs/rbac/getting-started.md +43 -0
- package/docs/troubleshooting/common-issues.md +116 -1516
- package/package.json +1 -1
- package/src/__tests__/TESTING_GUIDELINES.md +1 -1
- package/src/hooks/__tests__/useRBAC.unit.test.ts +8 -8
- package/src/providers/EventProvider.tsx +31 -17
- package/src/providers/OrganisationProvider.tsx +2 -2
- package/src/rbac/hooks/useRBAC.ts +2 -2
- package/src/types/supabase.ts +17 -0
- package/dist/chunk-YI25YXER.js.map +0 -1
- /package/dist/{DataTable-GABLO6H5.js.map → DataTable-PEAEZ7DL.js.map} +0 -0
- /package/dist/{chunk-77TYN5B4.js.map → chunk-73T26Z27.js.map} +0 -0
- /package/dist/{chunk-JO3Y2BOW.js.map → chunk-HLMLK5RD.js.map} +0 -0
- /package/dist/{chunk-DH7VDOQQ.js.map → chunk-HSK6AJKC.js.map} +0 -0
- /package/dist/{chunk-D3X2CGAG.js.map → chunk-ITPVFKDH.js.map} +0 -0
- /package/dist/{chunk-VY3DOGPU.js.map → chunk-N53OLPMT.js.map} +0 -0
- /package/dist/{chunk-E3ITLZBM.js.map → chunk-RYRGIDBD.js.map} +0 -0
- /package/dist/{chunk-TCX7STCC.js.map → chunk-W7PPXKTZ.js.map} +0 -0
|
@@ -1,1563 +1,163 @@
|
|
|
1
|
-
# Common Issues
|
|
1
|
+
# Common Issues & Solutions
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## 🚨 **Critical Setup Issues**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
### Issue 1: "RPC call timeout after 10 seconds" / "Loading organisation context..." hangs
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
**Symptoms:**
|
|
8
|
+
- App hangs on "Loading organisation context..."
|
|
9
|
+
- Console shows "RPC call timeout after 10 seconds"
|
|
10
|
+
- No error messages, just infinite loading
|
|
8
11
|
|
|
9
|
-
**
|
|
12
|
+
**Root Cause:** Wrong API key or missing RBAC setup
|
|
10
13
|
|
|
11
|
-
**
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
/>
|
|
22
|
-
|
|
23
|
-
// ✅ CORRECT - NavigationMenu with authentication context
|
|
24
|
-
<UnifiedAuthProvider supabaseClient={supabase} appName="My App">
|
|
25
|
-
<OrganisationProvider>
|
|
26
|
-
<EventProvider>
|
|
27
|
-
<PaceAppLayout
|
|
28
|
-
appName="My App"
|
|
29
|
-
navItems={navItems}
|
|
30
|
-
showEventSelector={true}
|
|
31
|
-
>
|
|
32
|
-
<Routes>
|
|
33
|
-
{/* Your routes */}
|
|
34
|
-
</Routes>
|
|
35
|
-
</PaceAppLayout>
|
|
36
|
-
</EventProvider>
|
|
37
|
-
</OrganisationProvider>
|
|
38
|
-
</UnifiedAuthProvider>
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
**Alternative Solution**: Use `NavigationMenu` directly with permission filtering:
|
|
42
|
-
|
|
43
|
-
```tsx
|
|
44
|
-
import { NavigationMenu } from '@jmruthers/pace-core';
|
|
45
|
-
import { useUnifiedAuth } from '@jmruthers/pace-core/providers';
|
|
46
|
-
|
|
47
|
-
function AuthenticatedNavigation() {
|
|
48
|
-
const { hasPermission, hasRole } = useUnifiedAuth();
|
|
49
|
-
|
|
50
|
-
const navItems = [
|
|
51
|
-
{
|
|
52
|
-
id: 'dashboard',
|
|
53
|
-
label: 'Dashboard',
|
|
54
|
-
href: '/dashboard',
|
|
55
|
-
permissions: ['dashboard:read']
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
id: 'admin',
|
|
59
|
-
label: 'Admin Panel',
|
|
60
|
-
href: '/admin',
|
|
61
|
-
roles: ['admin']
|
|
62
|
-
}
|
|
63
|
-
];
|
|
64
|
-
|
|
65
|
-
return (
|
|
66
|
-
<NavigationMenu
|
|
67
|
-
items={navItems}
|
|
68
|
-
currentPath={location.pathname}
|
|
69
|
-
onNavigate={handleNavigate}
|
|
70
|
-
filterByPermissions={true}
|
|
71
|
-
auditLog={true}
|
|
72
|
-
/>
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### NavigationMenu Items Not Filtering by Permissions
|
|
78
|
-
|
|
79
|
-
**Problem**: All navigation items are shown regardless of user permissions.
|
|
80
|
-
|
|
81
|
-
**Solution**: Enable permission filtering and add permission requirements to navigation items:
|
|
82
|
-
|
|
83
|
-
```tsx
|
|
84
|
-
// Add permissions to navigation items
|
|
85
|
-
const navItems = [
|
|
86
|
-
{
|
|
87
|
-
id: 'dashboard',
|
|
88
|
-
label: 'Dashboard',
|
|
89
|
-
href: '/dashboard',
|
|
90
|
-
permissions: ['dashboard:read'] // Required permission
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
id: 'admin',
|
|
94
|
-
label: 'Admin Panel',
|
|
95
|
-
href: '/admin',
|
|
96
|
-
roles: ['admin', 'super_admin'] // Required roles
|
|
97
|
-
}
|
|
98
|
-
];
|
|
99
|
-
|
|
100
|
-
// Enable filtering
|
|
101
|
-
<NavigationMenu
|
|
102
|
-
items={navItems}
|
|
103
|
-
filterByPermissions={true}
|
|
104
|
-
auditLog={true}
|
|
105
|
-
/>
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
### NavigationMenu Console Errors
|
|
109
|
-
|
|
110
|
-
**Problem**: Console shows "useUnifiedAuth not available" warnings.
|
|
111
|
-
|
|
112
|
-
**Solution**: Ensure `NavigationMenu` is used within `UnifiedAuthProvider`:
|
|
113
|
-
|
|
114
|
-
```tsx
|
|
115
|
-
// ❌ WRONG - Outside of auth provider
|
|
116
|
-
<NavigationMenu items={navItems} />
|
|
117
|
-
|
|
118
|
-
// ✅ CORRECT - Inside auth provider
|
|
119
|
-
<UnifiedAuthProvider supabaseClient={supabase} appName="My App">
|
|
120
|
-
<NavigationMenu items={navItems} />
|
|
121
|
-
</UnifiedAuthProvider>
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
## Authentication Issues
|
|
125
|
-
|
|
126
|
-
### 1. "User not authenticated" Error
|
|
127
|
-
|
|
128
|
-
**Problem**: Users are getting "not authenticated" errors even when they should be logged in.
|
|
129
|
-
|
|
130
|
-
**Solution**:
|
|
131
|
-
|
|
132
|
-
```typescript
|
|
133
|
-
import { useUnifiedAuth } from '@jmruthers/pace-core';
|
|
134
|
-
|
|
135
|
-
function App() {
|
|
136
|
-
const { user, loading, error } = useUnifiedAuth();
|
|
137
|
-
|
|
138
|
-
if (loading) {
|
|
139
|
-
return <div>Loading...</div>;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (error) {
|
|
143
|
-
console.error('Auth error:', error);
|
|
144
|
-
return <div>Authentication error: {error.message}</div>;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (!user) {
|
|
148
|
-
return <LoginForm />;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
return <AuthenticatedApp />;
|
|
152
|
-
}
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
**Common Causes**:
|
|
156
|
-
- Session expired
|
|
157
|
-
- Invalid token
|
|
158
|
-
- Network connectivity issues
|
|
159
|
-
- Supabase configuration problems
|
|
160
|
-
|
|
161
|
-
**Debugging**:
|
|
162
|
-
```typescript
|
|
163
|
-
// Check session status
|
|
164
|
-
const { session } = useUnifiedAuth();
|
|
165
|
-
console.log('Session:', session);
|
|
166
|
-
console.log('Session expires:', new Date(session?.expires_at * 1000));
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
### 2. Authentication Provider Not Wrapped
|
|
170
|
-
|
|
171
|
-
**Problem**: Components can't access authentication context.
|
|
172
|
-
|
|
173
|
-
**Solution**: Ensure your app is wrapped with the authentication provider:
|
|
174
|
-
|
|
175
|
-
```typescript
|
|
176
|
-
import { UnifiedAuthProvider } from '@jmruthers/pace-core';
|
|
177
|
-
|
|
178
|
-
function App() {
|
|
179
|
-
return (
|
|
180
|
-
<UnifiedAuthProvider>
|
|
181
|
-
<YourApp />
|
|
182
|
-
</UnifiedAuthProvider>
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
### 3. Session Refresh Issues
|
|
188
|
-
|
|
189
|
-
**Problem**: Sessions are not refreshing automatically.
|
|
190
|
-
|
|
191
|
-
**Solution**:
|
|
192
|
-
|
|
193
|
-
```typescript
|
|
194
|
-
import { useUnifiedAuth } from '@jmruthers/pace-core';
|
|
195
|
-
|
|
196
|
-
function SessionManager() {
|
|
197
|
-
const { session, refreshSession } = useUnifiedAuth();
|
|
198
|
-
|
|
199
|
-
useEffect(() => {
|
|
200
|
-
if (session && session.expires_at) {
|
|
201
|
-
const timeUntilExpiry = session.expires_at * 1000 - Date.now();
|
|
202
|
-
const refreshTime = Math.max(timeUntilExpiry - 5 * 60 * 1000, 0);
|
|
203
|
-
|
|
204
|
-
const timer = setTimeout(() => {
|
|
205
|
-
refreshSession();
|
|
206
|
-
}, refreshTime);
|
|
207
|
-
|
|
208
|
-
return () => clearTimeout(timer);
|
|
209
|
-
}
|
|
210
|
-
}, [session, refreshSession]);
|
|
211
|
-
|
|
212
|
-
return null;
|
|
213
|
-
}
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
## Permission Issues
|
|
217
|
-
|
|
218
|
-
### 1. "Access denied" Errors
|
|
219
|
-
|
|
220
|
-
**Problem**: Users are getting access denied even when they should have permissions.
|
|
221
|
-
|
|
222
|
-
**Solution**:
|
|
223
|
-
|
|
224
|
-
```typescript
|
|
225
|
-
import { useRBAC } from '@jmruthers/pace-core';
|
|
226
|
-
|
|
227
|
-
function DebugPermissions() {
|
|
228
|
-
const { user, roles, permissions, hasPermission } = useRBAC();
|
|
229
|
-
|
|
230
|
-
console.log('User:', user);
|
|
231
|
-
console.log('Roles:', roles);
|
|
232
|
-
console.log('Permissions:', permissions);
|
|
233
|
-
|
|
234
|
-
// Test specific permissions
|
|
235
|
-
console.log('Can read users:', hasPermission('read:users'));
|
|
236
|
-
console.log('Can create events:', hasPermission('create:events'));
|
|
237
|
-
|
|
238
|
-
return (
|
|
239
|
-
<div>
|
|
240
|
-
<h3>Permission Debug Info</h3>
|
|
241
|
-
<p>User: {user?.email}</p>
|
|
242
|
-
<p>Roles: {roles.map(r => r.name).join(', ')}</p>
|
|
243
|
-
<p>Permissions: {permissions.map(p => p.name).join(', ')}</p>
|
|
244
|
-
</div>
|
|
245
|
-
);
|
|
246
|
-
}
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
### 2. Page Permission Not Working
|
|
250
|
-
|
|
251
|
-
**Problem**: Page-level permissions are not being enforced.
|
|
252
|
-
|
|
253
|
-
**Solution**:
|
|
254
|
-
|
|
255
|
-
```typescript
|
|
256
|
-
import { usePagePermission } from '@jmruthers/pace-core';
|
|
257
|
-
|
|
258
|
-
function ProtectedPage() {
|
|
259
|
-
const { hasAccess, loading, error } = usePagePermission('admin');
|
|
260
|
-
|
|
261
|
-
if (loading) {
|
|
262
|
-
return <div>Checking permissions...</div>;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
if (error) {
|
|
266
|
-
console.error('Permission error:', error);
|
|
267
|
-
return <div>Error checking permissions</div>;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
if (!hasAccess) {
|
|
271
|
-
return <div>Access denied</div>;
|
|
272
|
-
}
|
|
14
|
+
**Solution:**
|
|
15
|
+
1. **Verify API Key Type** - Ensure you're using the **anon key**, not service role key
|
|
16
|
+
```typescript
|
|
17
|
+
// Check your environment variables
|
|
18
|
+
console.log('API Key check:', {
|
|
19
|
+
hasAnonKey: !!process.env.REACT_APP_SUPABASE_ANON_KEY,
|
|
20
|
+
keyLength: process.env.REACT_APP_SUPABASE_ANON_KEY?.length,
|
|
21
|
+
startsWithEyJ: process.env.REACT_APP_SUPABASE_ANON_KEY?.startsWith('eyJ')
|
|
22
|
+
})
|
|
23
|
+
```
|
|
273
24
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
25
|
+
2. **Ensure RBAC Setup** - Call `setupRBAC` before using RBAC features
|
|
26
|
+
```typescript
|
|
27
|
+
// src/main.tsx - MUST be called before rendering
|
|
28
|
+
import { setupRBAC } from '@jmruthers/pace-core/rbac'
|
|
29
|
+
setupRBAC(supabase)
|
|
30
|
+
```
|
|
277
31
|
|
|
278
|
-
|
|
32
|
+
3. **Check Provider Configuration** - Verify correct provider hierarchy
|
|
33
|
+
```tsx
|
|
34
|
+
<UnifiedAuthProvider
|
|
35
|
+
supabaseClient={supabase}
|
|
36
|
+
appName="your-app"
|
|
37
|
+
enableRBAC={true}
|
|
38
|
+
requireOrganisationContext={true}
|
|
39
|
+
>
|
|
40
|
+
<OrganisationProvider>
|
|
41
|
+
<EventProvider>
|
|
42
|
+
<YourApp />
|
|
43
|
+
</EventProvider>
|
|
44
|
+
</OrganisationProvider>
|
|
45
|
+
</UnifiedAuthProvider>
|
|
46
|
+
```
|
|
279
47
|
|
|
280
|
-
|
|
48
|
+
### Issue 2: "No organisation context available"
|
|
281
49
|
|
|
282
|
-
**
|
|
50
|
+
**Symptoms:**
|
|
51
|
+
- Error: "No organisation context available"
|
|
52
|
+
- Components can't access organisation data
|
|
283
53
|
|
|
284
|
-
|
|
285
|
-
import { useOrganisation } from '@jmruthers/pace-core';
|
|
54
|
+
**Root Cause:** Missing OrganisationProvider or wrong provider order
|
|
286
55
|
|
|
287
|
-
|
|
288
|
-
|
|
56
|
+
**Solution:**
|
|
57
|
+
1. Ensure OrganisationProvider wraps your app content
|
|
58
|
+
2. Check provider hierarchy is correct
|
|
59
|
+
3. Verify `requireOrganisationContext={true}` is set
|
|
289
60
|
|
|
290
|
-
|
|
291
|
-
return <div>Loading organisation...</div>;
|
|
292
|
-
}
|
|
61
|
+
### Issue 3: "RBAC system not initialized"
|
|
293
62
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
}
|
|
63
|
+
**Symptoms:**
|
|
64
|
+
- Error: "RBAC system not initialized"
|
|
65
|
+
- Permission checks fail
|
|
298
66
|
|
|
299
|
-
|
|
300
|
-
return <div>Please select an organisation</div>;
|
|
301
|
-
}
|
|
67
|
+
**Root Cause:** Missing `setupRBAC` call
|
|
302
68
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
</div>
|
|
308
|
-
);
|
|
309
|
-
}
|
|
310
|
-
```
|
|
69
|
+
**Solution:**
|
|
70
|
+
1. Import `setupRBAC` from `@jmruthers/pace-core/rbac`
|
|
71
|
+
2. Call `setupRBAC(supabase)` before using any RBAC features
|
|
72
|
+
3. Ensure this happens before rendering your app
|
|
311
73
|
|
|
312
|
-
### 4
|
|
74
|
+
### Issue 4: Components appear unstyled
|
|
313
75
|
|
|
314
|
-
**
|
|
76
|
+
**Symptoms:**
|
|
77
|
+
- Pace-core components have no styling
|
|
78
|
+
- UI looks broken or unstyled
|
|
315
79
|
|
|
316
|
-
**Root Cause
|
|
80
|
+
**Root Cause:** Missing CSS imports or Tailwind configuration
|
|
317
81
|
|
|
318
|
-
**Solution
|
|
82
|
+
**Solution:**
|
|
83
|
+
1. **Import CSS** - Add to your main entry point:
|
|
84
|
+
```tsx
|
|
85
|
+
import '@jmruthers/pace-core/styles/core.css'
|
|
86
|
+
```
|
|
319
87
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
88
|
+
2. **Configure Tailwind v4** - Ensure proper content scanning:
|
|
89
|
+
```js
|
|
90
|
+
// vite.config.js
|
|
91
|
+
import tailwindcss from '@tailwindcss/vite'
|
|
92
|
+
|
|
93
|
+
export default defineConfig({
|
|
94
|
+
plugins: [
|
|
95
|
+
tailwindcss({
|
|
96
|
+
content: [
|
|
97
|
+
'./src/**/*.{js,ts,jsx,tsx}',
|
|
98
|
+
'./node_modules/@jmruthers/pace-core/**/*.{js,ts,jsx,tsx}'
|
|
99
|
+
]
|
|
100
|
+
})
|
|
101
|
+
]
|
|
102
|
+
})
|
|
103
|
+
```
|
|
323
104
|
|
|
324
|
-
|
|
105
|
+
## 🔍 **Debugging Checklist**
|
|
325
106
|
|
|
326
|
-
|
|
327
|
-
// ✅ Ensure proper provider hierarchy
|
|
328
|
-
<UnifiedAuthProvider supabaseClient={supabase} appName="my-app">
|
|
329
|
-
<OrganisationProvider> {/* This now handles context timing automatically */}
|
|
330
|
-
<EventProvider>
|
|
331
|
-
<YourAppContent />
|
|
332
|
-
</EventProvider>
|
|
333
|
-
</OrganisationProvider>
|
|
334
|
-
</UnifiedAuthProvider>
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
**For v0.3.43 and earlier**: You may need to implement a local workaround:
|
|
107
|
+
### 1. Verify Environment Variables
|
|
338
108
|
|
|
339
109
|
```typescript
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
const [contextReady, setContextReady] = useState(false);
|
|
345
|
-
|
|
346
|
-
useEffect(() => {
|
|
347
|
-
if (selectedOrganisation && supabase) {
|
|
348
|
-
setOrganisationContext(supabase, selectedOrganisation.id)
|
|
349
|
-
.then(() => setContextReady(true))
|
|
350
|
-
.catch(console.error);
|
|
351
|
-
}
|
|
352
|
-
}, [selectedOrganisation, supabase]);
|
|
353
|
-
|
|
354
|
-
if (!contextReady) {
|
|
355
|
-
return <div>Setting up organisation context...</div>;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
return <>{children}</>;
|
|
359
|
-
}
|
|
360
|
-
```
|
|
361
|
-
|
|
362
|
-
**Detailed Setup**: If you're getting "unrecognized configuration parameter" errors, see the [Organisation Context Setup Guide](./organisation-context-setup.md) for complete database setup instructions.
|
|
363
|
-
|
|
364
|
-
## Styling Issues
|
|
365
|
-
|
|
366
|
-
### 1. App Looks Unstyled (Raw HTML)
|
|
367
|
-
|
|
368
|
-
**Problem**: App appears with default browser styling only - no colors, fonts, or proper layout.
|
|
369
|
-
|
|
370
|
-
**Symptoms**:
|
|
371
|
-
- Default browser styling only
|
|
372
|
-
- No colors, fonts, or layout
|
|
373
|
-
- Components look like plain HTML
|
|
374
|
-
- Header is squashed or too wide
|
|
375
|
-
- Main container stretches full width
|
|
376
|
-
- Missing colored background
|
|
377
|
-
|
|
378
|
-
**Solution**:
|
|
379
|
-
|
|
380
|
-
**CRITICAL**: Use the `PaceAppLayout` component - don't just import CSS files:
|
|
381
|
-
|
|
382
|
-
```tsx
|
|
383
|
-
// ❌ Wrong - just CSS imports
|
|
384
|
-
import '@jmruthers/pace-core/styles/core.css';
|
|
385
|
-
|
|
386
|
-
function App() {
|
|
387
|
-
return (
|
|
388
|
-
<div>
|
|
389
|
-
<h1>My App</h1>
|
|
390
|
-
{/* This won't be styled properly */}
|
|
391
|
-
</div>
|
|
392
|
-
);
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
// ✅ Correct - use PaceAppLayout
|
|
396
|
-
import { PaceAppLayout } from '@jmruthers/pace-core';
|
|
397
|
-
import './app.css'; // Your app's color palette (must come first)
|
|
398
|
-
import '@jmruthers/pace-core/styles/core.css';
|
|
399
|
-
|
|
400
|
-
function App() {
|
|
401
|
-
return (
|
|
402
|
-
<PaceAppLayout appName="My Application">
|
|
403
|
-
<div className="container mx-auto px-4 py-6">
|
|
404
|
-
<h1 className="text-3xl font-bold text-main-900">My App</h1>
|
|
405
|
-
<p className="text-main-700">This will be properly styled</p>
|
|
406
|
-
</div>
|
|
407
|
-
</PaceAppLayout>
|
|
408
|
-
);
|
|
409
|
-
}
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
**Common Causes**:
|
|
413
|
-
- Missing CSS imports
|
|
414
|
-
- Wrong build tool configuration (using Tailwind v3 instead of v4)
|
|
415
|
-
- Not using PaceAppLayout component
|
|
416
|
-
- Missing app.css with color palette
|
|
417
|
-
- CSS files not being processed
|
|
418
|
-
|
|
419
|
-
**Build Tool Configuration**:
|
|
420
|
-
|
|
421
|
-
**For Vite (Recommended):**
|
|
422
|
-
```js
|
|
423
|
-
// vite.config.js
|
|
424
|
-
import { defineConfig } from 'vite'
|
|
425
|
-
import react from '@vitejs/plugin-react'
|
|
426
|
-
import tailwindcss from '@tailwindcss/vite'
|
|
427
|
-
|
|
428
|
-
export default defineConfig({
|
|
429
|
-
plugins: [
|
|
430
|
-
react(),
|
|
431
|
-
tailwindcss() // Tailwind v4 - no config file needed!
|
|
432
|
-
],
|
|
110
|
+
console.log('Environment check:', {
|
|
111
|
+
url: process.env.REACT_APP_SUPABASE_URL,
|
|
112
|
+
hasKey: !!process.env.REACT_APP_SUPABASE_ANON_KEY,
|
|
113
|
+
keyLength: process.env.REACT_APP_SUPABASE_ANON_KEY?.length
|
|
433
114
|
})
|
|
434
115
|
```
|
|
435
116
|
|
|
436
|
-
|
|
437
|
-
```bash
|
|
438
|
-
npm install -D @tailwindcss/vite tailwindcss@^4.0.0
|
|
439
|
-
# Remove old Tailwind v3 if installed
|
|
440
|
-
npm uninstall tailwindcss@^3.0.0
|
|
441
|
-
```
|
|
442
|
-
|
|
443
|
-
**Create app.css with Color Palette:**
|
|
444
|
-
```css
|
|
445
|
-
/* app.css - Your app's color palette */
|
|
446
|
-
@theme static {
|
|
447
|
-
/* MAIN palette - your primary brand color */
|
|
448
|
-
--color-main-raw: oklch(0.7 0.057 252.02);
|
|
449
|
-
--color-main-50: oklch(0.98 0.001 252.02);
|
|
450
|
-
--color-main-100: oklch(0.96 0.005 252.02);
|
|
451
|
-
--color-main-200: oklch(0.927 0.012 252.02);
|
|
452
|
-
--color-main-300: oklch(0.881 0.021 252.02);
|
|
453
|
-
--color-main-400: oklch(0.822 0.032 252.02);
|
|
454
|
-
--color-main-500: oklch(0.75 0.047 252.02);
|
|
455
|
-
--color-main-600: oklch(0.7 0.057 252.02);
|
|
456
|
-
--color-main-700: oklch(0.567 0.044 252.02);
|
|
457
|
-
--color-main-800: oklch(0.456 0.034 252.02);
|
|
458
|
-
--color-main-900: oklch(0.332 0.024 252.02);
|
|
459
|
-
--color-main-950: oklch(0.195 0.014 252.02);
|
|
460
|
-
|
|
461
|
-
/* SEC palette - your secondary brand color */
|
|
462
|
-
--color-sec-raw: oklch(0.58 0.23 280.75);
|
|
463
|
-
--color-sec-50: oklch(0.98 0.003 280.75);
|
|
464
|
-
--color-sec-100: oklch(0.96 0.014 280.75);
|
|
465
|
-
--color-sec-200: oklch(0.927 0.033 280.75);
|
|
466
|
-
--color-sec-300: oklch(0.881 0.059 280.75);
|
|
467
|
-
--color-sec-400: oklch(0.822 0.093 280.75);
|
|
468
|
-
--color-sec-500: oklch(0.75 0.133 280.75);
|
|
469
|
-
--color-sec-600: oklch(0.665 0.182 280.75);
|
|
470
|
-
--color-sec-700: oklch(0.58 0.23 280.75);
|
|
471
|
-
--color-sec-800: oklch(0.456 0.158 280.75);
|
|
472
|
-
--color-sec-900: oklch(0.332 0.099 280.75);
|
|
473
|
-
--color-sec-950: oklch(0.195 0.047 280.75);
|
|
474
|
-
|
|
475
|
-
/* ACC palette - your accent brand color */
|
|
476
|
-
--color-acc-raw: oklch(0.64 0.21 37.76);
|
|
477
|
-
--color-acc-50: oklch(0.98 0.003 37.76);
|
|
478
|
-
--color-acc-100: oklch(0.96 0.015 37.76);
|
|
479
|
-
--color-acc-200: oklch(0.927 0.035 37.76);
|
|
480
|
-
--color-acc-300: oklch(0.881 0.063 37.76);
|
|
481
|
-
--color-acc-400: oklch(0.822 0.099 37.76);
|
|
482
|
-
--color-acc-500: oklch(0.75 0.143 37.76);
|
|
483
|
-
--color-acc-600: oklch(0.64 0.21 37.76);
|
|
484
|
-
--color-acc-700: oklch(0.567 0.177 37.76);
|
|
485
|
-
--color-acc-800: oklch(0.456 0.13 37.76);
|
|
486
|
-
--color-acc-900: oklch(0.332 0.085 37.76);
|
|
487
|
-
--color-acc-950: oklch(0.195 0.044 37.76);
|
|
488
|
-
}
|
|
489
|
-
```
|
|
490
|
-
|
|
491
|
-
**Debugging Steps**:
|
|
492
|
-
1. Check Browser DevTools for CSS import errors
|
|
493
|
-
2. Verify pace-core CSS files are loading in Network tab
|
|
494
|
-
3. Inspect elements to see if Tailwind classes are applied
|
|
495
|
-
4. Ensure Tailwind v4 is installed and configured
|
|
496
|
-
5. Test CSS imports with temporary rule: `body { background-color: red !important; }`
|
|
497
|
-
|
|
498
|
-
**Quick Checklist**:
|
|
499
|
-
- [ ] CSS files imported in main.tsx/App.tsx
|
|
500
|
-
- [ ] app.css created with color palette
|
|
501
|
-
- [ ] Using PaceAppLayout component
|
|
502
|
-
- [ ] Tailwind v4 configured in build tool
|
|
503
|
-
- [ ] No custom CSS overriding pace-core styles
|
|
504
|
-
- [ ] All required dependencies installed
|
|
505
|
-
- [ ] No build errors in console
|
|
506
|
-
|
|
507
|
-
### 2. App Looks Different from Demo (v0.3.47+ Fixed)
|
|
508
|
-
|
|
509
|
-
**Problem**: Your consuming app looks different from the PACE Core demo app
|
|
510
|
-
|
|
511
|
-
**Symptoms**:
|
|
512
|
-
- Different background colors (gray instead of blue)
|
|
513
|
-
- Different text colors
|
|
514
|
-
- Overall different visual appearance
|
|
515
|
-
|
|
516
|
-
**Root Cause**: The demo app uses a custom CSS configuration, while consuming apps use our theme file. The theme file was using neutral gray colors instead of the blue-tinted scheme from the demo.
|
|
517
|
-
|
|
518
|
-
**Solution**: This issue was fixed in v0.3.47+. The theme file now uses the same blue-tinted color scheme as the demo app:
|
|
519
|
-
|
|
520
|
-
- **Background**: Very light blue (`--color-primary-50`)
|
|
521
|
-
- **Foreground**: Very dark blue (`--color-primary-950`)
|
|
522
|
-
- **Primary**: Blue (`--color-primary-600`)
|
|
523
|
-
- **Borders**: Blue (`--color-primary-500`)
|
|
524
|
-
- **Inputs**: Light purple (`--color-secondary-200`)
|
|
525
|
-
|
|
526
|
-
**Quick Fix**:
|
|
527
|
-
```bash
|
|
528
|
-
npm install @jmruthers/pace-core@latest
|
|
529
|
-
```
|
|
530
|
-
|
|
531
|
-
### 2. Header Layout Issues (v0.3.48+ Fixed)
|
|
532
|
-
|
|
533
|
-
**Problem**: Header elements are stacked vertically instead of being aligned horizontally across the page
|
|
534
|
-
|
|
535
|
-
**Symptoms**:
|
|
536
|
-
- Logo, navigation, and user menu are stacked vertically
|
|
537
|
-
- Header doesn't use the full width properly
|
|
538
|
-
- Layout looks broken compared to demo app
|
|
539
|
-
|
|
540
|
-
**Root Cause**: Missing CSS variables that the header component depends on:
|
|
541
|
-
- `--app-width` (for container width)
|
|
542
|
-
- `--color-main-*` (for header background colors)
|
|
543
|
-
- `--color-sec-*` and `--color-acc-*` (for other header elements)
|
|
544
|
-
|
|
545
|
-
**Solution**: This issue was fixed in v0.3.48+. The theme file now includes all required CSS variables:
|
|
546
|
-
|
|
547
|
-
- **Layout Variables**: `--app-width: 90rem`
|
|
548
|
-
- **App Color Variables**: `--color-main-*`, `--color-sec-*`, `--color-acc-*`
|
|
549
|
-
- **Complete Color Palette**: All color variants (50, 100, 200, etc.) plus `-raw` variants
|
|
550
|
-
|
|
551
|
-
**Quick Fix**:
|
|
552
|
-
```bash
|
|
553
|
-
npm install @jmruthers/pace-core@latest
|
|
554
|
-
```
|
|
555
|
-
|
|
556
|
-
### 3. Missing CSS Variables (v0.3.49+ Fixed)
|
|
557
|
-
|
|
558
|
-
**Problem**: Components not rendering correctly due to missing CSS variables
|
|
559
|
-
|
|
560
|
-
**Symptoms**:
|
|
561
|
-
- Components appear unstyled or broken
|
|
562
|
-
- Console errors about undefined CSS variables
|
|
563
|
-
- Inconsistent appearance across different components
|
|
564
|
-
- DataTable examples not working properly
|
|
565
|
-
|
|
566
|
-
**Root Cause**: The theme file was missing many CSS variables that components depend on:
|
|
567
|
-
- Font variables (--font-sans, --font-serif, --font-mono)
|
|
568
|
-
- Design tokens (--pace-* variables)
|
|
569
|
-
- Event colors (--color-ev-* variables)
|
|
570
|
-
- Radix UI variables (--radix-toast-*)
|
|
571
|
-
|
|
572
|
-
**Solution**: This issue was fixed in v0.3.49+. The theme file now includes comprehensive variable coverage:
|
|
573
|
-
|
|
574
|
-
- **Font Variables**: All typography variables for consistent fonts
|
|
575
|
-
- **Design Tokens**: Complete PACE Core design token system
|
|
576
|
-
- **Event Colors**: Full color palette for DataTable examples
|
|
577
|
-
- **Component Variables**: All variables needed for component styling
|
|
578
|
-
- **Radix UI Variables**: Third-party component library compatibility
|
|
579
|
-
|
|
580
|
-
**Quick Fix**:
|
|
581
|
-
```bash
|
|
582
|
-
npm install @jmruthers/pace-core@latest
|
|
583
|
-
```
|
|
584
|
-
|
|
585
|
-
### 4. Login Page Styling Issues (v0.4.4+ Fixed)
|
|
586
|
-
|
|
587
|
-
**Problem**: Login page looks different from the pace-core demo - unstyled button, wrong background, missing shadows.
|
|
588
|
-
|
|
589
|
-
**Symptoms**:
|
|
590
|
-
- Button appears as plain text instead of styled button
|
|
591
|
-
- Background is white instead of gradient
|
|
592
|
-
- Card has no shadow or wrong styling
|
|
593
|
-
- Input fields are dark instead of white
|
|
594
|
-
- Overall appearance doesn't match the demo
|
|
595
|
-
|
|
596
|
-
**Root Cause**: Missing theme mappings in `styles/core.css` prevented CSS variables from being processed correctly by Tailwind v4.
|
|
597
|
-
|
|
598
|
-
**Solution**: This issue was fixed in v0.4.4+. The theme file now includes complete mappings for all color palettes.
|
|
599
|
-
|
|
600
|
-
**Quick Fix**:
|
|
601
|
-
```bash
|
|
602
|
-
npm install @jmruthers/pace-core@latest
|
|
603
|
-
```
|
|
604
|
-
|
|
605
|
-
**Required Setup** (must be exactly like this):
|
|
606
|
-
|
|
607
|
-
1. **CSS Imports** (in your main.tsx):
|
|
608
|
-
```tsx
|
|
609
|
-
import './app.css'; // Your app's palette definitions (must come first)
|
|
610
|
-
import '@jmruthers/pace-core/styles/core.css';
|
|
611
|
-
```
|
|
612
|
-
|
|
613
|
-
2. **App.css** (complete palette required):
|
|
614
|
-
```css
|
|
615
|
-
@theme static {
|
|
616
|
-
/* MAIN palette - your primary brand color */
|
|
617
|
-
--color-main-50: oklch(0.98 0.001 252.02);
|
|
618
|
-
--color-main-100: oklch(0.96 0.005 252.02);
|
|
619
|
-
/* ... all shades 50-950 + raw */
|
|
620
|
-
|
|
621
|
-
/* SEC palette - your secondary brand color */
|
|
622
|
-
--color-sec-50: oklch(0.98 0.003 280.75);
|
|
623
|
-
/* ... all shades 50-950 + raw */
|
|
624
|
-
|
|
625
|
-
/* ACC palette - your accent brand color */
|
|
626
|
-
--color-acc-50: oklch(0.98 0.003 37.76);
|
|
627
|
-
/* ... all shades 50-950 + raw */
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
@layer base {
|
|
631
|
-
.appGradient {
|
|
632
|
-
background: radial-gradient(var(--color-main-200), oklch(from var(--color-main-200) l c h / 0%) 30%),
|
|
633
|
-
conic-gradient(var(--color-main-200), var(--color-sec-200), var(--color-acc-200), var(--color-main-200));
|
|
634
|
-
background-attachment: fixed;
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
```
|
|
638
|
-
|
|
639
|
-
3. **HTML Structure** (in your index.html):
|
|
640
|
-
```html
|
|
641
|
-
<body class="appGradient">
|
|
642
|
-
<div id="root" class="grid grid-rows-[auto_1fr_auto] min-h-screen"></div>
|
|
643
|
-
</body>
|
|
644
|
-
```
|
|
645
|
-
|
|
646
|
-
4. **Vite Configuration** (Tailwind v4 required):
|
|
647
|
-
```ts
|
|
648
|
-
// vite.config.ts
|
|
649
|
-
import { defineConfig } from 'vite';
|
|
650
|
-
import react from '@vitejs/plugin-react';
|
|
651
|
-
import tailwindcss from '@tailwindcss/vite';
|
|
652
|
-
|
|
653
|
-
export default defineConfig({
|
|
654
|
-
plugins: [
|
|
655
|
-
react(),
|
|
656
|
-
tailwindcss() // Tailwind v4 - no config file needed!
|
|
657
|
-
],
|
|
658
|
-
});
|
|
659
|
-
```
|
|
660
|
-
|
|
661
|
-
**Debugging Steps**:
|
|
662
|
-
1. Check browser dev tools for CSS import errors
|
|
663
|
-
2. Verify `bg-main-600` class resolves to actual color value
|
|
664
|
-
3. Ensure all CSS files are imported in correct order
|
|
665
|
-
4. Confirm Tailwind v4 is installed (not v3)
|
|
666
|
-
5. Test with minimal setup to isolate the issue
|
|
667
|
-
|
|
668
|
-
### 5. Tailwind v4 Theme File Issues (v0.3.45+ Fixed)
|
|
669
|
-
|
|
670
|
-
**Problem**: Build failures when using `@import '@jmruthers/pace-core/styles/core.css'`
|
|
671
|
-
|
|
672
|
-
**Root Cause**: The theme file was missing semantic colors and had circular references in component classes.
|
|
673
|
-
|
|
674
|
-
**Solution**: This issue was fixed in v0.3.45+. The theme file now includes:
|
|
675
|
-
|
|
676
|
-
- **Complete semantic colors** (ring, border, background, foreground, etc.)
|
|
677
|
-
- **Fixed component classes** (no circular @apply references)
|
|
678
|
-
- **All required Tailwind v4 colors**
|
|
679
|
-
|
|
680
|
-
**Quick Fix**:
|
|
681
|
-
```bash
|
|
682
|
-
npm install @jmruthers/pace-core@latest
|
|
683
|
-
```
|
|
684
|
-
|
|
685
|
-
**Usage**:
|
|
686
|
-
```css
|
|
687
|
-
/* index.css */
|
|
688
|
-
@import '@jmruthers/pace-core/styles/core.css';
|
|
689
|
-
```
|
|
690
|
-
|
|
691
|
-
**Vite Configuration**:
|
|
692
|
-
```ts
|
|
693
|
-
// vite.config.ts
|
|
694
|
-
import { defineConfig } from 'vite';
|
|
695
|
-
import react from '@vitejs/plugin-react';
|
|
696
|
-
import tailwindcss from '@tailwindcss/vite';
|
|
697
|
-
|
|
698
|
-
export default defineConfig({
|
|
699
|
-
plugins: [
|
|
700
|
-
react(),
|
|
701
|
-
tailwindcss() // ✅ Simple - theme is in CSS
|
|
702
|
-
],
|
|
703
|
-
});
|
|
704
|
-
```
|
|
705
|
-
|
|
706
|
-
### 2. Missing Semantic Colors
|
|
707
|
-
|
|
708
|
-
**Problem**: Colors like `ring-ring`, `border`, `background` not working
|
|
709
|
-
|
|
710
|
-
**Solution**: The theme file now includes all semantic colors:
|
|
711
|
-
|
|
712
|
-
```css
|
|
713
|
-
/* These are now included in the theme file */
|
|
714
|
-
--color-ring: var(--color-primary-600);
|
|
715
|
-
--color-border: var(--color-neutral-300);
|
|
716
|
-
--color-background: var(--color-neutral-50);
|
|
717
|
-
--color-foreground: var(--color-neutral-950);
|
|
718
|
-
/* ... and more */
|
|
719
|
-
```
|
|
720
|
-
|
|
721
|
-
### 3. Component Classes Not Working
|
|
722
|
-
|
|
723
|
-
**Problem**: `.pace-button`, `.pace-input` classes not applying styles
|
|
724
|
-
|
|
725
|
-
**Solution**: Component classes are now self-contained:
|
|
726
|
-
|
|
727
|
-
```css
|
|
728
|
-
/* ✅ Fixed - no circular references */
|
|
729
|
-
.pace-button-primary {
|
|
730
|
-
@apply inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background bg-primary-600 text-main-50 hover:bg-primary-700 active:bg-primary-800;
|
|
731
|
-
}
|
|
732
|
-
```
|
|
733
|
-
|
|
734
|
-
## Event Management Issues
|
|
735
|
-
|
|
736
|
-
### 1. Events Not Loading
|
|
737
|
-
|
|
738
|
-
**Problem**: Events are not being fetched or displayed.
|
|
739
|
-
|
|
740
|
-
**Solution**:
|
|
117
|
+
### 2. Test Supabase Connection
|
|
741
118
|
|
|
742
119
|
```typescript
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
if (error) {
|
|
753
|
-
console.error('Events error:', error);
|
|
754
|
-
return (
|
|
755
|
-
<div>
|
|
756
|
-
<div>Error loading events: {error}</div>
|
|
757
|
-
<button onClick={refreshEvents}>Retry</button>
|
|
758
|
-
</div>
|
|
759
|
-
);
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
if (!events || events.length === 0) {
|
|
763
|
-
return <div>No events found</div>;
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
return (
|
|
767
|
-
<div>
|
|
768
|
-
{events.map(event => (
|
|
769
|
-
<div key={event.id}>
|
|
770
|
-
<h3>{event.name}</h3>
|
|
771
|
-
<p>{event.description}</p>
|
|
772
|
-
</div>
|
|
773
|
-
))}
|
|
774
|
-
</div>
|
|
775
|
-
);
|
|
776
|
-
}
|
|
777
|
-
```
|
|
778
|
-
|
|
779
|
-
### 2. Event Selection Not Working
|
|
780
|
-
|
|
781
|
-
**Problem**: Users can't select events or the selection is not persisting.
|
|
782
|
-
|
|
783
|
-
**Solution**:
|
|
784
|
-
|
|
785
|
-
```typescript
|
|
786
|
-
import { useEvents } from '@jmruthers/pace-core';
|
|
787
|
-
|
|
788
|
-
function EventSelector() {
|
|
789
|
-
const { events, selectedEvent, setSelectedEvent, hasAccess } = useEvents();
|
|
790
|
-
|
|
791
|
-
const handleEventSelect = (event) => {
|
|
792
|
-
if (hasAccess(event.id)) {
|
|
793
|
-
setSelectedEvent(event);
|
|
794
|
-
} else {
|
|
795
|
-
console.warn('User does not have access to this event');
|
|
796
|
-
}
|
|
797
|
-
};
|
|
798
|
-
|
|
799
|
-
return (
|
|
800
|
-
<div>
|
|
801
|
-
<h2>Select Event</h2>
|
|
802
|
-
{events.map(event => (
|
|
803
|
-
<div key={event.id}>
|
|
804
|
-
<span>{event.name}</span>
|
|
805
|
-
{hasAccess(event.id) ? (
|
|
806
|
-
<button onClick={() => handleEventSelect(event)}>
|
|
807
|
-
{selectedEvent?.id === event.id ? 'Selected' : 'Select'}
|
|
808
|
-
</button>
|
|
809
|
-
) : (
|
|
810
|
-
<span>No access</span>
|
|
811
|
-
)}
|
|
812
|
-
</div>
|
|
813
|
-
))}
|
|
814
|
-
</div>
|
|
815
|
-
);
|
|
816
|
-
}
|
|
817
|
-
```
|
|
818
|
-
|
|
819
|
-
## Form Issues
|
|
820
|
-
|
|
821
|
-
### 1. Form Validation Not Working
|
|
822
|
-
|
|
823
|
-
**Problem**: Form validation is not triggering or showing errors.
|
|
824
|
-
|
|
825
|
-
**Solution**:
|
|
826
|
-
|
|
827
|
-
```typescript
|
|
828
|
-
import { useZodForm } from '@jmruthers/pace-core';
|
|
829
|
-
import { z } from 'zod';
|
|
830
|
-
|
|
831
|
-
const schema = z.object({
|
|
832
|
-
name: z.string().min(1, 'Name is required'),
|
|
833
|
-
email: z.string().email('Invalid email'),
|
|
834
|
-
});
|
|
835
|
-
|
|
836
|
-
function UserForm() {
|
|
837
|
-
const {
|
|
838
|
-
register,
|
|
839
|
-
handleSubmit,
|
|
840
|
-
formState: { errors, isSubmitting },
|
|
841
|
-
reset,
|
|
842
|
-
} = useZodForm(schema);
|
|
843
|
-
|
|
844
|
-
const onSubmit = async (data) => {
|
|
845
|
-
try {
|
|
846
|
-
await createUser(data);
|
|
847
|
-
reset();
|
|
848
|
-
} catch (error) {
|
|
849
|
-
console.error('Form submission error:', error);
|
|
850
|
-
}
|
|
851
|
-
};
|
|
852
|
-
|
|
853
|
-
return (
|
|
854
|
-
<form onSubmit={handleSubmit(onSubmit)}>
|
|
855
|
-
<div>
|
|
856
|
-
<input {...register('name')} placeholder="Name" />
|
|
857
|
-
{errors.name && <span className="error">{errors.name.message}</span>}
|
|
858
|
-
</div>
|
|
859
|
-
|
|
860
|
-
<div>
|
|
861
|
-
<input type="email" {...register('email')} placeholder="Email" />
|
|
862
|
-
{errors.email && <span className="error">{errors.email.message}</span>}
|
|
863
|
-
</div>
|
|
864
|
-
|
|
865
|
-
<button type="submit" disabled={isSubmitting}>
|
|
866
|
-
{isSubmitting ? 'Submitting...' : 'Submit'}
|
|
867
|
-
</button>
|
|
868
|
-
</form>
|
|
869
|
-
);
|
|
870
|
-
}
|
|
871
|
-
```
|
|
872
|
-
|
|
873
|
-
### 2. Form Data Not Saving
|
|
874
|
-
|
|
875
|
-
**Problem**: Form data is not being saved to the database.
|
|
876
|
-
|
|
877
|
-
**Solution**:
|
|
878
|
-
|
|
879
|
-
```typescript
|
|
880
|
-
import { useZodForm } from '@jmruthers/pace-core';
|
|
881
|
-
import { useSupabase } from '@jmruthers/pace-core';
|
|
882
|
-
|
|
883
|
-
function UserForm() {
|
|
884
|
-
const { supabase } = useSupabase();
|
|
885
|
-
const { currentOrganisation } = useOrganisation();
|
|
886
|
-
|
|
887
|
-
const onSubmit = async (data) => {
|
|
888
|
-
try {
|
|
889
|
-
const { error } = await supabase
|
|
890
|
-
.from('users')
|
|
891
|
-
.insert({
|
|
892
|
-
...data,
|
|
893
|
-
organisation_id: currentOrganisation.id,
|
|
894
|
-
});
|
|
895
|
-
|
|
896
|
-
if (error) {
|
|
897
|
-
console.error('Database error:', error);
|
|
898
|
-
throw error;
|
|
899
|
-
}
|
|
900
|
-
|
|
901
|
-
console.log('User created successfully');
|
|
902
|
-
} catch (error) {
|
|
903
|
-
console.error('Form submission error:', error);
|
|
904
|
-
}
|
|
905
|
-
};
|
|
906
|
-
|
|
907
|
-
// ... rest of form component
|
|
908
|
-
}
|
|
909
|
-
```
|
|
910
|
-
|
|
911
|
-
## Component Issues
|
|
912
|
-
|
|
913
|
-
### 1. Components Not Rendering
|
|
914
|
-
|
|
915
|
-
**Problem**: Components are not rendering or showing blank content.
|
|
916
|
-
|
|
917
|
-
**Solution**:
|
|
918
|
-
|
|
919
|
-
```typescript
|
|
920
|
-
import { ErrorBoundary } from '@jmruthers/pace-core';
|
|
921
|
-
|
|
922
|
-
function App() {
|
|
923
|
-
return (
|
|
924
|
-
<ErrorBoundary fallback={<div>Something went wrong</div>}>
|
|
925
|
-
<YourComponents />
|
|
926
|
-
</ErrorBoundary>
|
|
927
|
-
);
|
|
928
|
-
}
|
|
929
|
-
```
|
|
930
|
-
|
|
931
|
-
### 2. Styling Issues
|
|
932
|
-
|
|
933
|
-
**Problem**: Components are not styled correctly or styles are missing.
|
|
934
|
-
|
|
935
|
-
**Solution**:
|
|
936
|
-
|
|
937
|
-
```typescript
|
|
938
|
-
// Ensure Tailwind CSS is imported
|
|
939
|
-
// Import the core CSS file
|
|
940
|
-
import './app.css'; // Your app's color palette (must come first)
|
|
941
|
-
import '@jmruthers/pace-core/styles/core.css';
|
|
942
|
-
|
|
943
|
-
// Check if your app is properly set up
|
|
944
|
-
function App() {
|
|
945
|
-
return (
|
|
946
|
-
<div>
|
|
947
|
-
<YourApp />
|
|
948
|
-
</div>
|
|
949
|
-
);
|
|
950
|
-
}
|
|
951
|
-
```
|
|
952
|
-
|
|
953
|
-
### 3. Component Props Issues
|
|
954
|
-
|
|
955
|
-
**Problem**: Components are not receiving the correct props or props are undefined.
|
|
956
|
-
|
|
957
|
-
**Solution**:
|
|
958
|
-
|
|
959
|
-
```typescript
|
|
960
|
-
import { Button } from '@jmruthers/pace-core';
|
|
961
|
-
|
|
962
|
-
function MyComponent() {
|
|
963
|
-
// Always provide required props
|
|
964
|
-
return (
|
|
965
|
-
<Button
|
|
966
|
-
variant="primary"
|
|
967
|
-
onClick={() => console.log('clicked')}
|
|
968
|
-
>
|
|
969
|
-
Click me
|
|
970
|
-
</Button>
|
|
971
|
-
);
|
|
972
|
-
}
|
|
973
|
-
```
|
|
974
|
-
|
|
975
|
-
## Database Issues
|
|
976
|
-
|
|
977
|
-
### 1. Database Connection Errors
|
|
978
|
-
|
|
979
|
-
**Problem**: Cannot connect to Supabase database.
|
|
980
|
-
|
|
981
|
-
**Solution**:
|
|
982
|
-
|
|
983
|
-
```typescript
|
|
984
|
-
import { createSupabaseClient } from '@jmruthers/pace-core';
|
|
985
|
-
|
|
986
|
-
// Check environment variables
|
|
987
|
-
const supabaseUrl = process.env.SUPABASE_URL;
|
|
988
|
-
const supabaseKey = process.env.SUPABASE_ANON_KEY;
|
|
989
|
-
|
|
990
|
-
if (!supabaseUrl || !supabaseKey) {
|
|
991
|
-
console.error('Missing Supabase environment variables');
|
|
992
|
-
throw new Error('Supabase configuration missing');
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
const supabase = createSupabaseClient(supabaseUrl, supabaseKey);
|
|
996
|
-
|
|
997
|
-
// Test connection
|
|
998
|
-
supabase.from('users').select('count').single()
|
|
999
|
-
.then(() => console.log('Database connected'))
|
|
1000
|
-
.catch(error => console.error('Database connection failed:', error));
|
|
1001
|
-
```
|
|
1002
|
-
|
|
1003
|
-
### 2. RLS Policy Issues
|
|
1004
|
-
|
|
1005
|
-
**Problem**: Row Level Security policies are blocking legitimate access.
|
|
1006
|
-
|
|
1007
|
-
**Solution**:
|
|
1008
|
-
|
|
1009
|
-
```sql
|
|
1010
|
-
-- Check if RLS is enabled
|
|
1011
|
-
SELECT schemaname, tablename, rowsecurity
|
|
1012
|
-
FROM pg_tables
|
|
1013
|
-
WHERE tablename = 'your_table_name';
|
|
1014
|
-
|
|
1015
|
-
-- Check policies
|
|
1016
|
-
SELECT * FROM pg_policies WHERE tablename = 'your_table_name';
|
|
1017
|
-
|
|
1018
|
-
-- Test policy
|
|
1019
|
-
SELECT * FROM your_table_name WHERE organisation_id = 'your_org_id';
|
|
1020
|
-
```
|
|
1021
|
-
|
|
1022
|
-
### 3. Data Not Filtered by Organisation
|
|
1023
|
-
|
|
1024
|
-
**Problem**: Data is not being filtered by the current organisation.
|
|
1025
|
-
|
|
1026
|
-
**Solution**:
|
|
1027
|
-
|
|
1028
|
-
```typescript
|
|
1029
|
-
import { useOrganisation } from '@jmruthers/pace-core';
|
|
1030
|
-
import { useSupabase } from '@jmruthers/pace-core';
|
|
1031
|
-
|
|
1032
|
-
function DataComponent() {
|
|
1033
|
-
const { supabase } = useSupabase();
|
|
1034
|
-
const { currentOrganisation } = useOrganisation();
|
|
1035
|
-
|
|
1036
|
-
const fetchData = async () => {
|
|
1037
|
-
if (!currentOrganisation) {
|
|
1038
|
-
console.warn('No organisation selected');
|
|
1039
|
-
return;
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
|
-
const { data, error } = await supabase
|
|
1043
|
-
.from('your_table')
|
|
1044
|
-
.select('*')
|
|
1045
|
-
.eq('organisation_id', currentOrganisation.id);
|
|
1046
|
-
|
|
1047
|
-
if (error) {
|
|
1048
|
-
console.error('Database error:', error);
|
|
1049
|
-
return;
|
|
1050
|
-
}
|
|
1051
|
-
|
|
1052
|
-
console.log('Filtered data:', data);
|
|
1053
|
-
};
|
|
1054
|
-
|
|
1055
|
-
return (
|
|
1056
|
-
<div>
|
|
1057
|
-
<button onClick={fetchData}>Load Data</button>
|
|
1058
|
-
</div>
|
|
1059
|
-
);
|
|
1060
|
-
}
|
|
1061
|
-
```
|
|
1062
|
-
|
|
1063
|
-
## Performance Issues
|
|
1064
|
-
|
|
1065
|
-
### 1. Slow Loading Times
|
|
1066
|
-
|
|
1067
|
-
**Problem**: Components are taking too long to load.
|
|
1068
|
-
|
|
1069
|
-
**Solution**:
|
|
1070
|
-
|
|
1071
|
-
```typescript
|
|
1072
|
-
import { useMemo } from 'react';
|
|
1073
|
-
import { useEvents } from '@jmruthers/pace-core';
|
|
1074
|
-
|
|
1075
|
-
function OptimizedEventList() {
|
|
1076
|
-
const { events, loading } = useEvents();
|
|
1077
|
-
|
|
1078
|
-
// Memoize expensive calculations
|
|
1079
|
-
const sortedEvents = useMemo(() => {
|
|
1080
|
-
return events?.sort((a, b) =>
|
|
1081
|
-
new Date(a.start_date).getTime() - new Date(b.start_date).getTime()
|
|
1082
|
-
) || [];
|
|
1083
|
-
}, [events]);
|
|
1084
|
-
|
|
1085
|
-
if (loading) {
|
|
1086
|
-
return <div>Loading events...</div>;
|
|
1087
|
-
}
|
|
1088
|
-
|
|
1089
|
-
return (
|
|
1090
|
-
<div>
|
|
1091
|
-
{sortedEvents.map(event => (
|
|
1092
|
-
<EventCard key={event.id} event={event} />
|
|
1093
|
-
))}
|
|
1094
|
-
</div>
|
|
1095
|
-
);
|
|
1096
|
-
}
|
|
1097
|
-
```
|
|
1098
|
-
|
|
1099
|
-
### 2. Memory Leaks
|
|
1100
|
-
|
|
1101
|
-
**Problem**: Memory usage is increasing over time.
|
|
1102
|
-
|
|
1103
|
-
**Solution**:
|
|
1104
|
-
|
|
1105
|
-
```typescript
|
|
1106
|
-
import { useEffect, useCallback } from 'react';
|
|
1107
|
-
import { useEvents } from '@jmruthers/pace-core';
|
|
1108
|
-
|
|
1109
|
-
function EventManager() {
|
|
1110
|
-
const { events, refreshEvents } = useEvents();
|
|
1111
|
-
|
|
1112
|
-
// Clean up on unmount
|
|
1113
|
-
useEffect(() => {
|
|
1114
|
-
return () => {
|
|
1115
|
-
// Cleanup function
|
|
1116
|
-
console.log('Component unmounting');
|
|
1117
|
-
};
|
|
1118
|
-
}, []);
|
|
1119
|
-
|
|
1120
|
-
// Memoize callbacks
|
|
1121
|
-
const handleRefresh = useCallback(() => {
|
|
1122
|
-
refreshEvents();
|
|
1123
|
-
}, [refreshEvents]);
|
|
1124
|
-
|
|
1125
|
-
return (
|
|
1126
|
-
<div>
|
|
1127
|
-
<button onClick={handleRefresh}>Refresh Events</button>
|
|
1128
|
-
{/* Event list */}
|
|
1129
|
-
</div>
|
|
1130
|
-
);
|
|
1131
|
-
}
|
|
1132
|
-
```
|
|
1133
|
-
|
|
1134
|
-
## Network Issues
|
|
1135
|
-
|
|
1136
|
-
### 1. API Request Failures
|
|
1137
|
-
|
|
1138
|
-
**Problem**: API requests are failing with network errors.
|
|
1139
|
-
|
|
1140
|
-
**Solution**:
|
|
1141
|
-
|
|
1142
|
-
```typescript
|
|
1143
|
-
import { useUnifiedAuth } from '@jmruthers/pace-core';
|
|
1144
|
-
|
|
1145
|
-
function NetworkAwareComponent() {
|
|
1146
|
-
const { error } = useUnifiedAuth();
|
|
1147
|
-
|
|
1148
|
-
useEffect(() => {
|
|
1149
|
-
if (error) {
|
|
1150
|
-
console.error('Network error:', error);
|
|
1151
|
-
|
|
1152
|
-
// Check if it's a network issue
|
|
1153
|
-
if (error.message.includes('network') || error.message.includes('fetch')) {
|
|
1154
|
-
console.log('Network connectivity issue detected');
|
|
1155
|
-
// Implement retry logic or show offline message
|
|
1156
|
-
}
|
|
1157
|
-
}
|
|
1158
|
-
}, [error]);
|
|
1159
|
-
|
|
1160
|
-
return (
|
|
1161
|
-
<div>
|
|
1162
|
-
{error && (
|
|
1163
|
-
<div className="error">
|
|
1164
|
-
<p>Connection error: {error.message}</p>
|
|
1165
|
-
<button onClick={() => window.location.reload()}>
|
|
1166
|
-
Retry
|
|
1167
|
-
</button>
|
|
1168
|
-
</div>
|
|
1169
|
-
)}
|
|
1170
|
-
</div>
|
|
1171
|
-
);
|
|
120
|
+
const testConnection = async () => {
|
|
121
|
+
const { data, error } = await supabase
|
|
122
|
+
.from('organisations')
|
|
123
|
+
.select('id')
|
|
124
|
+
.limit(1)
|
|
125
|
+
|
|
126
|
+
console.log('Connection test:', { data, error })
|
|
1172
127
|
}
|
|
1173
128
|
```
|
|
1174
129
|
|
|
1175
|
-
###
|
|
1176
|
-
|
|
1177
|
-
**Problem**: Getting CORS errors when making requests.
|
|
1178
|
-
|
|
1179
|
-
**Solution**:
|
|
1180
|
-
|
|
1181
|
-
```typescript
|
|
1182
|
-
// Check Supabase configuration
|
|
1183
|
-
const supabase = createSupabaseClient(
|
|
1184
|
-
process.env.SUPABASE_URL!,
|
|
1185
|
-
process.env.SUPABASE_ANON_KEY!,
|
|
1186
|
-
{
|
|
1187
|
-
auth: {
|
|
1188
|
-
autoRefreshToken: true,
|
|
1189
|
-
persistSession: true,
|
|
1190
|
-
detectSessionInUrl: true,
|
|
1191
|
-
},
|
|
1192
|
-
}
|
|
1193
|
-
);
|
|
1194
|
-
```
|
|
1195
|
-
|
|
1196
|
-
## Environment Issues
|
|
1197
|
-
|
|
1198
|
-
### 1. Environment Variables Missing
|
|
1199
|
-
|
|
1200
|
-
**Problem**: Application is failing due to missing environment variables.
|
|
1201
|
-
|
|
1202
|
-
**Solution**:
|
|
1203
|
-
|
|
1204
|
-
```typescript
|
|
1205
|
-
// Validate environment variables
|
|
1206
|
-
const requiredEnvVars = [
|
|
1207
|
-
'SUPABASE_URL',
|
|
1208
|
-
'SUPABASE_ANON_KEY',
|
|
1209
|
-
'NODE_ENV',
|
|
1210
|
-
];
|
|
1211
|
-
|
|
1212
|
-
requiredEnvVars.forEach(varName => {
|
|
1213
|
-
if (!process.env[varName]) {
|
|
1214
|
-
console.error(`Missing environment variable: ${varName}`);
|
|
1215
|
-
throw new Error(`Missing required environment variable: ${varName}`);
|
|
1216
|
-
}
|
|
1217
|
-
});
|
|
1218
|
-
|
|
1219
|
-
console.log('Environment variables validated');
|
|
1220
|
-
```
|
|
1221
|
-
|
|
1222
|
-
### 2. Development vs Production Issues
|
|
1223
|
-
|
|
1224
|
-
**Problem**: Application works in development but not in production.
|
|
1225
|
-
|
|
1226
|
-
**Solution**:
|
|
1227
|
-
|
|
1228
|
-
```typescript
|
|
1229
|
-
// Environment-specific configuration
|
|
1230
|
-
const config = {
|
|
1231
|
-
development: {
|
|
1232
|
-
supabaseUrl: process.env.SUPABASE_URL,
|
|
1233
|
-
supabaseKey: process.env.SUPABASE_ANON_KEY,
|
|
1234
|
-
debug: true,
|
|
1235
|
-
},
|
|
1236
|
-
production: {
|
|
1237
|
-
supabaseUrl: process.env.SUPABASE_URL,
|
|
1238
|
-
supabaseKey: process.env.SUPABASE_ANON_KEY,
|
|
1239
|
-
debug: false,
|
|
1240
|
-
},
|
|
1241
|
-
};
|
|
1242
|
-
|
|
1243
|
-
const currentConfig = config[process.env.NODE_ENV || 'development'];
|
|
1244
|
-
```
|
|
1245
|
-
|
|
1246
|
-
## Debugging Tools
|
|
1247
|
-
|
|
1248
|
-
### 1. Debug Component
|
|
130
|
+
### 3. Check Provider Context
|
|
1249
131
|
|
|
1250
132
|
```typescript
|
|
1251
|
-
|
|
1252
|
-
const { user, session } = useUnifiedAuth();
|
|
1253
|
-
const { currentOrganisation } = useOrganisation();
|
|
1254
|
-
const { events, selectedEvent } = useEvents();
|
|
133
|
+
import { useUnifiedAuth } from '@jmruthers/pace-core'
|
|
1255
134
|
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
{JSON.stringify({
|
|
1261
|
-
user: user?.email,
|
|
1262
|
-
session: session?.expires_at,
|
|
1263
|
-
organisation: currentOrganisation?.name,
|
|
1264
|
-
events: events?.length,
|
|
1265
|
-
selectedEvent: selectedEvent?.name,
|
|
1266
|
-
}, null, 2)}
|
|
1267
|
-
</pre>
|
|
1268
|
-
</div>
|
|
1269
|
-
);
|
|
135
|
+
function DebugComponent() {
|
|
136
|
+
const auth = useUnifiedAuth()
|
|
137
|
+
console.log('Auth context:', auth)
|
|
138
|
+
return <div>Check console for auth context</div>
|
|
1270
139
|
}
|
|
1271
140
|
```
|
|
1272
141
|
|
|
1273
|
-
###
|
|
142
|
+
### 4. Verify RBAC Setup
|
|
1274
143
|
|
|
1275
144
|
```typescript
|
|
1276
|
-
import {
|
|
145
|
+
import { useRBAC } from '@jmruthers/pace-core'
|
|
1277
146
|
|
|
1278
|
-
function
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
onError={(error, errorInfo) => {
|
|
1283
|
-
console.error('Error caught by boundary:', error);
|
|
1284
|
-
console.error('Error info:', errorInfo);
|
|
1285
|
-
|
|
1286
|
-
// Send to error reporting service
|
|
1287
|
-
// reportError(error, errorInfo);
|
|
1288
|
-
}}
|
|
1289
|
-
>
|
|
1290
|
-
{children}
|
|
1291
|
-
</ErrorBoundary>
|
|
1292
|
-
);
|
|
147
|
+
function DebugRBAC() {
|
|
148
|
+
const rbac = useRBAC()
|
|
149
|
+
console.log('RBAC context:', rbac)
|
|
150
|
+
return <div>Check console for RBAC context</div>
|
|
1293
151
|
}
|
|
1294
152
|
```
|
|
1295
153
|
|
|
1296
|
-
##
|
|
1297
|
-
|
|
1298
|
-
### Public Pages Not Working
|
|
1299
|
-
|
|
1300
|
-
**Problem**: Public pages show authentication errors or don't load properly
|
|
1301
|
-
|
|
1302
|
-
**Root Cause**: Public pages are being rendered inside the authentication context
|
|
1303
|
-
|
|
1304
|
-
**Solution**: Public pages MUST be completely separate from your main app
|
|
1305
|
-
|
|
1306
|
-
```tsx
|
|
1307
|
-
// ❌ WRONG - This will break
|
|
1308
|
-
<UnifiedAuthProvider>
|
|
1309
|
-
<Routes>
|
|
1310
|
-
<Route path="/events/:eventCode" element={<PublicPage />} />
|
|
1311
|
-
</Routes>
|
|
1312
|
-
</UnifiedAuthProvider>
|
|
1313
|
-
|
|
1314
|
-
// ✅ CORRECT - Separate applications
|
|
1315
|
-
<BrowserRouter>
|
|
1316
|
-
<Routes>
|
|
1317
|
-
<Route path="/events/*" element={<PublicPageApp />} />
|
|
1318
|
-
<Route path="/*" element={
|
|
1319
|
-
<UnifiedAuthProvider>
|
|
1320
|
-
<AuthenticatedApp />
|
|
1321
|
-
</UnifiedAuthProvider>
|
|
1322
|
-
} />
|
|
1323
|
-
</Routes>
|
|
1324
|
-
</BrowserRouter>
|
|
1325
|
-
```
|
|
1326
|
-
|
|
1327
|
-
**Complete Setup:**
|
|
1328
|
-
```tsx
|
|
1329
|
-
// PublicPageApp.tsx
|
|
1330
|
-
import { PublicPageProvider } from '@jmruthers/pace-core';
|
|
1331
|
-
|
|
1332
|
-
export function PublicPageApp() {
|
|
1333
|
-
return (
|
|
1334
|
-
<PublicPageProvider>
|
|
1335
|
-
<Routes>
|
|
1336
|
-
<Route path="/events/:eventCode" element={<PublicEventPage />} />
|
|
1337
|
-
</Routes>
|
|
1338
|
-
</PublicPageProvider>
|
|
1339
|
-
);
|
|
1340
|
-
}
|
|
1341
|
-
```
|
|
1342
|
-
|
|
1343
|
-
### Public Page Hooks Not Working
|
|
1344
|
-
|
|
1345
|
-
**Problem**: `usePublicEvent` or `usePublicRouteParams` return null/undefined
|
|
1346
|
-
|
|
1347
|
-
**Root Cause**: Not using the hooks inside `PublicPageProvider`
|
|
1348
|
-
|
|
1349
|
-
**Solution**: Ensure all public page components are wrapped in `PublicPageProvider`
|
|
1350
|
-
|
|
1351
|
-
```tsx
|
|
1352
|
-
// ❌ WRONG - Hooks won't work
|
|
1353
|
-
function PublicPage() {
|
|
1354
|
-
const { eventCode } = usePublicRouteParams(); // Returns null
|
|
1355
|
-
// ...
|
|
1356
|
-
}
|
|
1357
|
-
|
|
1358
|
-
// ✅ CORRECT - Hooks work properly
|
|
1359
|
-
<PublicPageProvider>
|
|
1360
|
-
<PublicPage /> {/* Hooks work here */}
|
|
1361
|
-
</PublicPageProvider>
|
|
1362
|
-
```
|
|
1363
|
-
|
|
1364
|
-
### Public Page Loading Forever
|
|
1365
|
-
|
|
1366
|
-
**Problem**: Public pages show loading spinner indefinitely
|
|
1367
|
-
|
|
1368
|
-
**Root Cause**: Event data not found or API errors
|
|
1369
|
-
|
|
1370
|
-
**Solution**: Add proper error handling and fallbacks
|
|
1371
|
-
|
|
1372
|
-
```tsx
|
|
1373
|
-
function PublicEventPage() {
|
|
1374
|
-
const { eventCode } = usePublicRouteParams({ fetchEventData: false });
|
|
1375
|
-
const { event, isLoading, error, refetch } = usePublicEvent(eventCode || '');
|
|
1376
|
-
|
|
1377
|
-
// Handle loading
|
|
1378
|
-
if (isLoading) {
|
|
1379
|
-
return <PublicLoadingSpinner message="Loading event..." />;
|
|
1380
|
-
}
|
|
1381
|
-
|
|
1382
|
-
// Handle error
|
|
1383
|
-
if (error) {
|
|
1384
|
-
return (
|
|
1385
|
-
<div className="min-h-screen bg-white flex items-center justify-center">
|
|
1386
|
-
<div className="text-center">
|
|
1387
|
-
<h1 className="text-2xl font-bold text-gray-900 mb-4">
|
|
1388
|
-
Event Not Found
|
|
1389
|
-
</h1>
|
|
1390
|
-
<p className="text-gray-600 mb-6">
|
|
1391
|
-
The event code "{eventCode}" is invalid or not available for public viewing.
|
|
1392
|
-
</p>
|
|
1393
|
-
<button
|
|
1394
|
-
onClick={refetch}
|
|
1395
|
-
className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700"
|
|
1396
|
-
>
|
|
1397
|
-
Try Again
|
|
1398
|
-
</button>
|
|
1399
|
-
</div>
|
|
1400
|
-
</div>
|
|
1401
|
-
);
|
|
1402
|
-
}
|
|
1403
|
-
|
|
1404
|
-
// Handle missing event
|
|
1405
|
-
if (!event) {
|
|
1406
|
-
return <div>Event not found</div>;
|
|
1407
|
-
}
|
|
1408
|
-
|
|
1409
|
-
// Render the page
|
|
1410
|
-
return (
|
|
1411
|
-
<PublicPageLayout eventCode={eventCode || ''} event={event}>
|
|
1412
|
-
{/* Your content */}
|
|
1413
|
-
</PublicPageLayout>
|
|
1414
|
-
);
|
|
1415
|
-
}
|
|
1416
|
-
```
|
|
1417
|
-
|
|
1418
|
-
### Public Page Styling Issues
|
|
1419
|
-
|
|
1420
|
-
**Problem**: Public pages appear unstyled or broken
|
|
1421
|
-
|
|
1422
|
-
**Root Cause**: Missing CSS import or Tailwind configuration
|
|
1423
|
-
|
|
1424
|
-
**Solution**: Ensure CSS is imported and Tailwind is configured
|
|
1425
|
-
|
|
1426
|
-
```tsx
|
|
1427
|
-
// Make sure to import CSS
|
|
1428
|
-
import '@jmruthers/pace-core/styles/core.css';
|
|
1429
|
-
|
|
1430
|
-
// And configure Tailwind properly
|
|
1431
|
-
// vite.config.ts
|
|
1432
|
-
import tailwindcss from '@tailwindcss/vite'
|
|
1433
|
-
export default defineConfig({
|
|
1434
|
-
plugins: [
|
|
1435
|
-
react(),
|
|
1436
|
-
tailwindcss({
|
|
1437
|
-
content: [
|
|
1438
|
-
'./src/**/*.{js,ts,jsx,tsx}',
|
|
1439
|
-
'./node_modules/@jmruthers/pace-core/**/*.{js,ts,jsx,tsx}'
|
|
1440
|
-
]
|
|
1441
|
-
})
|
|
1442
|
-
],
|
|
1443
|
-
})
|
|
1444
|
-
```
|
|
1445
|
-
|
|
1446
|
-
### Public Page Environment Variables
|
|
1447
|
-
|
|
1448
|
-
**Problem**: Public pages can't access Supabase or environment variables
|
|
1449
|
-
|
|
1450
|
-
**Root Cause**: Missing environment variables or incorrect configuration
|
|
1451
|
-
|
|
1452
|
-
**Solution**: Set up environment variables and pass them to `PublicPageProvider`
|
|
1453
|
-
|
|
1454
|
-
```tsx
|
|
1455
|
-
// .env.local
|
|
1456
|
-
VITE_SUPABASE_URL=your_supabase_url
|
|
1457
|
-
VITE_SUPABASE_ANON_KEY=your_supabase_anon_key
|
|
1458
|
-
VITE_APP_NAME=Your App Name
|
|
1459
|
-
|
|
1460
|
-
// PublicPageApp.tsx
|
|
1461
|
-
import { PublicPageProvider } from '@jmruthers/pace-core';
|
|
1462
|
-
|
|
1463
|
-
export function PublicPageApp() {
|
|
1464
|
-
return (
|
|
1465
|
-
<PublicPageProvider
|
|
1466
|
-
environment={{
|
|
1467
|
-
supabaseUrl: import.meta.env.VITE_SUPABASE_URL,
|
|
1468
|
-
supabaseKey: import.meta.env.VITE_SUPABASE_ANON_KEY,
|
|
1469
|
-
}}
|
|
1470
|
-
>
|
|
1471
|
-
<Routes>
|
|
1472
|
-
<Route path="/events/:eventCode" element={<PublicEventPage />} />
|
|
1473
|
-
</Routes>
|
|
1474
|
-
</PublicPageProvider>
|
|
1475
|
-
);
|
|
1476
|
-
}
|
|
1477
|
-
```
|
|
1478
|
-
|
|
1479
|
-
### Public Page "process is not defined" Error
|
|
1480
|
-
|
|
1481
|
-
**Problem**: `ReferenceError: process is not defined` when using `PublicPageProvider` in Vite-based applications
|
|
1482
|
-
|
|
1483
|
-
**Root Cause**: The component is trying to access Node.js globals (`process`) that aren't available in browser environments
|
|
1484
|
-
|
|
1485
|
-
**Solution**: This has been fixed in pace-core v0.4.61+. The `PublicPageProvider` now safely handles both browser and Node.js environments.
|
|
1486
|
-
|
|
1487
|
-
**If you're still seeing this error:**
|
|
1488
|
-
|
|
1489
|
-
1. **Update pace-core** to the latest version:
|
|
1490
|
-
```bash
|
|
1491
|
-
npm update @jmruthers/pace-core
|
|
1492
|
-
```
|
|
1493
|
-
|
|
1494
|
-
2. **Verify your Vite configuration** includes environment variable support:
|
|
1495
|
-
```ts
|
|
1496
|
-
// vite.config.ts
|
|
1497
|
-
export default defineConfig({
|
|
1498
|
-
plugins: [react(), tailwindcss()],
|
|
1499
|
-
envDir: '.', // Look for .env files in root
|
|
1500
|
-
envPrefix: 'VITE_', // Only load VITE_ prefixed variables
|
|
1501
|
-
})
|
|
1502
|
-
```
|
|
1503
|
-
|
|
1504
|
-
3. **Set up environment variables** in your `.env` file:
|
|
1505
|
-
```bash
|
|
1506
|
-
# .env.local
|
|
1507
|
-
VITE_SUPABASE_URL=your_supabase_url
|
|
1508
|
-
VITE_SUPABASE_ANON_KEY=your_supabase_anon_key
|
|
1509
|
-
```
|
|
1510
|
-
|
|
1511
|
-
4. **Use the correct environment variable names**:
|
|
1512
|
-
- ✅ `VITE_SUPABASE_URL` (Vite)
|
|
1513
|
-
- ✅ `NEXT_PUBLIC_SUPABASE_URL` (Next.js)
|
|
1514
|
-
- ❌ `SUPABASE_URL` (not prefixed for Vite)
|
|
1515
|
-
|
|
1516
|
-
**The fix ensures:**
|
|
1517
|
-
- ✅ Safe access to `import.meta.env` (Vite/browser)
|
|
1518
|
-
- ✅ Safe access to `process.env` (Node.js/server)
|
|
1519
|
-
- ✅ Proper fallback handling
|
|
1520
|
-
- ✅ No "process is not defined" errors
|
|
1521
|
-
|
|
1522
|
-
### Public Page Database Access
|
|
1523
|
-
|
|
1524
|
-
**Problem**: Public pages can't access event data from database
|
|
1525
|
-
|
|
1526
|
-
**Root Cause**: Missing RLS policies or incorrect database setup
|
|
1527
|
-
|
|
1528
|
-
**Solution**: Set up proper RLS policies for public access
|
|
1529
|
-
|
|
1530
|
-
```sql
|
|
1531
|
-
-- Enable RLS on events table
|
|
1532
|
-
ALTER TABLE events ENABLE ROW LEVEL SECURITY;
|
|
1533
|
-
|
|
1534
|
-
-- Create policy for public events
|
|
1535
|
-
CREATE POLICY "Public events are viewable by anyone" ON events
|
|
1536
|
-
FOR SELECT USING (is_public = true);
|
|
1537
|
-
|
|
1538
|
-
-- Or allow specific event codes
|
|
1539
|
-
CREATE POLICY "Specific event codes are public" ON events
|
|
1540
|
-
FOR SELECT USING (event_code IN ('EVENT123', 'EVENT456'));
|
|
1541
|
-
```
|
|
1542
|
-
|
|
1543
|
-
## Getting Help
|
|
1544
|
-
|
|
1545
|
-
If you're still experiencing issues:
|
|
1546
|
-
|
|
1547
|
-
1. **Check the console** for error messages
|
|
1548
|
-
2. **Verify your configuration** (environment variables, Supabase setup)
|
|
1549
|
-
3. **Test with minimal setup** to isolate the issue
|
|
1550
|
-
4. **Check the documentation** for specific component usage
|
|
1551
|
-
5. **Search existing issues** in the GitHub repository
|
|
1552
|
-
6. **Create a new issue** with detailed information about your problem
|
|
154
|
+
## 🆘 **Still Having Issues?**
|
|
1553
155
|
|
|
1554
|
-
|
|
156
|
+
If you're still experiencing problems after following this guide:
|
|
1555
157
|
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
- **Error messages**: Full error messages from console
|
|
1561
|
-
- **Code example**: Minimal code that reproduces the issue
|
|
158
|
+
1. **Check the browser console** for detailed error messages
|
|
159
|
+
2. **Verify your Supabase project** has the pace-core schema
|
|
160
|
+
3. **Ensure you're using the correct API key** (anon, not service role)
|
|
161
|
+
4. **Test with a minimal setup** to isolate the issue
|
|
1562
162
|
|
|
1563
|
-
|
|
163
|
+
The most common issue is using the **service role key** instead of the **anon key**. The service role key bypasses RLS policies and can cause unexpected behavior with RPC calls.
|