Skip to content

Commit f4908ff

Browse files
fix(ui): Add checkbox to accept terms and conditions (#295)
* fix(ui): Add checkbox for students to accept terms and conditions * test: Mark terms and conditions checkbox on tests
1 parent f4ca6cd commit f4908ff

File tree

8 files changed

+115
-3
lines changed

8 files changed

+115
-3
lines changed

e2e/courses/EnrollStudent.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ test.describe.serial("Enroll student workflow", () => {
5757
await page.getByLabel("Institutional ID").fill(studentInstitutionalID);
5858
await page.getByLabel("Email").fill(studentEmail);
5959
await page.getByLabel("Password").fill(studentPassword);
60+
await page.getByLabel("Accept terms and conditions").check();
6061
await page.getByRole("button", { name: "Submit" }).click();
6162
});
6263

e2e/courses/JoinCourse.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ test.describe.serial("Join courses workflow", () => {
142142
await page.getByLabel("Institutional ID").fill(studentInstitutionalID);
143143
await page.getByLabel("Email").fill(studentEmail);
144144
await page.getByLabel("Password").fill(studentPassword);
145-
145+
await page.getByLabel("Accept terms and conditions").check();
146146
await page.getByRole("button", { name: "Submit" }).click();
147147
await page.waitForURL(/\/login$/);
148148
});

e2e/grades/grades-workflow.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ test.describe.serial("Grades workflow", () => {
4949
await page.getByLabel("Institutional ID").fill(getRandomUniversityID());
5050
await page.getByLabel("Email").fill(studentEmail);
5151
await page.getByLabel("Password").fill(getDefaultPassword());
52+
await page.getByLabel("Accept terms and conditions").check();
5253
await page.getByRole("button", { name: "Submit" }).click();
5354
});
5455

e2e/register/RegisterStudents.spec.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ test("The fields are validated", async ({ page }) => {
2525
"Must contain at least one letter, one number and one special character"
2626
)
2727
).toBeVisible();
28+
await expect(
29+
page.getByText(
30+
"You can't register without accepting the terms and conditions"
31+
)
32+
).toBeVisible();
2833
});
2934

3035
test.describe.serial("Student registration", () => {
@@ -38,6 +43,7 @@ test.describe.serial("Student registration", () => {
3843
await page.getByLabel("Email").fill(newStudentEmail);
3944
await page.getByLabel("Institutional ID").fill(newStudentID);
4045
await page.getByLabel("Password").fill(getDefaultPassword());
46+
await page.getByLabel("Accept terms and conditions").check();
4147
await page.getByRole("button", { name: "Submit" }).click();
4248

4349
await expect(
@@ -53,6 +59,7 @@ test.describe.serial("Student registration", () => {
5359
await page.getByLabel("Email").fill(newStudentEmail);
5460
await page.getByLabel("Institutional ID").fill(getRandomUniversityID());
5561
await page.getByLabel("Password").fill(getDefaultPassword());
62+
await page.getByLabel("Accept terms and conditions").check();
5663
await page.getByRole("button", { name: "Submit" }).click();
5764

5865
await expect(
@@ -69,6 +76,7 @@ test.describe.serial("Student registration", () => {
6976
await page.getByLabel("Email").fill(getRandomEmail());
7077
await page.getByLabel("Institutional ID").fill(newStudentID);
7178
await page.getByLabel("Password").fill(getDefaultPassword());
79+
await page.getByLabel("Accept terms and conditions").check();
7280
await page.getByRole("button", { name: "Submit" }).click();
7381

7482
await expect(

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"dependencies": {
1919
"@hookform/resolvers": "3.3.4",
2020
"@radix-ui/react-alert-dialog": "1.0.5",
21+
"@radix-ui/react-checkbox": "^1.0.4",
2122
"@radix-ui/react-dialog": "1.0.5",
2223
"@radix-ui/react-dropdown-menu": "2.0.6",
2324
"@radix-ui/react-label": "2.0.2",

pnpm-lock.yaml

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/ui/checkbox.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { cn } from "@/lib/utils";
2+
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
3+
import { Check } from "lucide-react";
4+
import * as React from "react";
5+
6+
const Checkbox = React.forwardRef<
7+
React.ElementRef<typeof CheckboxPrimitive.Root>,
8+
React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
9+
>(({ className, ...props }, ref) => (
10+
<CheckboxPrimitive.Root
11+
ref={ref}
12+
className={cn(
13+
"peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
14+
className
15+
)}
16+
{...props}
17+
>
18+
<CheckboxPrimitive.Indicator
19+
className={cn("flex items-center justify-center text-current")}
20+
>
21+
<Check className="h-4 w-4" />
22+
</CheckboxPrimitive.Indicator>
23+
</CheckboxPrimitive.Root>
24+
));
25+
Checkbox.displayName = CheckboxPrimitive.Root.displayName;
26+
27+
export { Checkbox };

src/screens/session/register-student/Form.tsx

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Button } from "@/components/ui/button";
2+
import { Checkbox } from "@/components/ui/checkbox";
23
import {
34
Form,
45
FormControl,
@@ -30,7 +31,10 @@ const RegisterStudentSchema = z.object({
3031
.regex(
3132
/^(?=.*[A-Za-z])(?=.*\d)(?=.*[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?])[A-Za-z\d[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]{8,}$/,
3233
"Must contain at least one letter, one number and one special character"
33-
)
34+
),
35+
accept_terms: z.boolean().refine((value) => !!value, {
36+
message: "You can't register without accepting the terms and conditions"
37+
})
3438
});
3539

3640
export const RegisterStudentForm = () => {
@@ -43,7 +47,8 @@ export const RegisterStudentForm = () => {
4347
full_name: "",
4448
email: "",
4549
institutional_id: "",
46-
password: ""
50+
password: "",
51+
accept_terms: false
4752
}
4853
});
4954

@@ -144,6 +149,44 @@ export const RegisterStudentForm = () => {
144149
</FormItem>
145150
)}
146151
></FormField>
152+
<FormField
153+
control={form.control}
154+
name="accept_terms"
155+
render={({ field }) => (
156+
<FormItem>
157+
<div className="items-top flex space-x-2">
158+
<FormControl>
159+
<Checkbox
160+
id="terms1"
161+
checked={field.value}
162+
onCheckedChange={() => field.onChange(!field.value)}
163+
/>
164+
</FormControl>
165+
<div className="grid space-y-1.5">
166+
<FormLabel htmlFor="terms1">
167+
Accept terms and conditions
168+
</FormLabel>
169+
<p className="text-sm text-muted-foreground">
170+
By checking this box, you agree to{" "}
171+
<a
172+
href="/POLITICA_TRATAMIENTO_INFORMACION_PROTECCION_DATOS_PERSONALES.pdf"
173+
target="_blank"
174+
rel="noreferrer,noopener"
175+
className="text-red-upb underline"
176+
>
177+
our terms and conditions.
178+
</a>
179+
</p>
180+
</div>
181+
</div>
182+
{form.formState.errors.accept_terms && (
183+
<FormMessage>
184+
{form.formState.errors.accept_terms.message}
185+
</FormMessage>
186+
)}
187+
</FormItem>
188+
)}
189+
></FormField>
147190
<Button
148191
type="submit"
149192
className="w-full"

0 commit comments

Comments
 (0)