
This is a todo management website where users can;
- Create an account, login and access their tasks and logout.
- Make tasks. Edit tasks’ titles, priority, effort, status and start – end date by moving or resizing.
- View their tasks in month, week and day view. And move tasks in and out of the backlog.
For this project I planned, concepted, designed and programmed everything. I finished the project in 2 weeks by working efficiently with scrum and making clever use of plugins.

Design choices
User Experience
Most people using Fullcalendar use a JS prompt() to get a title from the user. This would have been extremely easy to do but I decided against it because you cant easily click away to cancel it. First I tried to solve this by having a pure html pop-up but I tought it was messy. In the end I talked to my brother and he recommened using a class. He wrote a first draft of the generic popup class and I extended it and made instances. This was much better because the class handles everything about the pop-up even collecting the input.
DB setup
The task database had a few changes. In the base version I had a duration instean of end date, but I changed that to fit FullCalendars set up more.
Backlog
I wanted to eventually include a backlog for the events (scrum style) I had originally planned to include this info in the status column in the DB so 0 for backlog 1 for todo 2 for doing and 3 for done. I realised that a doing wasn’t really neccecairy (and more annoying to the user) so I removed that option. While making the backlog I realised I could just make it a calendar too but set the initial date to 1970-1-1. That way when you drag events from one calendar to another, the date is automatically changed via functions I had already created and now every event set in 1970-1-1 is a backlog event.
Function layout
I started with the main calendar object in the calendar.js file I ended up changeing it into a component like php file. This way it became much easier to add more calendars like the backlog and the month component. I was also able to clean up the main JS file this way and have all the calendars use the same functions for making, updating an deleting the events.
CSS
I’m used to just putting all css into one gaint file. This was always quite messy so this time I tried it with 3 files, one called styles for all the broad styles like fonts etc. One called grid for the layout styles, and one called components for all the sepparate styles. Overall I liked it, but sadly it was still a mess. Next time I want to try planning the css more. What I did really like was how I did the components. Each component like a calendar or the navbar etc, is a php file with the html javascript and css all in the same file. This made it very clear what fit with what.
SECURITY
During the cs50 lessons I learned that you can never trust users ever both with editing html input and sql injections, and so I was worried about security. I did a bit of reseach and chatting with chatgpt and learned about prepared statements, sanitising input in JS and PHP and protecting the DB. I originally planned to do the DB just in SQLite but I also learned that you shouldn’t do that, since it isnt secure.
DB access
I was very worried about keepting the website secure and did research. I learned that you need a seperate mysql account for php accessing the databases, and that you should hide the password in a private folder hidden by the .htaccess file. (I also put the components in private so users cant access them directly and don’t need a loginrequired include)
The code (long)
I build the entire project by using a WAMP server. I wanted to learn an old industry standard for this project like PHP and mysql and this handy tool allowed me to just build it on my PC with a localhost link for development.
register.php
This contains a form for a username, password and repeated password. Submitting the form sends it to adduser.php
adduser.php
Will start the session, get login credentials and log into the users database. It checks if it has enough input from the user. Does htmlspecialchars to ensure theres no javascript getting entered into the database. Then it does a bunch of checks. It checks if the username already exists (if it does it exits). After it uses a prepared statement to safely add the password and username to the database. Lastly it sets the session id to the id recieved from the insert and the username and redirects the user to the index.php
login.php
This has a login form which submits to controllers/authenticate.php
authenticate.php
This also logs into the DB. Checks input. Then searches the username in the users table. It checks if anything is returned from the query (if there isn’t the user doesn’t exist so an error is returned) If there is it compares the hashed passwords and sets the session id if the passwords are the same.
logout.php
ends the session and redirects the user to the login page.
loginrequired.php
This file is included into other php pages. It requires the user to be logged in and if they arent they are redirected to the login page while remembering where they came from. (I got this from a tutorial) I also included a set_cookie_params to try and keep users logged in longer, but im not really sure if it works tbh.
Task management functionallity
I used the plugin Fullcalendar for the calendars and purify to sanitise user input
Index.php
This is the dashboard it has a grid css and a few php inludes, like a navbar. I also created separate php files to include in this dashboard like a clock, a small month calendar, a backlog for events, and the main calendar.
mainCalendarNode.php
This sets up the main calendar fullcalendar object. It has a whole lot of options in it and it links to the funtions in the main calendar.js file I made. Only the eventInnerContent function is also in here because it just wouldn’t work if i put it in the other file (I think its because it needs it instantly). This function provides fullcalendar with nodes to put inside the events. I put the effort stat and a checkbox with an event listener in there. If the check box is clicked it toggles the checkbox and sends the update to the server.
calendar.js
This file contains all the functions necessary for the calendar functionality.
– class GenericModal
This sets up a generic class that creates an html modal. It takes an document id, a title and a button text and id. In the constructor it creates the html elements like a title and buttons. It also provides the buttons with onclick functions that trigger okBtn = function() or Cancel = function(). In create it attaches the elements to the dom (this way the extends classes can also add things in the construct in the order neccecairy).
Show, shows the popup, cancel hides it again, okBtn loops over all the inputs and textareas in th popup and gets the values the user put in.
– class NewTaskPopUp
This is a class extended from GenericModal, this adds a text area for a title input. This class is used in itemSelected (so if a user selected a timeframe in the calendar.)
– class TaskEditPopUp
This is also a class extended from GenericModal,this adds input elements for users change the title, priority, effort level and a check box for the status. It has a setValue function which gets the event info and sets all the initial inputs to the current values ready for the user to change them.It also adds a delete button that triggers the deleteBtn function of the class when clicked and sets the values to just be delete.
– itemSelected
This will trigger the show function from the NewTaskPop object from class NewTaskPopUp. The class will return the value of the title textarea the user filled in if they pressed the create button. It then purifies the input and checks the length of the title. After it sends it to sendEventToDB.
– itemClicked
First this will save the current event info recieved from fullcalendar. Then it will trigger the show function and the setValues from the TaskPop object from class TaskEditPopUp. The class will return the value of all the values the user filled in if they pressed the create button or just delete from the deleteBtn function. It checks first if delete = true, if it is it triggers deleteEventInDB, removes it from fullcalendar and returns to end the function. If delete = false it will then check updatedTask against originalTask and add any difference to an array named changes.
If changes = 0 then it returns, otherwise it checks every item in changes with the function validateInput, if it passes the event is updated in fullcalendar. If it fails it is removed from changes. Finaly it checks changes again to see if it still contains something and if it does its send to updateEventInfoDB. This ensures that only actual changes are send to the DB.
– validateInput
Takes a key and value and compares the value against rules stored in validationRules. If it passes it returns true if it doesn’t false.
– colorEvent
Will color the event. If its completed it is always gray otherwise it is colored based on priotity, by using the value of priority (a number) as index to get a color from array colorl.
– async sendEventToDB
Will send the title, start date and end date to the server makeevent.php and recieve an id back
– async updateEventTimeDB
Is triggered when event is moved or resized. It send the new times and id to the server updateeventtime.php to update it.
– async updateEventInfoDB
This recieves all the changes send to it from itemClicked and sends them to the server updateeventinfo.php.
– async deleteEventInDB
This recieves an id and sends it to the server deleteevent.php
– datePrettier
Formats a date in a nicer way.
controllers folder
All controllers check if the user is logged in, since user can technically navigate to the page by typing the full link. All controllers also user the credentials in the private folder and log in to access the DB
getevents.php
Gets called by events: “controllers/getevents.php” in each fullcalendar object. Full calendar sends a timeframe (start and end date)to the server, so this function. I used a not prepared statement because there is no user input and it only gets triggered when you change the view or refresh the page (maybe a prepared statement would still be good im not sure.) Via a while loop all event info is added to an array, which is then appended to an array of events.
makeevent.php
Gets a start & end date and title send to it and it also gets the user id from the session. It sanitises the title and formats the time to UTC so it can actually be added to the DB. Then it uses a prepared statement to safely add the new event to the database. It gets the newly generated id and returns this to the frontend.
updateeventinfo.php
This is the most complicated one. It takes a list of changes, safes and removes the ID from changes. Then it creates a new array for fields and for params and a string for types. It loops over all the changes and separates the key and value into fields and params respectively. It also adds an s to types for each loop. If after this looping fields is empty it exits. It adds the task id and user id to the 2 arrays. Then it finally puts all the changes in the DB statement by expanding the arrays.
updateeventtime.php
This one is very simple it just updates the start and end date of the given task id.
deleteevent.php
This deletes the task with the given task id and session id from the server.