General Details
- Please reply back with the project you are choosing to do
- Don’t worry about making everything perfect! This is more to see the kind of work you can put out rather than making sure you dont make any mistakes (we all do)
- For your submission, create a public GitHub repo and email us the link to view it. PLEASE INCLUDE IN THE README “Boilerexams Frontend Application Project” ALONG WITH INSTRUCTIONS TO INSTALL/RUN THE CODE
- You can use whichever package manager, styling system, frontend framework, coding language etc. that you are most comfortable with
- If you wish to use our specific stack, use React with Tailwind. We also use ShadCN components. You can create a Single Page App in React using Vite.
- If you have questions about our tech stack or any of the resources included etc. feel free to ask! I can be reached either at
matthew@boilerexams.com
by email or at@monsterico
on Discord
Course Form
Create a new course edit/create form. The form will need to take in all the required things to make a course and compile them into a single object to send off to the API. For this challenge, focus on the form and compiling of form inputs, you do not have to worry about actually integrating directly with our API to create database objects.
Resources
interface UpsertCourse {
id?: string;
number: number;
abbreviation: string;
color?: string;
image: string; // String of the image URL to display as the course icon
disclaimer?: string | undefined;
studyModes: StudyMode[];
flags: {
published: boolean;
};
}
type StudyMode = "EXAM" | "TOPIC" | "TIMED_EXAM"; // What study modes are "enabled" for this specific course. For example, CHM 115 has the two exam modes disabled, you can only study by topic
The above interface is the object the API will be expecting.
Example Edit Course form (this is the one we currently use. We do not like it. If we like yours we might bring you on to just implement it immediately :) )
Local Storage Stats
Create a mini statistics page based off some data. For this challenge you have more freedom of what exactly you want to show, whatever kind of statistics you can aggregate from the data is perfectly fine.
Resources
- https://boilerexams.com/statistics
- You can take a look at our current Stats page to see some examples of data we display. This uses our global statistics, but for this challenge you will be working with a single users submission data instead.
const LocalSubmissions = {
"1f86e0a7-0736-4f45-85d7-b0e4cdf5f969": {
"attempts": [
{
"id": "b75b7f23-1a27-40f1-aaaf-3ac2fb5df052",
"correct": false,
"userSolution": [
2
],
"type": "MULTIPLE_CHOICE"
},
{
"id": "87733164-7758-49cd-aff3-ba81d78b2189",
"correct": false,
"userSolution": [
1
],
"type": "MULTIPLE_CHOICE"
},
{
"id": "1ac69fa1-ab04-4c71-a893-df44f06fe5c1",
"correct": true,
"userSolution": [
4
],
"type": "MULTIPLE_CHOICE"
}
]
},
"2babcb23-91c7-4328-be7e-21d928212a72": {
"attempts": [
{
"id": "cbe6c697-a405-4855-96ed-f8ac71351b93",
"correct": true,
"userSolution": [
2
],
"type": "MULTIPLE_CHOICE"
}
]
},
"34b774c2-fd83-480d-acdb-3b170477cdb8": {
"attempts": [
{
"id": "6dc31110-d753-4044-ad2b-5ec14379e43d",
"correct": false,
"userSolution": [
3
],
"type": "MULTIPLE_CHOICE"
},
{
"id": "7057d4ad-2654-4637-b08c-c7bab6c5afce",
"correct": false,
"userSolution": [
2
],
"type": "MULTIPLE_CHOICE"
},
{
"id": "2b5d6099-8bb8-4d51-aaba-df6948fcedc1",
"correct": true,
"userSolution": [
1
],
"type": "MULTIPLE_CHOICE"
}
]
},
"92b0b416-a28e-4d94-a6d0-00e30c836209": {
"attempts": [
{
"id": "6c07efa6-c1ac-490d-bac1-5e7cd41e150c",
"correct": false,
"userSolution": [
4
],
"type": "MULTIPLE_CHOICE"
},
{
"id": "3f57ef1a-a88d-44d3-a001-41d80b9d9c42",
"correct": false,
"userSolution": [
4
],
"type": "MULTIPLE_CHOICE"
},
{
"id": "ded59800-12bf-4b32-93e3-4e3669198e0f",
"correct": true,
"userSolution": [
1
],
"type": "MULTIPLE_CHOICE"
}
]
},
"ad02cfa5-e269-4f18-953c-eabaf4aba395": {
"attempts": [
{
"id": "1a68d8ce-5267-4c2d-9c08-3b001c1cd4b8",
"correct": false,
"userSolution": [
1
],
"type": "MULTIPLE_CHOICE"
}
]
},
"ae399a1f-0722-4de6-a0c9-164a5d3e4a09": {
"attempts": [
{
"id": "86afd507-8b08-4be6-8eee-e0f211197510",
"correct": false,
"userSolution": [
1
],
"type": "MULTIPLE_CHOICE"
},
{
"id": "392ff2cf-5de7-438c-b8c4-9010e96d3da4",
"correct": false,
"userSolution": [
4
],
"type": "MULTIPLE_CHOICE"
},
{
"id": "c1759689-5b79-43fb-bb61-5f7d41fc8ba6",
"correct": true,
"userSolution": [
3
],
"type": "MULTIPLE_CHOICE"
}
]
},
"b82e5940-1afd-4514-8fe1-c3bd89adbb27": {
"attempts": [
{
"id": "3527499c-2c01-4fc5-be9e-588375ed5a08",
"correct": false,
"userSolution": [
0
],
"type": "MULTIPLE_CHOICE"
}
]
},
"c5fe1087-3fad-40e3-8b02-baa066f7718d": {
"attempts": [
{
"id": "829a32c1-821d-4558-ba1e-d889cadad2a1",
"correct": false,
"userSolution": [
1
],
"type": "MULTIPLE_CHOICE"
},
{
"id": "399b2822-83c5-4565-9cfb-bde6b4a87d74",
"correct": true,
"userSolution": [
3
],
"type": "MULTIPLE_CHOICE"
}
]
},
"ce88915a-d4cd-46cb-a1e6-c63f016ce5c7": {
"attempts": [
{
"id": "1a2165c2-fe40-48dc-b06b-fceedee00319",
"correct": false,
"userSolution": [
4
],
"type": "MULTIPLE_CHOICE"
}
]
},
"d028ae9b-37c1-4d74-a191-574e365dfa42": {
"attempts": [
{
"id": "b04df926-749b-450d-a41d-92ba4056145d",
"correct": false,
"userSolution": [
4
],
"type": "MULTIPLE_CHOICE"
}
]
},
"d44531f1-3cf7-404d-bd10-e9a786484b8a": {
"attempts": [
{
"id": "adc9bd82-a158-4748-878a-2eb1eb4e955e",
"correct": false,
"userSolution": [
0
],
"type": "MULTIPLE_CHOICE"
},
{
"id": "32fe2248-de2b-42c0-aacd-b988eb5fd2fd",
"correct": false,
"userSolution": [
2
],
"type": "MULTIPLE_CHOICE"
},
{
"id": "9202d742-94e0-406d-a1f0-1078c1e0983a",
"correct": true,
"userSolution": [
4
],
"type": "MULTIPLE_CHOICE"
}
]
},
"fce43ea6-284e-4347-ab51-b0b32184c310": {
"attempts": [
{
"id": "c50d3110-aed2-44ba-aa03-cce1ec03a578",
"correct": false,
"userSolution": [
1
],
"type": "MULTIPLE_CHOICE"
}
]
}
}
- Each key in the above object represents the local storage data for one question with that id. Each key contains a list of the attempts made for that question. Each attempt has an associated id, whether it was correct or incorrect, the userSolution associated with that attempt (0, 1, 2, 3, 4 all correspond to A, B, C, D, E), and the type of question it was (for this challenge they will all be MULTIPLE_CHOICE.
- This is a small subset of submissions all from one exam on one course. You can always take a look in your own Local Storage for Boilerexams to see this same structure mirrored there and copy more data to work with
Question Page
Create your own version of our question page! For this challenge we want to see your design skills at work. You don’t have to mirror our design standards at all, make this page as if it were for your own test or study site not for ours. However, we do want you to work a little with our API as well for this one! Your question page should be able to work with a couple of the different questions we give it!
Resources
api.boilerexams.com/questions/d44531f1-3cf7-404d-bd10-e9a786484b8a
- The response to this will be one Question object. You can substitute the id (everything after the last /) for any other question id on the site and receive a similar response- Example Question Object from the API (some fields were stripped to simplify things)
{
"id": "d44531f1-3cf7-404d-bd10-e9a786484b8a",
"type": "MULTIPLE_CHOICE",
"data": {
"body": "A line $l$ passes through the points $A(1,-2,1)$ and $B(2,3,-1)$. At what point does this line intersect with the $x y$-plane?",
"solution": [
4
],
"answerChoices": [
{
"id": "207ba5d5-499e-4998-8b33-c36d199720b9",
"index": 0,
"body": "$\\left(\\frac{3}{2}, \\frac{-1}{2}, 0\\right)$",
"questionId": "d44531f1-3cf7-404d-bd10-e9a786484b8a",
"stats": {
"count": 216
},
},
{
"id": "2739cdee-984e-41f4-b594-3a193ad3c177",
"index": 1,
"body": "$\\left(\\frac{5}{2}, \\frac{-1}{2}, 0\\right)$",
"questionId": "d44531f1-3cf7-404d-bd10-e9a786484b8a",
"stats": {
"count": 121
},
},
{
"id": "de252315-0a0f-4e9a-b489-9de938cddb66",
"index": 2,
"body": "$\\left(\\frac{3}{2},-1,0\\right)$",
"questionId": "d44531f1-3cf7-404d-bd10-e9a786484b8a",
"stats": {
"count": 52
},
},
{
"id": "69c66fb7-e7cc-49c6-8da1-ef15994c8b85",
"index": 3,
"body": "$\\left(\\frac{5}{2}, \\frac{1}{2}, 0\\right)$",
"questionId": "d44531f1-3cf7-404d-bd10-e9a786484b8a",
"stats": {
"count": 166
},
},
{
"id": "dfd102c0-9ad2-4864-bdd1-b4a53b211e06",
"index": 4,
"body": "$\\left(\\frac{3}{2}, \\frac{1}{2}, 0\\right)$",
"questionId": "d44531f1-3cf7-404d-bd10-e9a786484b8a",
"stats": {
"count": 3198
},
}
]
},
"number": 1,
"stats": {
"count": 1,
"timeSpent": "1060917290",
"timeSpentVideo": "199553861",
"submissions": 4975,
"submissionsCorrect": 3197,
"accuracy": 0.6426130653266332,
"difficulty": 0.6101970443349753
},
}
- The various body fields all support LaTeX, though this does not have to necessarily be implemented in your version (LaTeX can be annoying to render)
- Mainly focus on design and implementing the fields from an API response into that design!
- Any fields you find from our API can be ignored for the challenge (though feel free to experiment with them and look at various questions to see how we store them in the backend!)
Create a New Question Type
A slight variation on the previous challenge, for this challenge you will implement your own Question Type. Have you ever seen a question on an exam that is not just multiple choice? Well how would we support that type of question on Boilerexams? You can come up with your own data scheme to store the necessary information for that question and your own way of displaying that question, along with any associated logic. The resources here will be various examples of question data we currently have around the site.
Resources
interface MultipleChoiceData {
body?: string;
answerChoices: AnswerChoice[];
solution: number[];
}
interface FreeResponseData {
body?: string;
solution?: string;
}
interface FillInBlankData {
body?: string;
solution?: string[];
}
Every question type will likely have a body
for the question body itself, and a solution
that somehow stores the correct/expected answer. We do support LaTeX in our question bodies, but if its easier you can ignore LaTeX rendering entirely (its a pain to do, we know)
Create a Course Page
Create what could be page dedicated to an entire Course! You can either choose a specific course or make it more generic for any course. Where would the course logo and colors be incorporated? Where do you display the course name and number? What about the Study by Topic/Exam sections, Timed Exam button, Custom Exam button? What kinds of resources could you show for a course and how? You have full freedom here, no API restrictions, so be creative!
Resources
- Here’s a course logo and the colors associated with the course, though feel free to choose a different course or make your course page generic!
MA 16100 - Math - Applied Calculus I
Course color is
#870124
and Accent Color is#6c011d
. The accent color is used to change the White PNG to a darker shade of the courses color. You can also find this similar information about any course via the API by usingapi.boilerexams.com/courses/{courseAbbreviation}
where{courseAbbreviation}
is replaced with “MA16100” or “CS25100” etc. Using the API or supporting it is not required for this challenge.
Bring Your Own Challenge
Do you have another idea that’s similar to the other challenges here? Let us know what it is and we can approve it! As long as the challenge showcases your skills in some way it works for us. Your own challenge could revolve around a section of the site not mentioned here, use different parts of our API etc. Whatever it is, we will try and provide some helpful resources! Just make sure you are able to showcase it during our next interview round in about 5-10 minutes!