Skip to content

Commit

Permalink
Merge pull request #69 from imperial/feat-add-gdpr
Browse files Browse the repository at this point in the history
feat: TOS for students
  • Loading branch information
nick-bolas authored Aug 23, 2024
2 parents 3d1e5ce + a8ced6a commit c46ef6f
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 4 deletions.
44 changes: 44 additions & 0 deletions components/DialogTOS.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"use client"

import MdViewer from "./MdViewer"

import { Button, Dialog, Flex, Text } from "@radix-ui/themes"
import React, { useEffect, useState } from "react"

const DialogTOS = ({ accept }: { accept: () => void }) => {
const [openState, setOpenState] = useState(false)
const [tosText, setTosText] = useState<string>()

useEffect(() => {
fetch("/tos.txt")
.then(res => res.text())
.then(text => setTosText(text))
.catch(e => console.error(e))
}, [])

return (
<Dialog.Root open={openState} onOpenChange={setOpenState} defaultOpen={false}>
<Dialog.Trigger>
<Button type="button">Save</Button>
</Dialog.Trigger>
<Dialog.Content style={{ minWidth: "60vw" }}>
<Dialog.Title>Terms & Conditions</Dialog.Title>
{typeof tosText !== "undefined" && <MdViewer markdown={tosText} tos />}
<Flex justify="end" gap="3" pt="3">
<Dialog.Close>
<Button variant="soft" color="gray">
Cancel
</Button>
</Dialog.Close>
<Dialog.Close>
<Button onClick={accept} disabled={typeof tosText === "undefined"}>
Accept
</Button>
</Dialog.Close>
</Flex>
</Dialog.Content>
</Dialog.Root>
)
}

export default DialogTOS
9 changes: 7 additions & 2 deletions components/EditStudent.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
"use client"

import { DangerZone } from "@/components/DeleteStudent"
import DialogTOS from "@/components/DialogTOS"
import { updateStudent } from "@/lib/crud/students"
import { ServerSideFormHandler } from "@/lib/types"
import { FormPassBackState, ServerSideFormHandler } from "@/lib/types"

import Chip from "./Chip"
import FileInput from "./FileInput"
Expand Down Expand Up @@ -30,6 +31,7 @@ const EditStudentForm = ({ close, prevStudentProfile }: { close: () => void; pre
updateStudent(prevState, formData, prevStudentProfile.userId)

const [bio, setBio] = useState(prevStudentProfile.bio ?? "")
const [acceptedTOS, setAcceptedTOS] = useState(prevStudentProfile.acceptedTOS)
const mdxEditorRef = useRef<MDXEditorMethods>(null)

const [skill, setSkill] = useState("")
Expand All @@ -38,6 +40,8 @@ const EditStudentForm = ({ close, prevStudentProfile }: { close: () => void; pre
const [interest, setInterest] = useState("")
const [interests, setInterests] = useState(prevStudentProfile.interests)

const TosDialogButton = () => <DialogTOS accept={() => setAcceptedTOS(true)} />

const addSkill = () => {
if (skills.includes(skill.trim())) return

Expand All @@ -58,7 +62,7 @@ const EditStudentForm = ({ close, prevStudentProfile }: { close: () => void; pre

return (
<>
<FormInModal action={updateStudentWithID} close={close}>
<FormInModal action={updateStudentWithID} close={close} submitButton={!acceptedTOS ? TosDialogButton : undefined}>
<label>
<Text as="div" size="2" mb="1" weight="bold">
Course
Expand Down Expand Up @@ -242,6 +246,7 @@ const EditStudentForm = ({ close, prevStudentProfile }: { close: () => void; pre
type="url"
/>
</label>
<input type="checkbox" name="acceptedTOS" checked={acceptedTOS} style={{ visibility: "hidden" }} readOnly />
</FormInModal>
<DangerZone id={prevStudentProfile.userId} />
</>
Expand Down
8 changes: 6 additions & 2 deletions components/MdViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@ import rehypeRaw from "rehype-raw"
import remarkBreaks from "remark-breaks"
import remarkGfm from "remark-gfm"

const MdViewer = ({ markdown }: { markdown: string }) => {
const MdViewer = ({ markdown, tos = false }: { markdown: string; tos?: boolean }) => {
return (
<Markdown className={styles.markdownViewer} remarkPlugins={[remarkGfm, remarkBreaks]} rehypePlugins={[rehypeRaw]}>
<Markdown
className={tos ? styles.tosViewer : styles.markdownViewer}
remarkPlugins={[remarkGfm, remarkBreaks]}
rehypePlugins={[rehypeRaw]}
>
{markdown}
</Markdown>
)
Expand Down
5 changes: 5 additions & 0 deletions components/md-viewer.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,8 @@
background-color: var(--gray-4);
}
}

.tosViewer {
list-style-position: inside;
line-height: 2em;
}
6 changes: 6 additions & 0 deletions lib/crud/students.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const updateStudent = studentOnlyAction(
const website = formData.get("website")?.toString().trim()
const github = formData.get("github")?.toString().trim()
const linkedIn = formData.get("linkedIn")?.toString().trim()
const acceptedTOS = !!formData.get("acceptedTOS")

try {
if (skills) {
Expand All @@ -57,6 +58,10 @@ export const updateStudent = studentOnlyAction(
return { message: "Invalid graduation date", status: "error" }
}

if (!acceptedTOS) {
return { message: "Please accept Terms & Conditions before proceeding.", status: "error" }
}

// Now update the student in the database
try {
await prisma.studentProfile.update({
Expand All @@ -71,6 +76,7 @@ export const updateStudent = studentOnlyAction(
personalWebsite: website,
skills,
interests,
acceptedTOS,
},
})
} catch (e: any) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "StudentProfile" ADD COLUMN "acceptedTOS" BOOLEAN NOT NULL DEFAULT false;
1 change: 1 addition & 0 deletions prisma/schema/studentProfile.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ model StudentProfile {
graduationDate DateTime?
lookingFor OpportunityType?
cv String?
acceptedTOS Boolean @default(false)
skills String[] @default([])
interests String[] @default([])
updatedAt DateTime @updatedAt
Expand Down
90 changes: 90 additions & 0 deletions public/tos.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# *THIS IS A TEMPLATE*

## 1. Introduction
Welcome to Imperial's Corporate Parternship Program Connect (the "Website"). These Terms of Service (the "Terms") govern your use of our website, including any content, functionality, and services offered on or through the Website.

By accessing or using the Website, you agree to comply with and be bound by these Terms. If you do not agree to these Terms, please do not use the Website.
<br>

## 2. Data Protection and Privacy

### 2.1 Personal Data

By using our Website, you may be required to upload, submit, or share personal data. This data may include, but is not limited to, your name, email address, phone number, and any other information you choose to provide ("Personal Data").
<br>

### 2.2 GDPR Compliance

We are committed to ensuring that your Personal Data is protected and processed in compliance with the General Data Protection Regulation (GDPR). For more information on how we handle your data, please refer to our Privacy Policy.
<br>

### 2.3 Data Controller

Imperial College London is the data controller responsible for your Personal Data. We are registered in the United Kingdom, with our registered office at Exhibition Rd, South Kensington, London SW7 2AZ.
<br>

## 3. User Responsibilities

### 3.1 Accuracy of Information

You are responsible for ensuring that the Personal Data you upload is accurate, complete, and up-to-date. We are not responsible for any issues arising from incorrect or outdated information provided by you.
<br>

### 3.2 Lawful Use

You agree to use the Website and upload Personal Data only in a lawful manner. You are prohibited from uploading any data that:

- Violates any applicable laws or regulations.
- Infringes on the rights of others, including intellectual property rights.
- Contains harmful, defamatory, or inappropriate content.

<br>

### 3.3 Data Subject Rights

As a data subject under GDPR, you have the following rights:

- **Right to Access**: You can request access to the Personal Data we hold about you.
- **Right to Rectification**: You can request correction of any inaccuracies in your Personal Data.
- **Right to Erasure**: You can request the deletion of your Personal Data under certain conditions.
- **Right to Restrict Processing**: You can request that we limit the processing of your Personal Data under certain conditions.
- **Right to Data Portability**: You can request that we transfer your data to another organization, or directly to you, in a structured, commonly used, and machine-readable format.
- **Right to Object**: You can object to the processing of your Personal Data under certain conditions.

To exercise any of these rights, please contact us at [email protected].
<br>

## 4. Data Security

We have implemented appropriate technical and organizational measures to protect your Personal Data from unauthorized access, use, disclosure, alteration, or destruction.

However, please be aware that no method of transmission over the Internet, or method of electronic storage, is 100% secure. While we strive to protect your Personal Data, we cannot guarantee its absolute security.
<br>

## 5. Data Retention

We will retain your Personal Data only for as long as is necessary for the purposes set out in these Terms or as required by law. Once your data is no longer needed, it will be securely deleted or anonymized.
<br>

## 6. Third-Party Services

Our Website may include links to or use third-party services, which may collect and process Personal Data independently. We are not responsible for the practices or policies of these third parties. Please review their respective privacy policies before using their services.
<br>

## 7. Changes to These Terms

We may update these Terms from time to time. Any changes will be effective immediately upon posting to the Website. Your continued use of the Website after such changes constitutes your acceptance of the revised Terms.
<br>

## 8. Contact Information

If you have any questions or concerns about these Terms or our data protection practices, please contact us at:
<br>

**Email**: [email protected]
**Address**: Exhibition Rd, South Kensington, London SW7 2AZ
**Phone**: 020 7589 5111

<hr>

Last updated: 23/8/2024

0 comments on commit c46ef6f

Please sign in to comment.