@chaaskit/client 0.1.0 → 0.1.2

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 (96) hide show
  1. package/LICENSE +21 -0
  2. package/dist/lib/index.js +1023 -160
  3. package/dist/lib/index.js.map +1 -1
  4. package/dist/lib/routes/AcceptInviteRoute.js +1 -1
  5. package/dist/lib/routes/AcceptInviteRoute.js.map +1 -1
  6. package/dist/lib/routes/AdminDashboardRoute.js +1 -1
  7. package/dist/lib/routes/AdminDashboardRoute.js.map +1 -1
  8. package/dist/lib/routes/AdminPromoCodesRoute.js +19 -0
  9. package/dist/lib/routes/AdminPromoCodesRoute.js.map +1 -0
  10. package/dist/lib/routes/AdminTeamRoute.js +1 -1
  11. package/dist/lib/routes/AdminTeamRoute.js.map +1 -1
  12. package/dist/lib/routes/AdminTeamsRoute.js +1 -1
  13. package/dist/lib/routes/AdminTeamsRoute.js.map +1 -1
  14. package/dist/lib/routes/AdminUsersRoute.js +1 -1
  15. package/dist/lib/routes/AdminUsersRoute.js.map +1 -1
  16. package/dist/lib/routes/AdminWaitlistRoute.js +19 -0
  17. package/dist/lib/routes/AdminWaitlistRoute.js.map +1 -0
  18. package/dist/lib/routes/ApiKeysRoute.js +1 -1
  19. package/dist/lib/routes/ApiKeysRoute.js.map +1 -1
  20. package/dist/lib/routes/AutomationsRoute.js +1 -1
  21. package/dist/lib/routes/AutomationsRoute.js.map +1 -1
  22. package/dist/lib/routes/ChatRoute.js +1 -1
  23. package/dist/lib/routes/ChatRoute.js.map +1 -1
  24. package/dist/lib/routes/DocumentsRoute.js +1 -1
  25. package/dist/lib/routes/DocumentsRoute.js.map +1 -1
  26. package/dist/lib/routes/OAuthConsentRoute.js +1 -1
  27. package/dist/lib/routes/OAuthConsentRoute.js.map +1 -1
  28. package/dist/lib/routes/PricingRoute.js +1 -1
  29. package/dist/lib/routes/PricingRoute.js.map +1 -1
  30. package/dist/lib/routes/PrivacyRoute.js +1 -1
  31. package/dist/lib/routes/PrivacyRoute.js.map +1 -1
  32. package/dist/lib/routes/TeamSettingsRoute.js +1 -1
  33. package/dist/lib/routes/TeamSettingsRoute.js.map +1 -1
  34. package/dist/lib/routes/TermsRoute.js +1 -1
  35. package/dist/lib/routes/TermsRoute.js.map +1 -1
  36. package/dist/lib/routes/VerifyEmailRoute.js +1 -1
  37. package/dist/lib/routes/VerifyEmailRoute.js.map +1 -1
  38. package/dist/lib/routes.js +47 -37
  39. package/dist/lib/routes.js.map +1 -1
  40. package/dist/lib/ssr-utils.js +64 -1
  41. package/dist/lib/ssr-utils.js.map +1 -1
  42. package/dist/lib/ssr.js +23 -0
  43. package/dist/lib/ssr.js.map +1 -1
  44. package/dist/lib/styles.css +58 -62
  45. package/dist/lib/useExtensions-B5nX_8XD.js.map +1 -1
  46. package/package.json +25 -12
  47. package/src/components/MessageItem.tsx +35 -4
  48. package/src/components/MessageList.tsx +51 -5
  49. package/src/components/OAuthAppsSection.tsx +1 -1
  50. package/src/components/Sidebar.tsx +1 -3
  51. package/src/components/ToolCallDisplay.tsx +102 -11
  52. package/src/components/tool-renderers/DocumentListRenderer.tsx +44 -0
  53. package/src/components/tool-renderers/DocumentReadRenderer.tsx +33 -0
  54. package/src/components/tool-renderers/DocumentSaveRenderer.tsx +32 -0
  55. package/src/components/tool-renderers/DocumentSearchRenderer.tsx +33 -0
  56. package/src/components/tool-renderers/index.ts +36 -0
  57. package/src/components/tool-renderers/utils.ts +7 -0
  58. package/src/contexts/AuthContext.tsx +16 -6
  59. package/src/contexts/ConfigContext.tsx +60 -28
  60. package/src/contexts/ThemeContext.tsx +39 -68
  61. package/src/extensions/registry.ts +2 -1
  62. package/src/hooks/__tests__/basePath.test.ts +42 -0
  63. package/src/index.tsx +11 -2
  64. package/src/pages/AdminDashboardPage.tsx +15 -1
  65. package/src/pages/AdminPromoCodesPage.tsx +378 -0
  66. package/src/pages/AdminTeamPage.tsx +29 -1
  67. package/src/pages/AdminTeamsPage.tsx +15 -1
  68. package/src/pages/AdminUsersPage.tsx +15 -1
  69. package/src/pages/AdminWaitlistPage.tsx +156 -0
  70. package/src/pages/RegisterPage.tsx +91 -9
  71. package/src/routes/AcceptInviteRoute.tsx +1 -1
  72. package/src/routes/AdminDashboardRoute.tsx +1 -1
  73. package/src/routes/AdminPromoCodesRoute.tsx +24 -0
  74. package/src/routes/AdminTeamRoute.tsx +1 -1
  75. package/src/routes/AdminTeamsRoute.tsx +1 -1
  76. package/src/routes/AdminUsersRoute.tsx +1 -1
  77. package/src/routes/AdminWaitlistRoute.tsx +24 -0
  78. package/src/routes/ApiKeysRoute.tsx +1 -1
  79. package/src/routes/AutomationsRoute.tsx +1 -1
  80. package/src/routes/ChatRoute.tsx +2 -1
  81. package/src/routes/DocumentsRoute.tsx +1 -1
  82. package/src/routes/OAuthConsentRoute.tsx +1 -1
  83. package/src/routes/PricingRoute.tsx +1 -1
  84. package/src/routes/PrivacyRoute.tsx +1 -1
  85. package/src/routes/TeamSettingsRoute.tsx +1 -1
  86. package/src/routes/TermsRoute.tsx +1 -1
  87. package/src/routes/VerifyEmailRoute.tsx +1 -1
  88. package/src/routes/index.ts +2 -0
  89. package/src/ssr-utils.tsx +100 -1
  90. package/src/ssr.ts +59 -0
  91. package/src/stores/chatStore.ts +5 -0
  92. package/src/styles/index.css +16 -63
  93. package/src/tailwind-preset.js +360 -0
  94. package/dist/favicon.svg +0 -11
  95. package/dist/index.html +0 -17
  96. package/dist/logo.svg +0 -12
@@ -1,6 +1,6 @@
1
1
  import { useState, useEffect } from 'react';
2
2
  import { Link, useParams } from 'react-router';
3
- import { LayoutDashboard, X, Users, Building2 } from 'lucide-react';
3
+ import { LayoutDashboard, X, Users, Building2, Mail, Tag } from 'lucide-react';
4
4
  import { useAppPath } from '../hooks/useAppPath';
5
5
  import { api } from '../utils/api';
6
6
  import type { AdminTeamDetails } from '@chaaskit/shared';
@@ -86,6 +86,20 @@ export default function AdminTeamPage() {
86
86
  <Building2 size={16} />
87
87
  Teams
88
88
  </Link>
89
+ <Link
90
+ to={appPath('/admin/waitlist')}
91
+ className="flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80"
92
+ >
93
+ <Mail size={16} />
94
+ Waitlist
95
+ </Link>
96
+ <Link
97
+ to={appPath('/admin/promo-codes')}
98
+ className="flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80"
99
+ >
100
+ <Tag size={16} />
101
+ Promo Codes
102
+ </Link>
89
103
  </div>
90
104
 
91
105
  <div className="rounded-lg bg-error/10 p-4 text-sm text-error">
@@ -142,6 +156,20 @@ export default function AdminTeamPage() {
142
156
  <Building2 size={16} />
143
157
  Teams
144
158
  </Link>
159
+ <Link
160
+ to={appPath('/admin/waitlist')}
161
+ className="flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80"
162
+ >
163
+ <Mail size={16} />
164
+ Waitlist
165
+ </Link>
166
+ <Link
167
+ to={appPath('/admin/promo-codes')}
168
+ className="flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80"
169
+ >
170
+ <Tag size={16} />
171
+ Promo Codes
172
+ </Link>
145
173
  </div>
146
174
 
147
175
  {/* Team Header */}
@@ -1,6 +1,6 @@
1
1
  import { useState, useEffect, useCallback } from 'react';
2
2
  import { Link } from 'react-router';
3
- import { LayoutDashboard, X, Users, Building2 } from 'lucide-react';
3
+ import { LayoutDashboard, X, Users, Building2, Mail, Tag } from 'lucide-react';
4
4
  import { useAppPath } from '../hooks/useAppPath';
5
5
  import { api } from '../utils/api';
6
6
  import type { AdminTeam, AdminTeamsResponse } from '@chaaskit/shared';
@@ -91,6 +91,20 @@ export default function AdminTeamsPage() {
91
91
  <Building2 size={16} />
92
92
  Teams
93
93
  </Link>
94
+ <Link
95
+ to={appPath('/admin/waitlist')}
96
+ className="flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80"
97
+ >
98
+ <Mail size={16} />
99
+ Waitlist
100
+ </Link>
101
+ <Link
102
+ to={appPath('/admin/promo-codes')}
103
+ className="flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80"
104
+ >
105
+ <Tag size={16} />
106
+ Promo Codes
107
+ </Link>
94
108
  </div>
95
109
 
96
110
  {error && (
@@ -1,6 +1,6 @@
1
1
  import { useState, useEffect, useCallback } from 'react';
2
2
  import { Link } from 'react-router';
3
- import { LayoutDashboard, X, Users, Building2 } from 'lucide-react';
3
+ import { LayoutDashboard, X, Users, Building2, Mail, Tag } from 'lucide-react';
4
4
  import { useConfig } from '../contexts/ConfigContext';
5
5
  import { useAppPath } from '../hooks/useAppPath';
6
6
  import { api } from '../utils/api';
@@ -134,6 +134,20 @@ export default function AdminUsersPage() {
134
134
  Teams
135
135
  </Link>
136
136
  )}
137
+ <Link
138
+ to={appPath('/admin/waitlist')}
139
+ className="flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80"
140
+ >
141
+ <Mail size={16} />
142
+ Waitlist
143
+ </Link>
144
+ <Link
145
+ to={appPath('/admin/promo-codes')}
146
+ className="flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80"
147
+ >
148
+ <Tag size={16} />
149
+ Promo Codes
150
+ </Link>
137
151
  </div>
138
152
 
139
153
  {error && (
@@ -0,0 +1,156 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { Link } from 'react-router';
3
+ import { LayoutDashboard, Users, Building2, X, Mail, Tag } from 'lucide-react';
4
+ import { useConfig } from '../contexts/ConfigContext';
5
+ import { useAppPath } from '../hooks/useAppPath';
6
+ import { api } from '../utils/api';
7
+ import type { AdminWaitlistEntry, AdminWaitlistResponse } from '@chaaskit/shared';
8
+
9
+ export default function AdminWaitlistPage() {
10
+ const config = useConfig();
11
+ const appPath = useAppPath();
12
+ const [entries, setEntries] = useState<AdminWaitlistEntry[]>([]);
13
+ const [isLoading, setIsLoading] = useState(true);
14
+ const [error, setError] = useState('');
15
+ const [success, setSuccess] = useState('');
16
+
17
+ async function loadWaitlist() {
18
+ setIsLoading(true);
19
+ setError('');
20
+
21
+ try {
22
+ const response = await api.get<AdminWaitlistResponse>('/api/admin/waitlist');
23
+ setEntries(response.entries);
24
+ } catch (err) {
25
+ setError(err instanceof Error ? err.message : 'Failed to load waitlist');
26
+ } finally {
27
+ setIsLoading(false);
28
+ }
29
+ }
30
+
31
+ useEffect(() => {
32
+ loadWaitlist();
33
+ }, []);
34
+
35
+ async function handleInvite(entryId: string, email: string) {
36
+ setError('');
37
+ setSuccess('');
38
+
39
+ try {
40
+ await api.post(`/api/admin/waitlist/${entryId}/invite`, {});
41
+ setSuccess(`Invite sent to ${email}`);
42
+ loadWaitlist();
43
+ } catch (err) {
44
+ setError(err instanceof Error ? err.message : 'Failed to send invite');
45
+ }
46
+ }
47
+
48
+ return (
49
+ <div className="min-h-screen bg-background p-4 sm:p-8">
50
+ <div className="mx-auto max-w-6xl">
51
+ <div className="flex items-center justify-between mb-4">
52
+ <h1 className="text-xl sm:text-2xl font-bold text-text-primary">Admin</h1>
53
+ <Link
54
+ to={appPath('/')}
55
+ className="flex items-center justify-center rounded-lg p-2 text-text-muted hover:text-text-primary hover:bg-background-secondary"
56
+ aria-label="Close"
57
+ >
58
+ <X size={20} />
59
+ </Link>
60
+ </div>
61
+
62
+ <div className="flex items-center gap-2 mb-6 sm:mb-8">
63
+ <Link
64
+ to={appPath('/admin')}
65
+ className="flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80"
66
+ >
67
+ <LayoutDashboard size={16} />
68
+ Overview
69
+ </Link>
70
+ <Link
71
+ to={appPath('/admin/users')}
72
+ className="flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80"
73
+ >
74
+ <Users size={16} />
75
+ Users
76
+ </Link>
77
+ {config.teams?.enabled && (
78
+ <Link
79
+ to={appPath('/admin/teams')}
80
+ className="flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80"
81
+ >
82
+ <Building2 size={16} />
83
+ Teams
84
+ </Link>
85
+ )}
86
+ <Link
87
+ to={appPath('/admin/promo-codes')}
88
+ className="flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80"
89
+ >
90
+ <Tag size={16} />
91
+ Promo Codes
92
+ </Link>
93
+ <span className="flex items-center gap-1.5 rounded-full bg-primary px-4 py-2 text-sm font-medium text-white">
94
+ <Mail size={16} />
95
+ Waitlist
96
+ </span>
97
+ </div>
98
+
99
+ {error && (
100
+ <div className="mb-6 rounded-lg bg-error/10 p-4 text-sm text-error">
101
+ {error}
102
+ </div>
103
+ )}
104
+
105
+ {success && (
106
+ <div className="mb-6 rounded-lg bg-success/10 p-4 text-sm text-success">
107
+ {success}
108
+ </div>
109
+ )}
110
+
111
+ <div className="rounded-lg bg-background-secondary overflow-hidden">
112
+ <div className="hidden md:block px-4 py-3 bg-background">
113
+ <div className="grid grid-cols-12 gap-4 text-sm font-medium text-text-muted">
114
+ <div className="col-span-4">Email</div>
115
+ <div className="col-span-2">Name</div>
116
+ <div className="col-span-2">Status</div>
117
+ <div className="col-span-2">Joined</div>
118
+ <div className="col-span-2">Action</div>
119
+ </div>
120
+ </div>
121
+
122
+ <div className="divide-y divide-background">
123
+ {isLoading ? (
124
+ <div className="px-4 py-8 text-center text-text-muted">Loading...</div>
125
+ ) : entries.length === 0 ? (
126
+ <div className="px-4 py-8 text-center text-text-muted">No waitlist entries</div>
127
+ ) : (
128
+ entries.map((entry) => (
129
+ <div key={entry.id} className="px-4 py-3 hover:bg-background/50">
130
+ <div className="grid grid-cols-1 md:grid-cols-12 gap-2 md:gap-4 text-sm">
131
+ <div className="md:col-span-4 text-text-primary">{entry.email}</div>
132
+ <div className="md:col-span-2 text-text-secondary">{entry.name || '-'}</div>
133
+ <div className="md:col-span-2 capitalize text-text-secondary">{entry.status.replace('_', ' ')}</div>
134
+ <div className="md:col-span-2 text-text-muted">
135
+ {new Date(entry.createdAt).toLocaleDateString()}
136
+ </div>
137
+ <div className="md:col-span-2">
138
+ <button
139
+ type="button"
140
+ onClick={() => handleInvite(entry.id, entry.email)}
141
+ disabled={entry.status === 'invited'}
142
+ className="rounded-lg bg-primary px-3 py-1.5 text-xs font-medium text-white hover:bg-primary-hover disabled:opacity-50"
143
+ >
144
+ {entry.status === 'invited' ? 'Invited' : 'Invite'}
145
+ </button>
146
+ </div>
147
+ </div>
148
+ </div>
149
+ ))
150
+ )}
151
+ </div>
152
+ </div>
153
+ </div>
154
+ </div>
155
+ );
156
+ }
@@ -1,9 +1,10 @@
1
1
  import { useState } from 'react';
2
- import { Link, useNavigate } from 'react-router';
2
+ import { Link, useNavigate, useSearchParams } from 'react-router';
3
3
  import { useAuth } from '../contexts/AuthContext';
4
4
  import { useConfig } from '../contexts/ConfigContext';
5
5
  import { useTheme } from '../contexts/ThemeContext';
6
6
  import { useAppPath } from '../hooks/useAppPath';
7
+ import { api } from '../utils/api';
7
8
 
8
9
  export default function RegisterPage() {
9
10
  const navigate = useNavigate();
@@ -11,12 +12,22 @@ export default function RegisterPage() {
11
12
  const { register } = useAuth();
12
13
  const config = useConfig();
13
14
  const { theme } = useTheme();
15
+ const [searchParams] = useSearchParams();
16
+
17
+ const inviteToken = searchParams.get('invite') || undefined;
18
+ const referralCode = searchParams.get('ref') || undefined;
19
+ const gating = config.auth.gating;
20
+ const signupsRestricted = gating?.mode && gating.mode !== 'open' && !inviteToken;
21
+ const waitlistEnabled = gating?.waitlistEnabled ?? false;
22
+ const showWaitlist = !!signupsRestricted && waitlistEnabled;
23
+ const showRestrictedMessage = !!signupsRestricted && !waitlistEnabled;
14
24
 
15
25
  const [name, setName] = useState('');
16
26
  const [email, setEmail] = useState('');
17
27
  const [password, setPassword] = useState('');
18
28
  const [error, setError] = useState('');
19
29
  const [isLoading, setIsLoading] = useState(false);
30
+ const [waitlistStatus, setWaitlistStatus] = useState<'idle' | 'submitted'>('idle');
20
31
 
21
32
  async function handleSubmit(e: React.FormEvent) {
22
33
  e.preventDefault();
@@ -30,7 +41,10 @@ export default function RegisterPage() {
30
41
  setIsLoading(true);
31
42
 
32
43
  try {
33
- const { requiresVerification } = await register(email, password, name || undefined);
44
+ const { requiresVerification } = await register(email, password, name || undefined, {
45
+ inviteToken,
46
+ referralCode,
47
+ });
34
48
  if (requiresVerification) {
35
49
  navigate('/verify-email');
36
50
  } else {
@@ -43,6 +57,18 @@ export default function RegisterPage() {
43
57
  }
44
58
  }
45
59
 
60
+ async function handleWaitlistSubmit(e: React.FormEvent) {
61
+ e.preventDefault();
62
+ setError('');
63
+
64
+ try {
65
+ await api.post('/api/auth/waitlist', { email, name: name || undefined });
66
+ setWaitlistStatus('submitted');
67
+ } catch (err) {
68
+ setError(err instanceof Error ? err.message : 'Failed to join waitlist');
69
+ }
70
+ }
71
+
46
72
  return (
47
73
  <div className="flex min-h-screen items-center justify-center bg-background p-4">
48
74
  <div className="w-full max-w-md">
@@ -66,7 +92,60 @@ export default function RegisterPage() {
66
92
  </div>
67
93
  )}
68
94
 
69
- <form onSubmit={handleSubmit} className="space-y-4">
95
+ {showRestrictedMessage ? (
96
+ <div className="rounded-lg border border-border bg-background-secondary p-4 text-sm text-text-secondary">
97
+ Signups are currently closed. Please check back later.
98
+ </div>
99
+ ) : showWaitlist ? (
100
+ <div className="rounded-lg border border-border bg-background-secondary p-4">
101
+ <p className="text-sm text-text-secondary">
102
+ Signups are currently restricted. Join the waitlist to get an invite.
103
+ </p>
104
+
105
+ {waitlistStatus === 'submitted' ? (
106
+ <div className="mt-4 rounded-lg bg-success/10 p-3 text-sm text-success">
107
+ Thanks! You’re on the waitlist.
108
+ </div>
109
+ ) : (
110
+ <form onSubmit={handleWaitlistSubmit} className="mt-4 space-y-3">
111
+ <div>
112
+ <label htmlFor="waitlist-name" className="block text-sm font-medium text-text-primary">
113
+ Name (optional)
114
+ </label>
115
+ <input
116
+ type="text"
117
+ id="waitlist-name"
118
+ value={name}
119
+ onChange={(e) => setName(e.target.value)}
120
+ className="mt-1 w-full rounded-lg border border-input-border bg-input-background px-4 py-2 text-text-primary focus:border-primary focus:outline-none"
121
+ />
122
+ </div>
123
+
124
+ <div>
125
+ <label htmlFor="waitlist-email" className="block text-sm font-medium text-text-primary">
126
+ Email
127
+ </label>
128
+ <input
129
+ type="email"
130
+ id="waitlist-email"
131
+ value={email}
132
+ onChange={(e) => setEmail(e.target.value)}
133
+ required
134
+ className="mt-1 w-full rounded-lg border border-input-border bg-input-background px-4 py-2 text-text-primary focus:border-primary focus:outline-none"
135
+ />
136
+ </div>
137
+
138
+ <button
139
+ type="submit"
140
+ className="w-full rounded-lg bg-primary px-4 py-2 font-medium text-white hover:bg-primary-hover"
141
+ >
142
+ Join waitlist
143
+ </button>
144
+ </form>
145
+ )}
146
+ </div>
147
+ ) : (
148
+ <form onSubmit={handleSubmit} className="space-y-4">
70
149
  <div>
71
150
  <label
72
151
  htmlFor="name"
@@ -129,13 +208,16 @@ export default function RegisterPage() {
129
208
  {isLoading ? 'Creating account...' : 'Create account'}
130
209
  </button>
131
210
  </form>
211
+ )}
132
212
 
133
- <p className="mt-6 text-center text-sm text-text-secondary">
134
- Already have an account?{' '}
135
- <Link to="/login" className="text-primary hover:underline">
136
- Sign in
137
- </Link>
138
- </p>
213
+ {!signupsRestricted && (
214
+ <p className="mt-6 text-center text-sm text-text-secondary">
215
+ Already have an account?{' '}
216
+ <Link to="/login" className="text-primary hover:underline">
217
+ Sign in
218
+ </Link>
219
+ </p>
220
+ )}
139
221
 
140
222
  <p className="mt-4 text-center text-xs text-text-muted">
141
223
  By creating an account, you agree to our{' '}
@@ -10,7 +10,7 @@ export function meta() {
10
10
  }
11
11
 
12
12
  export function links() {
13
- return [{ rel: 'stylesheet', href: '/node_modules/@chaaskit/client/dist/lib/styles.css' }];
13
+ return [];
14
14
  }
15
15
 
16
16
  export default function AcceptInviteRoute() {
@@ -10,7 +10,7 @@ export function meta() {
10
10
  }
11
11
 
12
12
  export function links() {
13
- return [{ rel: 'stylesheet', href: '/node_modules/@chaaskit/client/dist/lib/styles.css' }];
13
+ return [];
14
14
  }
15
15
 
16
16
  export default function AdminDashboardRoute() {
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Admin Promo Codes Route - Promo code management
3
+ */
4
+ import { ChatProviders } from '../index';
5
+ import AdminPromoCodesPage from '../pages/AdminPromoCodesPage';
6
+ import { SimpleLoadingSkeleton } from '../components/LoadingSkeletons';
7
+
8
+ export function meta() {
9
+ return [{ title: 'Admin - Promo Codes' }];
10
+ }
11
+
12
+ export function links() {
13
+ return [];
14
+ }
15
+
16
+ export default function AdminPromoCodesRoute() {
17
+ return (
18
+ <ChatProviders>
19
+ <AdminPromoCodesPage />
20
+ </ChatProviders>
21
+ );
22
+ }
23
+
24
+ export { SimpleLoadingSkeleton as LoadingSkeleton };
@@ -10,7 +10,7 @@ export function meta() {
10
10
  }
11
11
 
12
12
  export function links() {
13
- return [{ rel: 'stylesheet', href: '/node_modules/@chaaskit/client/dist/lib/styles.css' }];
13
+ return [];
14
14
  }
15
15
 
16
16
  export default function AdminTeamRoute() {
@@ -10,7 +10,7 @@ export function meta() {
10
10
  }
11
11
 
12
12
  export function links() {
13
- return [{ rel: 'stylesheet', href: '/node_modules/@chaaskit/client/dist/lib/styles.css' }];
13
+ return [];
14
14
  }
15
15
 
16
16
  export default function AdminTeamsRoute() {
@@ -10,7 +10,7 @@ export function meta() {
10
10
  }
11
11
 
12
12
  export function links() {
13
- return [{ rel: 'stylesheet', href: '/node_modules/@chaaskit/client/dist/lib/styles.css' }];
13
+ return [];
14
14
  }
15
15
 
16
16
  export default function AdminUsersRoute() {
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Admin Waitlist Route - Waitlist management
3
+ */
4
+ import { ChatProviders } from '../index';
5
+ import AdminWaitlistPage from '../pages/AdminWaitlistPage';
6
+ import { SimpleLoadingSkeleton } from '../components/LoadingSkeletons';
7
+
8
+ export function meta() {
9
+ return [{ title: 'Admin - Waitlist' }];
10
+ }
11
+
12
+ export function links() {
13
+ return [];
14
+ }
15
+
16
+ export default function AdminWaitlistRoute() {
17
+ return (
18
+ <ChatProviders>
19
+ <AdminWaitlistPage />
20
+ </ChatProviders>
21
+ );
22
+ }
23
+
24
+ export { SimpleLoadingSkeleton as LoadingSkeleton };
@@ -10,7 +10,7 @@ export function meta() {
10
10
  }
11
11
 
12
12
  export function links() {
13
- return [{ rel: 'stylesheet', href: '/node_modules/@chaaskit/client/dist/lib/styles.css' }];
13
+ return [];
14
14
  }
15
15
 
16
16
  export default function ApiKeysRoute() {
@@ -10,7 +10,7 @@ export function meta() {
10
10
  }
11
11
 
12
12
  export function links() {
13
- return [{ rel: 'stylesheet', href: '/node_modules/@chaaskit/client/dist/lib/styles.css' }];
13
+ return [];
14
14
  }
15
15
 
16
16
  export default function AutomationsRoute() {
@@ -12,7 +12,8 @@ export function meta() {
12
12
  }
13
13
 
14
14
  export function links() {
15
- return [{ rel: 'stylesheet', href: '/node_modules/@chaaskit/client/dist/lib/styles.css' }];
15
+ // CSS is bundled via app's Tailwind preset - no separate stylesheet needed
16
+ return [];
16
17
  }
17
18
 
18
19
  export default function ChatRoute() {
@@ -10,7 +10,7 @@ export function meta() {
10
10
  }
11
11
 
12
12
  export function links() {
13
- return [{ rel: 'stylesheet', href: '/node_modules/@chaaskit/client/dist/lib/styles.css' }];
13
+ return [];
14
14
  }
15
15
 
16
16
  export default function DocumentsRoute() {
@@ -10,7 +10,7 @@ export function meta() {
10
10
  }
11
11
 
12
12
  export function links() {
13
- return [{ rel: 'stylesheet', href: '/node_modules/@chaaskit/client/dist/lib/styles.css' }];
13
+ return [];
14
14
  }
15
15
 
16
16
  export default function OAuthConsentRoute() {
@@ -10,7 +10,7 @@ export function meta() {
10
10
  }
11
11
 
12
12
  export function links() {
13
- return [{ rel: 'stylesheet', href: '/node_modules/@chaaskit/client/dist/lib/styles.css' }];
13
+ return [];
14
14
  }
15
15
 
16
16
  export default function PricingRoute() {
@@ -10,7 +10,7 @@ export function meta() {
10
10
  }
11
11
 
12
12
  export function links() {
13
- return [{ rel: 'stylesheet', href: '/node_modules/@chaaskit/client/dist/lib/styles.css' }];
13
+ return [];
14
14
  }
15
15
 
16
16
  export default function PrivacyRoute() {
@@ -10,7 +10,7 @@ export function meta() {
10
10
  }
11
11
 
12
12
  export function links() {
13
- return [{ rel: 'stylesheet', href: '/node_modules/@chaaskit/client/dist/lib/styles.css' }];
13
+ return [];
14
14
  }
15
15
 
16
16
  export default function TeamSettingsRoute() {
@@ -10,7 +10,7 @@ export function meta() {
10
10
  }
11
11
 
12
12
  export function links() {
13
- return [{ rel: 'stylesheet', href: '/node_modules/@chaaskit/client/dist/lib/styles.css' }];
13
+ return [];
14
14
  }
15
15
 
16
16
  export default function TermsRoute() {
@@ -10,7 +10,7 @@ export function meta() {
10
10
  }
11
11
 
12
12
  export function links() {
13
- return [{ rel: 'stylesheet', href: '/node_modules/@chaaskit/client/dist/lib/styles.css' }];
13
+ return [];
14
14
  }
15
15
 
16
16
  export default function VerifyEmailRoute() {
@@ -45,6 +45,8 @@ export { default as AdminDashboardRoute, meta as adminDashboardMeta, links as ad
45
45
  export { default as AdminUsersRoute, meta as adminUsersMeta, links as adminUsersLinks, LoadingSkeleton as AdminUsersLoadingSkeleton } from './AdminUsersRoute';
46
46
  export { default as AdminTeamsRoute, meta as adminTeamsMeta, links as adminTeamsLinks, LoadingSkeleton as AdminTeamsLoadingSkeleton } from './AdminTeamsRoute';
47
47
  export { default as AdminTeamRoute, meta as adminTeamMeta, links as adminTeamLinks, LoadingSkeleton as AdminTeamLoadingSkeleton } from './AdminTeamRoute';
48
+ export { default as AdminWaitlistRoute, meta as adminWaitlistMeta, links as adminWaitlistLinks, LoadingSkeleton as AdminWaitlistLoadingSkeleton } from './AdminWaitlistRoute';
49
+ export { default as AdminPromoCodesRoute, meta as adminPromoCodesMeta, links as adminPromoCodesLinks, LoadingSkeleton as AdminPromoCodesLoadingSkeleton } from './AdminPromoCodesRoute';
48
50
 
49
51
  // Auth-related routes
50
52
  export { default as VerifyEmailRoute, meta as verifyEmailMeta, links as verifyEmailLinks, LoadingSkeleton as VerifyEmailLoadingSkeleton } from './VerifyEmailRoute';