@nualang/nualang-ui-components 0.1.1419 → 0.1.1421

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.
@@ -1,137 +1,238 @@
1
- import { Typography, Box, Link, List, ListItem, ListItemText, Divider, IconButton } from "@mui/material";
2
- import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
3
- import ChevronRightIcon from "@mui/icons-material/ChevronRight";
1
+ import { useState } from "react";
2
+ import { Typography, Box, Button, IconButton } from "@mui/material";
3
+ import CloseIcon from "@mui/icons-material/Close";
4
+ import LinkIcon from "@mui/icons-material/Link";
4
5
  import SwipeableDrawer from "@mui/material/SwipeableDrawer";
5
- import { useTheme } from "@mui/material/styles";
6
6
  import { QRCode } from "react-qrcode-logo";
7
7
  import nualangImage from "../../img/nualangSquareIcon.svg";
8
+ import { selectedRowBg } from "../../Lists/RoleplaySelection/RoleplaySelection";
8
9
 
9
- // Sentinel handed to i18next as the interpolation value so we can split the
10
- // translated sentence and drop a React node in the placeholder's position.
11
- // Splitting on the real value would break when it is empty or repeated, and
12
- // splitting on the raw "{{name}}" token would not work because i18next has
13
- // already substituted it.
10
+ // The QR stays on a fixed white card with brand-purple modules in both themes
11
+ // so it always scans reliably.
14
12
  import { Fragment as _Fragment, jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
15
- const PLACEHOLDER = "\u0000";
16
- function withNode(sentence, node) {
17
- const [before, after = ""] = sentence.split(PLACEHOLDER);
13
+ const QR_FG = "#8300A1";
14
+ const QR_BG = "#fff";
15
+
16
+ // Split the translated sentence on the raw `{{button}}` placeholder (before
17
+ // i18next interpolates it) so we can drop a React node in the button's position.
18
+ // If a locale omits the placeholder, `node` is simply appended after the text.
19
+ function withButton(sentence, node) {
20
+ const [before, after = ""] = (sentence || "").split("{{button}}");
18
21
  return /*#__PURE__*/_jsxs(_Fragment, {
19
22
  children: [before, node, after]
20
23
  });
21
24
  }
22
25
  export default function HowToJoin({
23
26
  t,
24
- classroomName,
25
27
  classroomURL,
26
28
  isOpen,
27
29
  handleClose
28
30
  }) {
29
- const theme = useTheme();
30
- return /*#__PURE__*/_jsxs(SwipeableDrawer, {
31
+ const [copied, setCopied] = useState(false);
32
+ const handleCopy = async () => {
33
+ try {
34
+ await navigator.clipboard.writeText(classroomURL);
35
+ setCopied(true);
36
+ setTimeout(() => setCopied(false), 2000);
37
+ } catch {
38
+ // clipboard unavailable — no-op
39
+ }
40
+ };
41
+ const displayUrl = (classroomURL || "").replace(/^https?:\/\//, "");
42
+ const steps = [t("invite_step_sign_in"), t("invite_step_scan"), withButton(t("invite_step_tap_join", {
43
+ button: "{{button}}"
44
+ }), /*#__PURE__*/_jsx("b", {
45
+ children: t("join_live_game")
46
+ }))];
47
+ const sectionLabelSx = {
48
+ fontSize: 14,
49
+ fontWeight: 700,
50
+ color: "text.secondary"
51
+ };
52
+ return /*#__PURE__*/_jsx(SwipeableDrawer, {
31
53
  open: isOpen,
32
54
  anchor: "right",
33
55
  onClose: handleClose,
56
+ onOpen: () => {},
34
57
  sx: {
35
- zIndex: "3000"
58
+ zIndex: 3000
36
59
  },
37
- children: [/*#__PURE__*/_jsxs(Box, {
60
+ children: /*#__PURE__*/_jsxs(Box, {
38
61
  sx: {
39
- p: 5,
40
- maxWidth: "700px"
62
+ width: 520,
63
+ maxWidth: "100vw",
64
+ height: "100%",
65
+ display: "flex",
66
+ flexDirection: "column",
67
+ backgroundColor: "background.paper"
41
68
  },
42
- children: [/*#__PURE__*/_jsx(Typography, {
43
- variant: "h5",
44
- component: "h1",
45
- gutterBottom: true,
46
- children: t("how_to_join_title")
47
- }), /*#__PURE__*/_jsx(Typography, {
48
- variant: "body1",
49
- gutterBottom: true,
50
- children: t("how_to_join_intro")
51
- }), /*#__PURE__*/_jsxs(List, {
69
+ children: [/*#__PURE__*/_jsxs(Box, {
52
70
  sx: {
53
- listStyleType: "decimal",
54
- pl: 2,
55
- "& .MuiListItem-root": {
56
- display: "list-item"
57
- }
71
+ p: "24px 24px 16px",
72
+ display: "flex",
73
+ alignItems: "flex-start",
74
+ justifyContent: "space-between",
75
+ gap: 2
58
76
  },
59
- children: [/*#__PURE__*/_jsx(ListItem, {
60
- children: /*#__PURE__*/_jsx(ListItemText, {
61
- primary: /*#__PURE__*/_jsx(Typography, {
62
- component: "span",
63
- variant: "body1",
64
- children: t("how_to_join_sign_in")
65
- })
66
- })
67
- }), /*#__PURE__*/_jsx(ListItem, {
68
- children: /*#__PURE__*/_jsx(ListItemText, {
69
- primary: /*#__PURE__*/_jsx(Typography, {
70
- component: "span",
71
- variant: "body1",
72
- children: withNode(t("how_to_join_open_classroom", {
73
- classroom: PLACEHOLDER
74
- }), /*#__PURE__*/_jsx(Link, {
75
- href: classroomURL,
76
- target: "_blank",
77
- rel: "noreferrer",
78
- children: classroomName
79
- }))
80
- })
81
- })
82
- }), /*#__PURE__*/_jsx(Box, {
77
+ children: [/*#__PURE__*/_jsx(Box, {
83
78
  sx: {
84
- pl: 2.5,
85
- py: 5
79
+ display: "flex",
80
+ flexDirection: "column",
81
+ gap: 0.5
86
82
  },
87
- children: /*#__PURE__*/_jsx(QRCode, {
88
- value: classroomURL,
89
- size: 256,
90
- fgColor: theme.palette.primary.main,
91
- bgColor: theme.palette.background.paper,
92
- logoImage: nualangImage,
93
- logoHeight: 70,
94
- logoWidth: 70,
95
- qrStyle: "dots"
83
+ children: /*#__PURE__*/_jsx(Typography, {
84
+ sx: {
85
+ fontSize: 24,
86
+ fontWeight: 700,
87
+ lineHeight: 1.3,
88
+ color: "text.primary"
89
+ },
90
+ children: t("how_to_join_title")
96
91
  })
97
- }), /*#__PURE__*/_jsx(ListItem, {
98
- children: /*#__PURE__*/_jsx(ListItemText, {
99
- primary: /*#__PURE__*/_jsx(Typography, {
100
- component: "span",
101
- variant: "body1",
102
- children: withNode(t("how_to_join_find_button", {
103
- button: PLACEHOLDER
104
- }), /*#__PURE__*/_jsx("b", {
105
- children: t("join_live_game")
106
- }))
107
- })
92
+ }), /*#__PURE__*/_jsx(IconButton, {
93
+ onClick: handleClose,
94
+ "aria-label": t("close"),
95
+ size: "small",
96
+ children: /*#__PURE__*/_jsx(CloseIcon, {
97
+ sx: {
98
+ fontSize: 24,
99
+ color: "text.secondary"
100
+ }
108
101
  })
109
- }), /*#__PURE__*/_jsx(ListItem, {
110
- children: /*#__PURE__*/_jsx(ListItemText, {
111
- primary: /*#__PURE__*/_jsx(Typography, {
112
- component: "span",
113
- variant: "body1",
114
- children: t("how_to_join_get_ready")
102
+ })]
103
+ }), /*#__PURE__*/_jsxs(Box, {
104
+ sx: {
105
+ flex: 1,
106
+ p: "0 24px 24px",
107
+ display: "flex",
108
+ flexDirection: "column",
109
+ gap: 3,
110
+ overflow: "auto"
111
+ },
112
+ children: [/*#__PURE__*/_jsx(Box, {
113
+ sx: {
114
+ display: "flex",
115
+ flexDirection: "column",
116
+ alignItems: "center"
117
+ },
118
+ children: /*#__PURE__*/_jsx(Box, {
119
+ sx: {
120
+ backgroundColor: QR_BG,
121
+ border: "1px solid",
122
+ borderColor: "divider",
123
+ borderRadius: "12px",
124
+ p: 2,
125
+ display: "flex"
126
+ },
127
+ children: /*#__PURE__*/_jsx(QRCode, {
128
+ value: classroomURL,
129
+ size: 200,
130
+ fgColor: QR_FG,
131
+ bgColor: QR_BG,
132
+ logoImage: nualangImage,
133
+ logoHeight: 56,
134
+ logoWidth: 56,
135
+ qrStyle: "squares"
115
136
  })
116
137
  })
138
+ }), /*#__PURE__*/_jsxs(Box, {
139
+ sx: {
140
+ display: "flex",
141
+ flexDirection: "column",
142
+ gap: 1
143
+ },
144
+ children: [/*#__PURE__*/_jsx(Typography, {
145
+ sx: sectionLabelSx,
146
+ children: t("classroom_link")
147
+ }), /*#__PURE__*/_jsxs(Box, {
148
+ sx: {
149
+ display: "flex",
150
+ alignItems: "center",
151
+ gap: 1,
152
+ border: "1px solid",
153
+ borderColor: "divider",
154
+ borderRadius: "8px",
155
+ px: 1.5,
156
+ py: 1
157
+ },
158
+ children: [/*#__PURE__*/_jsx(LinkIcon, {
159
+ sx: {
160
+ fontSize: 20,
161
+ color: "text.secondary",
162
+ flex: "none"
163
+ }
164
+ }), /*#__PURE__*/_jsx(Typography, {
165
+ noWrap: true,
166
+ sx: {
167
+ flex: 1,
168
+ minWidth: 0,
169
+ fontSize: 14,
170
+ color: "text.primary"
171
+ },
172
+ children: displayUrl
173
+ }), /*#__PURE__*/_jsx(Button, {
174
+ onClick: handleCopy,
175
+ color: "primary",
176
+ sx: {
177
+ fontWeight: 600,
178
+ flex: "none"
179
+ },
180
+ children: copied ? t("copied") : t("copy")
181
+ })]
182
+ })]
183
+ }), /*#__PURE__*/_jsxs(Box, {
184
+ sx: {
185
+ display: "flex",
186
+ flexDirection: "column",
187
+ gap: 1
188
+ },
189
+ children: [/*#__PURE__*/_jsx(Typography, {
190
+ sx: sectionLabelSx,
191
+ children: t("tell_students_to")
192
+ }), /*#__PURE__*/_jsx(Box, {
193
+ sx: {
194
+ border: "1px solid",
195
+ borderColor: "divider",
196
+ borderRadius: "16px",
197
+ overflow: "hidden"
198
+ },
199
+ children: steps.map((step, i) => /*#__PURE__*/_jsxs(Box, {
200
+ sx: {
201
+ display: "flex",
202
+ alignItems: "center",
203
+ gap: 2,
204
+ p: 2,
205
+ ...(i > 0 ? {
206
+ borderTop: "1px solid",
207
+ borderColor: "divider"
208
+ } : {})
209
+ },
210
+ children: [/*#__PURE__*/_jsx(Box, {
211
+ sx: {
212
+ flex: "none",
213
+ width: 28,
214
+ height: 28,
215
+ borderRadius: "50%",
216
+ backgroundColor: selectedRowBg,
217
+ color: "primary.main",
218
+ display: "flex",
219
+ alignItems: "center",
220
+ justifyContent: "center",
221
+ fontSize: 14,
222
+ fontWeight: 700
223
+ },
224
+ children: i + 1
225
+ }), /*#__PURE__*/_jsx(Typography, {
226
+ sx: {
227
+ fontSize: 16,
228
+ color: "text.primary"
229
+ },
230
+ children: step
231
+ })]
232
+ }, i))
233
+ })]
117
234
  })]
118
235
  })]
119
- }), /*#__PURE__*/_jsx(Box, {
120
- sx: {
121
- flexGrow: 1
122
- }
123
- }), /*#__PURE__*/_jsx(Divider, {}), /*#__PURE__*/_jsx(Box, {
124
- sx: theme => ({
125
- display: "flex",
126
- alignItems: "center",
127
- justifyContent: "flex-start",
128
- padding: "0 8px",
129
- ...theme.mixins.toolbar
130
- }),
131
- children: /*#__PURE__*/_jsx(IconButton, {
132
- onClick: handleClose,
133
- children: theme.direction === "ltr" ? /*#__PURE__*/_jsx(ChevronRightIcon, {}) : /*#__PURE__*/_jsx(ChevronLeftIcon, {})
134
- })
135
- })]
236
+ })
136
237
  });
137
238
  }