@messenger-box/slack-ui-browser 10.0.3-alpha.176

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 (61) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/LICENSE +21 -0
  3. package/lib/components/Home/Channels.js +62 -0
  4. package/lib/components/Home/Channels.js.map +1 -0
  5. package/lib/components/Home/DirectChannels.js +92 -0
  6. package/lib/components/Home/DirectChannels.js.map +1 -0
  7. package/lib/components/Home/InviteMembers.js +70 -0
  8. package/lib/components/Home/InviteMembers.js.map +1 -0
  9. package/lib/components/Home/Teams.js +62 -0
  10. package/lib/components/Home/Teams.js.map +1 -0
  11. package/lib/components/Home/TopCommonSlider.js +35 -0
  12. package/lib/components/Home/TopCommonSlider.js.map +1 -0
  13. package/lib/compute.js +223 -0
  14. package/lib/compute.js.map +1 -0
  15. package/lib/constants/routes.js +63 -0
  16. package/lib/constants/routes.js.map +1 -0
  17. package/lib/hooks/useOptimizedChannelsQueries.js +107 -0
  18. package/lib/hooks/useOptimizedChannelsQueries.js.map +1 -0
  19. package/lib/hooks/useRouteState.js +193 -0
  20. package/lib/hooks/useRouteState.js.map +1 -0
  21. package/lib/index.js +1 -0
  22. package/lib/index.js.map +1 -0
  23. package/lib/machines/routeMachine.js +804 -0
  24. package/lib/machines/routeMachine.js.map +1 -0
  25. package/lib/module.js +3 -0
  26. package/lib/module.js.map +1 -0
  27. package/lib/queries/slackuiQueries.js +144 -0
  28. package/lib/queries/slackuiQueries.js.map +1 -0
  29. package/lib/routes.json +260 -0
  30. package/lib/screens/Home/HomeScreen.js +664 -0
  31. package/lib/screens/Home/HomeScreen.js.map +1 -0
  32. package/lib/screens/Home/index.js +1 -0
  33. package/lib/screens/Home/index.js.map +1 -0
  34. package/package.json +52 -0
  35. package/rollup.config.mjs +41 -0
  36. package/src/components/Home/Channels.tsx +135 -0
  37. package/src/components/Home/DirectChannels.tsx +185 -0
  38. package/src/components/Home/InviteMembers.tsx +134 -0
  39. package/src/components/Home/Teams.tsx +129 -0
  40. package/src/components/Home/TopCommonSlider.tsx +70 -0
  41. package/src/components/Home/index.ts +5 -0
  42. package/src/components/index.ts +1 -0
  43. package/src/compute.ts +156 -0
  44. package/src/constants/index.ts +1 -0
  45. package/src/constants/routes.ts +92 -0
  46. package/src/hooks/index.ts +3 -0
  47. package/src/hooks/useOptimizedChannelsQueries.ts +165 -0
  48. package/src/hooks/useRouteState.ts +253 -0
  49. package/src/icons.ts +137 -0
  50. package/src/index.ts +11 -0
  51. package/src/machines/index.ts +9 -0
  52. package/src/machines/routeMachine.ts +682 -0
  53. package/src/module.tsx +6 -0
  54. package/src/queries/index.ts +1 -0
  55. package/src/queries/slackuiQueries.ts +227 -0
  56. package/src/screens/Home/HomeScreen.tsx +1308 -0
  57. package/src/screens/Home/index.ts +4 -0
  58. package/src/screens/NewChannel/NewChannelScreen.tsx +188 -0
  59. package/src/screens/NewChannel/index.ts +2 -0
  60. package/src/screens/index.ts +1 -0
  61. package/tsconfig.json +21 -0
@@ -0,0 +1,4 @@
1
+ export { default as HomeScreen } from './HomeScreen';
2
+ export { RefetchContext, ChannelsDataContext } from './HomeScreen';
3
+
4
+ export { default } from './HomeScreen';
@@ -0,0 +1,188 @@
1
+ import React, { useState, useCallback } from 'react';
2
+ import { useNavigate, useLocation } from '@remix-run/react';
3
+ import { FiX, FiHash, FiLock } from '../../icons';
4
+ import { slackUiRoutePaths } from '../../constants/routes';
5
+
6
+ interface NewChannelScreenProps {
7
+ onClose?: () => void;
8
+ }
9
+
10
+ const NewChannelScreen: React.FC<NewChannelScreenProps> = ({ onClose }) => {
11
+ const navigate = useNavigate();
12
+ const location = useLocation();
13
+ const orgSlug = location.pathname.split('/')[2];
14
+
15
+ const [channelName, setChannelName] = useState('');
16
+ const [description, setDescription] = useState('');
17
+ const [isPrivate, setIsPrivate] = useState(false);
18
+ const [isLoading, setIsLoading] = useState(false);
19
+ const [error, setError] = useState<string | null>(null);
20
+
21
+ const handleClose = useCallback(() => {
22
+ if (onClose) {
23
+ onClose();
24
+ } else {
25
+ navigate(slackUiRoutePaths.home(orgSlug));
26
+ }
27
+ }, [navigate, orgSlug, onClose]);
28
+
29
+ const handleSubmit = useCallback(async (e: React.FormEvent) => {
30
+ e.preventDefault();
31
+
32
+ if (!channelName.trim()) {
33
+ setError('Channel name is required');
34
+ return;
35
+ }
36
+
37
+ // Validate channel name format (lowercase, no spaces, alphanumeric with hyphens)
38
+ const validName = channelName.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, '');
39
+ if (validName !== channelName) {
40
+ setChannelName(validName);
41
+ }
42
+
43
+ setIsLoading(true);
44
+ setError(null);
45
+
46
+ try {
47
+ // TODO: Implement actual channel creation mutation
48
+ console.log('Creating channel:', { name: channelName, description, isPrivate });
49
+
50
+ // Navigate to the new channel after creation
51
+ // For now, just go back to home
52
+ handleClose();
53
+ } catch (err) {
54
+ setError('Failed to create channel. Please try again.');
55
+ } finally {
56
+ setIsLoading(false);
57
+ }
58
+ }, [channelName, description, isPrivate, handleClose]);
59
+
60
+ const handleChannelNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
61
+ // Auto-format: lowercase, replace spaces with hyphens
62
+ const value = e.target.value.toLowerCase().replace(/\s+/g, '-');
63
+ setChannelName(value);
64
+ setError(null);
65
+ };
66
+
67
+ return (
68
+ <div className="flex flex-col h-full bg-white">
69
+ {/* Header */}
70
+ <div className="flex items-center justify-between px-4 py-3 border-b border-gray-200">
71
+ <button
72
+ onClick={handleClose}
73
+ className="p-2 hover:bg-gray-100 rounded-full transition-colors"
74
+ >
75
+ <FiX className="w-5 h-5 text-gray-600" />
76
+ </button>
77
+ <h1 className="text-lg font-semibold text-gray-900">Create Channel</h1>
78
+ <button
79
+ onClick={handleSubmit}
80
+ disabled={isLoading || !channelName.trim()}
81
+ className="px-4 py-2 bg-blue-600 text-white rounded-md text-sm font-medium hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
82
+ >
83
+ {isLoading ? 'Creating...' : 'Create'}
84
+ </button>
85
+ </div>
86
+
87
+ {/* Form */}
88
+ <form onSubmit={handleSubmit} className="flex-1 overflow-y-auto p-4 space-y-6">
89
+ {/* Channel Type Toggle */}
90
+ <div className="space-y-2">
91
+ <label className="block text-sm font-medium text-gray-700">Channel Type</label>
92
+ <div className="flex gap-4">
93
+ <button
94
+ type="button"
95
+ onClick={() => setIsPrivate(false)}
96
+ className={`flex items-center gap-2 px-4 py-3 rounded-lg border-2 transition-colors ${
97
+ !isPrivate
98
+ ? 'border-blue-500 bg-blue-50 text-blue-700'
99
+ : 'border-gray-200 bg-white text-gray-700 hover:border-gray-300'
100
+ }`}
101
+ >
102
+ <FiHash className="w-5 h-5" />
103
+ <div className="text-left">
104
+ <div className="font-medium">Public</div>
105
+ <div className="text-xs text-gray-500">Anyone can join</div>
106
+ </div>
107
+ </button>
108
+ <button
109
+ type="button"
110
+ onClick={() => setIsPrivate(true)}
111
+ className={`flex items-center gap-2 px-4 py-3 rounded-lg border-2 transition-colors ${
112
+ isPrivate
113
+ ? 'border-blue-500 bg-blue-50 text-blue-700'
114
+ : 'border-gray-200 bg-white text-gray-700 hover:border-gray-300'
115
+ }`}
116
+ >
117
+ <FiLock className="w-5 h-5" />
118
+ <div className="text-left">
119
+ <div className="font-medium">Private</div>
120
+ <div className="text-xs text-gray-500">Invite only</div>
121
+ </div>
122
+ </button>
123
+ </div>
124
+ </div>
125
+
126
+ {/* Channel Name */}
127
+ <div className="space-y-2">
128
+ <label htmlFor="channelName" className="block text-sm font-medium text-gray-700">
129
+ Channel Name
130
+ </label>
131
+ <div className="relative">
132
+ <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
133
+ {isPrivate ? (
134
+ <FiLock className="w-5 h-5 text-gray-400" />
135
+ ) : (
136
+ <FiHash className="w-5 h-5 text-gray-400" />
137
+ )}
138
+ </div>
139
+ <input
140
+ id="channelName"
141
+ type="text"
142
+ value={channelName}
143
+ onChange={handleChannelNameChange}
144
+ placeholder="e.g. marketing, engineering"
145
+ className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
146
+ maxLength={80}
147
+ />
148
+ </div>
149
+ <p className="text-xs text-gray-500">
150
+ Lowercase letters, numbers, and hyphens only. Max 80 characters.
151
+ </p>
152
+ {error && <p className="text-xs text-red-500">{error}</p>}
153
+ </div>
154
+
155
+ {/* Description */}
156
+ <div className="space-y-2">
157
+ <label htmlFor="description" className="block text-sm font-medium text-gray-700">
158
+ Description <span className="text-gray-400">(optional)</span>
159
+ </label>
160
+ <textarea
161
+ id="description"
162
+ value={description}
163
+ onChange={(e) => setDescription(e.target.value)}
164
+ placeholder="What's this channel about?"
165
+ rows={3}
166
+ className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors resize-none"
167
+ maxLength={250}
168
+ />
169
+ <p className="text-xs text-gray-500">
170
+ {description.length}/250 characters
171
+ </p>
172
+ </div>
173
+
174
+ {/* Info */}
175
+ <div className="bg-gray-50 rounded-lg p-4">
176
+ <h3 className="text-sm font-medium text-gray-700 mb-2">What happens next?</h3>
177
+ <ul className="text-sm text-gray-600 space-y-1">
178
+ <li>• You'll be added as the channel admin</li>
179
+ <li>• You can invite members after creating the channel</li>
180
+ {isPrivate && <li>• Only invited members can see and join this channel</li>}
181
+ </ul>
182
+ </div>
183
+ </form>
184
+ </div>
185
+ );
186
+ };
187
+
188
+ export default React.memo(NewChannelScreen);
@@ -0,0 +1,2 @@
1
+ export { default } from './NewChannelScreen';
2
+ export { default as NewChannelScreen } from './NewChannelScreen';
@@ -0,0 +1 @@
1
+ export * from './Home';
package/tsconfig.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "extends": "../../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "rootDir": "src",
5
+ "outDir": "lib",
6
+ "declaration": true,
7
+ "declarationDir": "lib",
8
+ "types": ["@types/node", "@types/jest", "../../../typings"],
9
+ "skipLibCheck": true,
10
+ "jsx": "react-jsx"
11
+ },
12
+ "include": ["src"],
13
+ "exclude": [
14
+ "**/*.test.ts",
15
+ "../../../node_modules",
16
+ "node_modules",
17
+ "lib",
18
+ "webpack.config.js",
19
+ "rollup.config.mjs"
20
+ ]
21
+ }