-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* quick save * quick save * quick save * fixes * fix: simplify * fix: refetchOnMountOrArgChange * new cfl package * reuse create class form * fix: print credentials pdf notification * fix: button styles * unique names * fix: install new cfl package * feedback * small fix
- Loading branch information
Showing
21 changed files
with
1,581 additions
and
1,193 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
import * as pdf from "@react-pdf/renderer" | ||
import { Button, type ButtonProps } from "@mui/material" | ||
import { type FC, useRef } from "react" | ||
import { type Student, type User } from "codeforlife/api" | ||
import { Print as PrintIcon } from "@mui/icons-material" | ||
import { generatePath } from "react-router-dom" | ||
|
||
import CflLogoImage from "../images/logo_cfl.png" | ||
import { makeAutoLoginLink } from "../utils/student" | ||
import { paths } from "../routes" | ||
|
||
interface PDFProps { | ||
classId: string | ||
students: Array< | ||
Pick<Student, "id" | "auto_gen_password"> & { | ||
user: Pick<User, "id" | "first_name" | "password"> | ||
} | ||
> | ||
} | ||
|
||
const PDF: FC<PDFProps> = ({ classId, students }) => { | ||
const classLoginLink = generatePath(paths.login.student.class._, { classId }) | ||
|
||
const styles = pdf.StyleSheet.create({ | ||
mainView: { | ||
border: "2px solid black", | ||
display: "flex", | ||
flexDirection: "row", | ||
gap: 5, | ||
padding: 10, | ||
}, | ||
page: { | ||
padding: 20, | ||
}, | ||
text: { | ||
textAlign: "justify", | ||
marginBottom: 5, | ||
fontSize: 12, | ||
}, | ||
image: { | ||
width: 85, | ||
height: 70, | ||
}, | ||
}) | ||
|
||
return ( | ||
<pdf.Document> | ||
<pdf.Page size="A4" style={styles.page}> | ||
<pdf.Text style={styles.text}> | ||
Please ensure students keep login details in a secure place | ||
</pdf.Text> | ||
{students.map(student => ( | ||
<pdf.View key={`${student.user.id}-pdf`} style={styles.mainView}> | ||
<pdf.Image | ||
source={CflLogoImage} | ||
src={CflLogoImage} | ||
style={styles.image} | ||
/> | ||
<pdf.View> | ||
{/*TODO: Improve overall styles for this.*/} | ||
<pdf.Text style={styles.text}> | ||
Directly log in with:{"\n"} | ||
{makeAutoLoginLink(classLoginLink, student)} | ||
</pdf.Text> | ||
<pdf.Text style={styles.text}> | ||
OR class link: {classLoginLink} | ||
</pdf.Text> | ||
<pdf.Text style={styles.text}> | ||
Name: {student.user.first_name} Password:{" "} | ||
{student.user.password} | ||
</pdf.Text> | ||
</pdf.View> | ||
</pdf.View> | ||
))} | ||
</pdf.Page> | ||
</pdf.Document> | ||
) | ||
} | ||
|
||
export type PrintPasswordReminderCardsButtonProps = PDFProps & | ||
Omit<ButtonProps, "endIcon" | "onClick" | "className"> | ||
|
||
const PrintPasswordReminderCardsButton: FC< | ||
PrintPasswordReminderCardsButtonProps | ||
> = ({ classId, students, ...buttonProps }) => { | ||
const linkRef = useRef<HTMLAnchorElement | null>(null) | ||
|
||
const downloadPdf = async (): Promise<void> => { | ||
try { | ||
const blob = await pdf | ||
.pdf(<PDF classId={classId} students={students} />) | ||
.toBlob() | ||
|
||
const url = URL.createObjectURL(blob) | ||
|
||
if (linkRef.current) { | ||
linkRef.current.href = url | ||
linkRef.current.click() | ||
} | ||
|
||
URL.revokeObjectURL(url) | ||
} catch (error) { | ||
console.error(error) | ||
} | ||
} | ||
|
||
return ( | ||
<> | ||
<Button | ||
endIcon={<PrintIcon />} | ||
onClick={() => { | ||
void downloadPdf() | ||
}} | ||
className="body" | ||
{...buttonProps} | ||
> | ||
Print reminder cards | ||
</Button> | ||
{/* Invisible anchor tag to trigger the download */} | ||
<a ref={linkRef} target="_blank" style={{ display: "none" }}></a> | ||
</> | ||
) | ||
} | ||
|
||
export default PrintPasswordReminderCardsButton |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { Stack, Typography } from "@mui/material" | ||
import { type FC } from "react" | ||
import { Section } from "codeforlife/components/page" | ||
import { WarningAmber as WarningAmberIcon } from "@mui/icons-material" | ||
|
||
import PrintPasswordReminderCardsButton, { | ||
type PrintPasswordReminderCardsButtonProps, | ||
} from "./PrintPasswordReminderCardsButton" | ||
|
||
export interface PrintStudentCredentialsNotificationProps | ||
extends PrintPasswordReminderCardsButtonProps {} | ||
|
||
const PrintStudentCredentialsNotification: FC< | ||
PrintStudentCredentialsNotificationProps | ||
> = props => ( | ||
<Section boxProps={{ bgcolor: "#ffd23b" }} sx={{ paddingY: "5px" }}> | ||
<Stack direction="row" alignItems="center" gap={2}> | ||
<WarningAmberIcon htmlColor="#000" /> | ||
<Typography variant="body2" color="#000" mb={0}> | ||
This is the only time you will be able to view this page. You can print | ||
reminder cards or download as a CSV file. | ||
</Typography> | ||
<PrintPasswordReminderCardsButton | ||
{...props} | ||
style={{ marginLeft: "auto" }} | ||
variant="outlined" | ||
/> | ||
</Stack> | ||
</Section> | ||
) | ||
|
||
export default PrintStudentCredentialsNotification |
Oops, something went wrong.