Video Demo: https://youtu.be/wMdfZMkByws
This is a web apllication that allows to check your dog into our local playground in Zemun, Belgarde and overview current participants.
As a dog owner, I know how it might be difficult to manage communication among dogs, as every dog has its own previous experience and level of social adaptation. When meeting another dog it's good to know such details about it as: gender, age, breed, is it friendly or not and so on. Based on needs of your dog, you might want to avoid certain dogs or meet only with your dog's friends.
My web application allows user to understand what dogs are currently checked into the playground and to decide whether you want to join them and check in as well or to choose another spot for a walk, which saves user's time and adds to a confident and calm walk with their dog. For the overview part there are two information blocks: a short overview of participants, such as total amount of dogs, total males/females, total based on dogs size (small/medium/large according to the breed classification), and a detailed one with specific information about every dog (name, age, breed, size, behavior around other dogs).
There is also a notification field where every user get notified about new gifts received and from whom and about birthdays of currently checked in dogs. I added this functionality as a small and fun ice breaker for dog owners.
My web application has a responsive design, so it is easy to open it on differenet devices.
A quick research gave me no results for similar web or mobile apps on the Internet.
- Flask framework to make a dynamic web application
- Jinja template engine
- SQLite3 for my database
- JavaScript to manipulate the DOM and BOM
- JavaScript Fetch API
- JavaScript History API (back() method)
- JavaScript Validation API (Constraint Validation DOM method)
- cs50, datetime, flask, flask_session, Werkzeug, Bootstrap libraries
- CSS
- HTML
Static folder contains images that I use for my web app and styles.css is a css with responsive design.
Templates folder contains html files for pages of my web app:
- layout.html is a template for other html files
- index.html is a first page a user sees with a menu to register or log in only. After registration or login a user would see also other links: My dogs, My playground, Log out
- register.html contains a form to register a user and JS code for user's inputs validation
- login.html contains a form to log in and JS for form input validation, also if a user forgot password, there is a button that links to reset.html
- reset.html contains two forms, one of them is hidden at the start. One form shows security questions, that user fills out at the registration. If user replies correctly, another form will be shown to reset a user's password. Security questions answers and new password are being fetched to the server with Fetch API
- my_profile.html displays cards with dogs' profiles, data is being retrieved from a database and passed to the template as an object
- at my_profile.html user is able to view dog's profile, delete it or add a new one. When a user presses delete button, id of a dog is being fetched to the server and then a dog with this id is being deleted from a database. A form with a view button contains hidden dog id, which would help to display data about this dog in account_view.html
- account_view.html displays data about a concrete dog, the dog id is got from form input from my_profile.html, then all the necessary data is being retrieved from a database and passed to the template as an object. There are two options on the page: to edit data or go back
- Edit functionality is implemented through form with a hidden dog id and submit button "edit". Then this id is got with request.form.get() server side and form_edit.html is being rendered with prefilled data from a database, which is being passed to the template as an object. This allows the user to see the current values and make changes as needed.
- Back functionality is implemented with the history back() method (History API)
- form_edit.html has JS input validation, save and back buttons
- account_new.html contains a form with options to choose to fill out a dog profile, it contains JS input validation as well
- checkin.html contains a form with checkboxes with users' dogs names and accordion component with different information: instructions about checking in, notifications, a short overview and a detailed one of currently checked in dogs
- checkin.html contains JS that implements timer() function, checkin() and checkout() functions. Also I fetch data from a server for currently checked in dogs overview and notifications
breeds.csv is a csv file with breeds and breed sizes, with which I populated breeds table in my database (see to_create_db_from_csv.py).
dict.txt is a file with breeds and sizes according to the AKC, I used it to make csv file.
dogs.db is my database.
requirements.txt is a file with Python packages, which are required to run the project.
app.py is the main file, where my Flask app is being created and configured, routes are being defined and requests and responses are being handled:
- "/" - renders index.html.
- "/register" - gets and validates user's input form registration form, if data is invalid, it redirects to the page with a registration form and flashes a message where is a mistake. If data is valid, it proceeds to save data in database, to save user_id in session and redirects to "/my_profiles" route. Renders register.html
- "/login" - gets and validates user's input form login form, if data is invalid it redirects to the page with a login form and flashes a message where is a mistake. If data is valid, it proceeds to save user_id in session and redirects to "/checkin" route. Renders login.html
- "/logout" - clears session data and redirects to "/"
- "/validate" - renders reset.html; converts the incoming request data into Python data and checks the security questions answers. Based on the result, sends the response with a Success/Failure message
- "/reset" - renders reset.html; converts the incoming request data into Python data and saves a new password to the database. Based on the result, sends the response with a Success/Failure message
- "/account_new" - renders account_new.html; gets and validates user's inputs from a form, if user's data is incorrect, flashes the message where the problem is and redirects user to the same page with new account form. Otherwise, saves user's dog's info to the database, assigns to a dog a profile avatar and updates the database
- "/form_edit" - gets and validates user's inputs from a form, if user's data is incorrect, flashes the message where the problem is and redirects user to the same page with dogs profiles. Otherwise, shows the form to edit dog's profile, prefilled with previous information and passes the data from database to the template
- "/save_edited_account" - gets and validates user's inputs from a form, if user's data is incorrect, flashes the message where the problem is and redirects user to the /form_edit. Otherwise, updates the database with new info and redirects to /my_profile
- "/account_delete" - converts the incoming request data into Python data, validates the data and, if incorrect, sends response with a failure message. Otherwise, deletes the data from the database, from session and sends response with a success message
- "/my_profile" - retrieves the avatar picture number associated with user's dogs' id and passes it to the template, renders my_profile.html
- "/account_view" - gets id of a dog from a form in a dog card, validates the data and, if incorrect, flashes an error and redirects back to /my_profile. Otherwise, retrieves data from a database to pass it later to the template, calculates dog's age, renders account_view.html
- "/checkin" - converts the incoming request data into Python data, validates the data and, if incorrect, sends response with a failure message. Otherwise saves data in database and returns a response with success message. Renders checkin.html
- "/checkin_time" - converts the incoming request data into Python data, validates the data and, if incorrect, sends response with a failure message. Otherwise retrieves time of check in from database and returns a response with success message
- "/checkout" - converts the incoming request data into Python data, validates the data and, if incorrect, sends response with a failure message. Otherwise, deletes a dog from a checkout table in my database and returns a response with success message
- "/current_checkins" - retrieves all the necessary information from the database about checked in dogs, calculates age of dogs, if today is dog's birthday, inserts this dog id into birthdays table in our database (I use it later to show notifications about dog's birthdays), if it hasn't been done yet. If it has, but a user hasn't seen the notification about birthday, inserts it anyway. If a user has already seen the notification about this dog birthday, inserts only if a year has passed since the previous record. Then, it sends the response with the list of currently checked in dogs and all the info about them
- "/gift" - gets the data from a form input and validates the data and if incorrect, flashes a message with the problem and redirects to /checkin. Otherwise,inserts data about a gift to the database and redirects to /checkin
- "/get_gifts" - sends the response to fetch request with data about new gifts that currently checked in dogs have got
- "/update_gifts" - converts the incoming request data into Python data and validates it, if data is incorrect or no records with status "new", sends a response with failure message. Otherwise, updates gift status with the id we got to 'OLD' in my database.
- "/update_birthdays" - converts the incoming request data into Python data and validates it, if data is incorrect or no records with status "new", sends a response with failure message. Otherwise, updates birthday status with the id we got to 'OLD' in my database.