Experience our live website here!
Welcome to Gipfel Tutor, the pinnacle of personalized tutoring! Our Django-powered marketplace pairs you with the perfect tutor to conquer your academic peaks. Quick, simple, and effective — scale new heights in learning with us!
Our Mission: "Connect learners with a highly suitable tutor for their specific needs and preferences, within 48 hours."
Top Technical Features
- Credit Card Payments using Stripe: Securely pay for lessons online - Google Pay included. Powered by Stripe API and Stripe Webhooks
- Calendly Integration: Schedule and Cancel Calendly lessons seamlessly from the site. Powered by the Calendly API v2
- Socialaccount Login: Sign in with Google for a passwordless and modern experience.
⤴️ source: amiresponsive
The colour scheme follows a bright and engaging palette that is both professional and friendly. It suits the educational theme of the site and is designed to appeal to a younger student and tutor demographic.
#FFB703
used for Primary emphasis.#FB8500
used for secondary emphasis.#8ECAE6
used for light emphasis.#219EBC
used for darker emphasis.#023047
used for dark bakgrounds.I used coolors.co to generate my colour palette.
I've used CSS :root
variables to easily update the global colour scheme by changing only one value, instead of everywhere in the CSS file.
File: base.css
:root {
--my-blue-green: #219EBC;
--my-prussian-blue: #023047;
--my-ut-oragne: #FB8500;
--my-font-serif: "Noto serif", Arial, serif;
}
Additionally I've adapted the bootstrap variables to match the colour scheme. This was done according to a blogpost by bootstrap.
File: custom_bootstrap.css
:root,
[data-bs-theme=light] {
/* Custom Styles */
--bs-black: #0f0f0f;
--bs-light: #f2f2f2;
--bs-light-rgb: 242, 242, 242;
--bs-body-bg: #fff;
--bs-body-bg-rgb: 255, 255, 255;
--bs-primary: #FFB703;
--bs-primary-rgb: 255, 183, 3;
--bs-primary-shaded: #FFC533;
--bs-secondary: #8ecae6;
--bs-secondary-rgb: 142, 202, 230;
--bs-secondary-shaded: #ABD8ED;
--bs-dark: #023047;
--bs-dark-rgb: 2, 48, 71;
--bs-dark-shaded: #034363;
--bs-btn-light: #C3EAFD;
--bs-btn-light-rgb: 195, 234, 253;
--bs-btn-light-shaded: #9CDCFC;
--bs-success: #198754;
--bs-success-rgb: 25, 135, 84;
--bs-success-shaded: #2CAE6A;
--bs-border-style: none;
--bs-border-radius: 1.125rem;
--bs-border-radius-lg: 2rem;
--bs-font-sans-serif: "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
...
}
The user stories are based on the user personas (To be found at the bottom of the document under Design Thinking Process) and the features of the app.
Each user story is followed by a set of acceptance criteria that must be met for the story to be considered complete.
[!IMPORTANT] Make sure to also check out the User Story Map on GitHub Projects which was used extensively during the development process. It provides a more visual representation of the user stories and shows them grouped by epic along with their priority and status.
To follow best practice, wireframes were developed for mobile, tablet, and desktop sizes. I've used draw.io to design my site wireframes.
View the original draw.io file of the wireframes. (click on the "Open with" button and select "draw.io")
When first visiting the site, users are greeted with a clean, modern and inviting landing page. It includes a hero section with an image and a CTA Button. Further down the page, users will find an interactive section with a couple of different options to get started searching for a tutor.
The interactive Section is designed using a bento box layout, which is a modern and engaging way to present information. It allows users to quickly get an overview of the site's features and benefits.
The landing page is designed to be simple and user-friendly, providing a quick overview of the site's purpose and functionality. It encourages users to explore the site further and get started with their learning journey.
⤴️ Screenshot of the landing page
⤴️ Screenshot of the Bento Box Layout
relevant project files: index.html
The navigation bar is fixed at the top of the page, ensuring easy access to the most important links. It includes the text-logo (which is a link to the homepage), a CTA Button-Link to the Tutor List, the the dashboard and login/register. The Dashboard Link is hidden to logged out users and the login/register links are hidden to logged in users and will show them a logout link instead.
The Navigation bar also shows an "Admin" link to users that are flagged as "Staff" in the Django Admin Panel.
The navigation bar is designed to be simple and intuitive, providing quick access to the site's main features. It is responsive and collapses into a hamburger menu on smaller screens using the Bootstrap framework.
⤴️ Screenshot of the navigation bar
Some custom Javascript code was used to change the navigation bar's opacity once scrolling down the page. This was done to make the hero section of the landing page cleaner and more focused.
relevant project files: base.html, index.js
The footer includes Links to the Home, FAQs and About pages. It also includes links to the site's social media profiles (Facebook, Instagram, Github). Additionally, there is a Mailchimp Signup Form to allow users to subscribe to the site's newsletter.
The footer is designed to be simple and informative, providing users with quick access to important site links and social media profiles. It is responsive and collapses into a single column on smaller screens using the Bootstrap framework.
⤴️ Screenshot of the footer
relevant project files: base.html
The About page provides a brief overview of the site's purpose and the creator. The content of the About page can by dynamically changed by the site owner in the Django Admin Panel. For this, the Site owner Account needs to be added to the "Site Owner Admin" Authentication Group.
The About page is designed to be informative, providing users with background information. It helps to establish trust and credibility with users, ensuring they feel comfortable using the site.
⤴️ Screenshot of the about page
relevant project files: about.html
The FAQ page provides answers to common questions users may have about the site. The content of the FAQ page can be dynamically changed by a Staff member in the Django Admin Panel. For this, the Staff Account needs to be added to the "Customer Service Admin" Authentication Group.
The FAQ page is designed using bootstraps accordion component, which allows users to easily find the information they are looking for. It helps to reduce the number of support requests and ensures users have a positive experience on the site.
⤴️ Screenshot of the FAQ page
relevant project files: faq.html
The Tutor List page displays a list of all available tutors. Each tutor is displayed in a card format, showing their profile picture, name, hourly rate, and a brief description. The cards are designed to be visually appealing and informative, helping users quickly find a tutor that meets their needs. Most importantly the cards have a visible CTA Button to book a lesson with the tutor.
At the top of the Tutor List page, users can filter tutors based on their subjects and teaching values - or they can search for a specific tutor by name, catch phrase or description using the search bar. Search results can be sorted using the simplified sorting options below the search box.
The Tutor List page is designed to be user-friendly and interactive, providing users with the tools they need to find the perfect tutor. It helps users quickly narrow down their search and make an informed decision.
⤴️ Screenshot of the tutor list page
relevant project files: tutor_list.html
The Tutor Detail page provides a detailed profile of a specific tutor. It includes the tutor's profile picture, name, hourly rate, description, teaching values, and ratings. Additionally, users can see the tutor's availability and book a lesson with them. Lastly the tutor's reviews are displayed at the bottom of the page.
The Tutor Detail page is designed to be informative and engaging, providing users with all the information they need to make an informed decision. It helps users learn more about a tutor and decide if they are the right fit for their needs.
⤴️ Screenshot of the tutor detail page
relevant project files: tutor_detail.html
The Tutor reviews are displayed on the tutor detail page. They include the student's name, the review text, and the star rating. Above the reviews, the average rating of the tutor is displayed including a bar chart that visualizes the distribution of the ratings.
The reviews are designed to be informative and engaging, providing users with feedback from other students. They help users make an informed decision and build trust with the tutor.
⤴️ Screenshot of the tutor reviews
relevant project files: tutor_detail.html
The Calendly Scheduling Integration allows users to schedule lessons with tutors directly from the Tutor Detail page. The Calendly widget is embedded on the page and displays the tutor's availability. Users can select a date and time that works for them and book a lesson with the tutor.
The Calendly Scheduling Integration is implemented using the Calendly API v2 and OAuth2.0. A tutor can connect their Calendly account to the site in their tutor dashboard. Once connected, the tutor's availability and the status of any lesson is automatically synced with the site, ensuring users can book and cancel lessons at their convenience. The calendly webhooks were not used, as they are a paid feature - therefore any changes to events on the calendly site are not automatically reflected on Gipfel Tutor.
Upon booking a lesson, the user receives a confirmation email from Calendly and is redirected to a success page on the site. The tutor also receives a notification email from Calendly and can manage the lesson from their Dashboard.
⤴️ Screenshot of the Calendly Scheduling Integration
⤴️ Screenshot of the Calendly Success Page
relevant project files: tutor_detail.html, tutor_detail.js
All Calendly OAuth2.0 related code is stored in the calendly app and can be reused in other projects. The main functionality is handling the refresh token and the access token used by the Calendly API.
The Payments with Stripe feature allows users to pay for lessons online. Users can choose, when they want to pay for the lessons that they have booked. If they choose to go to the payment page either from their dashboard or from the tutor detail page, they will be redirected to the payment page. There they will see a list of all their upcoming lessons and the total amount they have to pay. They can then enter their credit card details and pay for the lessons. If they are signed in using their google account that has Google Pay set up, they can also use the Google Pay feature.
The Payments with Stripe feature is implemented using Custom payment flow documented by Stripe and includes webhook hadnling to ensure the payment status is updated in the site's database.
Once a users payment is successful, they are redirected to a success page on the site. An email is sent to the user confirming the payment and the payment is displayed in the user's dashboard.
⤴️ Screenshot of the Payments with Stripe feature
⤴️ Screenshot of the Payment Success Page
relevant project files: payment.html, payment.js
The User Authentication with Allauth feature allows users to create an account, log in, log out, reset their password and manage their account email. The feature is implemented using the Django Allauth package and includes email verification to ensure the security of user accounts. Additionally, the feature includes social media login using Google.
The socical media login feature comes in very handy in combination with Calendly and Stripe. For Calendly it allows a more seamless integration of the scheduling feature for tutors and for Stripe it allows Google Pay to be used as a payment method.
The Project is running Allauth Version: 0.63.3. This means that it is very convenient to adapt the templates which are heavily reliant on django template tags. Basically all Styling could be achieved by only changing one template file:
file: templates/account/allauth/base.html
{% extends 'base.html' %}
{% block page_header %}
{{ block.super }}
# Wrapping the block Content in a card by adding the wrapping
# divs to the page_header and post_content blocks
<div class="container navbar-margin mb-5">
<div class="row justify-content-center mt-3">
<div class="col col-lg-5">
<div class="card mt-2 auth-card">
<div class="card-body p-5">
{% endblock page_header %}
{% block post_content %}
</div>
</div>
</div>
</div>
</div>
{% endblock post_content %}
All other templates are extending this base.html file and only need to adapt their content block tag to add their form or content to the card above.
The google login Button was styled using the Google Sign-In Branding Guidelines
⤴️ Screenshot of the User Authentication with Allauth feature
⤴️ Screenshot of the Google Login confirm Screen
The Django Allauth package provides more templates that are not all documented here, but they are working on the site.
relevant project files: base.html, login.html, signup.html, password_reset.html, email.html, allauth/base.html
The user Dashboard provides users with an overview of their account. It includes a list of upcoming lessons, booking history, and payment history. Additionally, users can manage their account email and password. Unpaid lessons are displayed with an additional "Pay Now" Button. Lessons can also be canceled from the dashboard. Lastly, the dashboard includes a button that lets the user sign up as a tutor.
The user Dashboard is designed to be informative and user-friendly, providing users with all the information they need to manage their account. It helps users keep track of their lessons and payments and ensures they have a positive experience on the site.
⤴️ Screenshot of the Student Dashboard
relevant project files: student_dashboard.html
The Tutor Account Creation feature allows users to sign up as a tutor and create a detailed tutor profile. The feature includes a custom form that collects information about the tutor's hourly rate, availability, and teaching values. The tutor can also upload a profile picture and write a description of themselves. Additionally, the tutor can connect their Calendly account to the site.
The Tutor Account Creation feature is designed to be user-friendly and informative, providing tutors with all the tools they need to create a detailed profile. It helps tutors attract students and ensures they have a positive experience on the site.
⤴️ Screenshot of the Tutor Account Creation feature
relevant project files: add_tutor.html
The Tutor Dashboard provides tutors with an overview of their account. It includes a list of upcoming lessons, lessons that are waiting for confirmation, and an overview over all their students and upcoming lessons with them. Additionally, tutors can manage their account email, password and tutor profile. On the tutor dashboard, tutors can also connect their Calendly account to the site. At the bottom they have the option to delete their tutor profile.
If a tutor hasn't provided all necessary information to be displayed on the site yet - especially their calendly account, they will see a warning message at the top of the page informing them that their account will not be displayed on the site until they have provided the necessary information.
The Tutor Dashboard is designed to be informative and user-friendly, providing tutors with all the information they need to manage their account. It helps tutors keep track of their lessons and students and ensures they have a positive experience on the site.
⤴️ Screenshot of the Tutor Dashboard
⤴️ Screenshot of the Connect Calendly process
relevant project files: tutor_dashboard.html
The Tutor Card and the Lesson list item are used on the Tutor List page, the Tutor Detail page and the Tutor Dashboard. They are designed to be visually appealing and informative, providing users with all the information they need to make an informed decision. They are accessed in the django templates using the include tag. Using the with keyword, the context of the include block can be changed to display different information depending on the session user and the context on the page.
The lesson list item is used to display a single lesson as an item of a list and is used in the Tutor Detail view and the Student and Tutor Dashboards. It can be accessed using the include tag in the django templates as well and has similar customization options using the with keyword.
Example call to the tutor card include block:
file: tutor_dashboard.html
{% include "tutor_market/includes/tutor_card.html" with page="tutor_detail" %}
⤴️ Screenshot of the Tutor Card
⤴️ Screenshot of a Lesson List
relevant project files: tutor_card.html, lesson_list_item.html
The Django Admin Panel is used to manage the site's content and users. It provides an easy-to-use interface for site owners and staff members. Logged in users of the site can be flagged as "Staff" and added to a specific Authentication Group to access the Admin Panel with permissions appropriate to their role. The following Groups are avaliable in the Admin Panel:
These Permissions should allow staff members to manage the site effectively, provide customer support, and ensure the security of user accounts.
⤴️ Screenshot of the Admin Panel
relevant project files: allauth_groups_fixture.json
In the footer of the site, users can subscribe to the site's newsletter using the Mailchimp Newsletter form. The form is designed to be simple and user-friendly, providing users with an easy way to stay informed about new features and updates. The form is implemented using a generated template from the Mailchimp website. The design is adapted to fit the site's color scheme and branding but still sticks out as a Mailchimp form, sticking to the Mailchimp Branding Guidelines.
Mailchimp provides security and validation features out of the box.
Emails are collected using the site owners Mailchimp account. Momentarily, no emails are sent out to the subscribers, but this feature is planned for a future update.
⤴️ Screenshot of the Mailchimp Newsletter form
relevant project files: base.html
Django messages are used to provide feedback to users after they perform an action on the site. Messages are displayed at the bottom left of the screen. They are used to inform users about successful actions, errors, and warnings. The messages are designed to be simple and informative, providing users with feedback about their actions. Users can dismiss the messages by clicking the close button.
⤴️ Screenshot of the Django messages
relevant project files: base.html
Custom 404 and 500 error pages are used to provide users with a better experience when they encounter an error on the site. The pages include a brief message explaining the error and a link to the homepage. The pages are designed to be simple and user-friendly, providing users with a quick way to get back to the site's main content.
⤴️ Screenshot of the Custom 404 error page
⤴️ Screenshot of the Custom 500 error page
relevant project files: 404.html, 500.html
The site is designed to be responsive and work on all devices. It includes breakpoints for mobile, tablet, and desktop sizes. The site is designed using the Bootstrap framework, which provides a responsive grid system and components. The site is tested on multiple devices and browsers to ensure compatibility.
The responsive design ensures users have a positive experience on the site. Especially mobile users can easily navigate the site and access all features as mobile users are the expected main user group.
⤴️ Screenshot of the responsive design
relevant project files: All template files.
Many features were planned for the site but could not be implemented due to time constraints. Some of the planned features include:
[!NOTE] Make sure to have a look at the User Story Map to see smaller additions and quality of life improvements that are planned for the site. Just have a look at the "Should Have" and "Could Have" Columns.
git add
, git commit
, git push
)Below is a flowchart that outlines the user journey on the site. It shows the different paths a user can take and the actions they can perform. One focus of the site is to provide as much access to users that aren't logged in yet as possible. Users can view all tutors and their profiles without being logged in. They only need to log in or sign up once they want to book a lesson.
⤴️ Flowchart of the User Journey
A relational database was used for this project. The database schema was designed using dbdiagram.io before development began. The schema was then implemented using Django's built-in ORM. Throughout the development process, the schema was adjusted and updated as needed. The initial and the final version of the schema can be found below.
At the core of the Database is the Tutor
model which represents a tutor and saves all the information about them. The Tutor
model has relationships to students
via the TutoringSession
model which represents a single lesson. Payments are linked to a groupf of TutoringSessions
and are represented by the Payment
model. Further models and relationships can be seen in the ERD below.
⤴️ the initial ERD
Below is the ORM code that was used for the Tutor
model:
file: models.py
class Tutor(models.Model):
user = models.OneToOneField('auth.User', on_delete=models.CASCADE, related_name='tutor')
display_name = models.CharField(max_length=200)
subjects = models.ManyToManyField('Subject', related_name='tutors')
# -> Credit for decimal fields: https://docs.djangoproject.com/en/5.0/ref/models/fields/#decimalfield # noqa
hourly_rate = models.DecimalField(max_digits=6, decimal_places=2)
catch_phrase = models.CharField(max_length=200, default='Tutoring with a smile!')
description = models.TextField()
profile_image = models.ImageField(upload_to='tutor_images', null=True, blank=True)
values = models.ManyToManyField('Value', related_name='tutors')
iban = models.CharField(max_length=34, null=True, blank=True)
calendly_event_url = models.URLField(null=True, blank=True)
calendly_personal_token = models.CharField(max_length=600, null=True, blank=True)
calendly_access_token = models.CharField(max_length=600, null=True, blank=True)
calendly_refresh_token = models.CharField(max_length=600, null=True, blank=True)
calendly_token_expires_at = models.DateTimeField(null=True, blank=True)
profile_status = models.BooleanField(default=False)
def average_rating(self):
"""
Returns the average rating of the tutor from all related Rating
objects.
"""
return Rating.objects.filter(tutor=self).aggregate(Avg('score'))
def __str__(self):
return self.display_name
class Meta:
ordering = ['display_name']
I have used pygraphviz
and django-extensions
to auto-generate an ERD.
The steps taken were as follows:
sudo apt update
sudo apt-get install python3-dev graphviz libgraphviz-dev pkg-config
Y
to proceedpip3 install django-extensions pygraphviz
settings.py
file, I added the following to my INSTALLED_APPS
:
INSTALLED_APPS = [
...
'django_extensions',
...
]
python3 manage.py graph_models -a -o documentation/erd_final.png
'django_extensions',
from my INSTALLED_APPS
pip3 uninstall django-extensions pygraphviz -y
Note that the Student
model was dropped in the final version of the site. The User
model is used directly instead to represent students.
⤴️ the final ERD
source for django ERD generation: medium.com
GitHub Projects served as an Agile tool for this project. It isn't a specialized tool, but with the right tags and project creation/issue assignments, it can be made to work.
Through it, user stories, issues, and milestone tasks were planned, then tracked on a weekly basis using the basic Kanban board.
User stories are grouped by Epic and MoSCoW priority. The epics were determined before development began as part of the design process. Epics are represented as milestones in the GitHub Project while MoSCoW priorites are represented in a custom project field.
In depth information about the conception of the idea for the site and the User Stories can be found under the Design Thinking Progress section at the bottom of this file.
Throughout the development process, user stories were reevaluated after each iteration and adjusted accordingly. Many tasks were created based off of each User story. These tasks were mainly organized in a Kanban Board within the same GitHub Project.
All in all the User Story Map was of immense help to plan in between iterations and the Kanban Board served as a progress measuring tool while in the middle of a sprint.
[!NOTE] The User Story Map is frozen at the end of the last iteration. All user stories that are marked as
could-have
orshould-have
will be moved to the next iteration and reevaluated. The User Story Map is frozen like this to demonstrate what the Board would look like throughout the development process.
⤴️ Screenshot of the User Story Map
⤴️ Screenshot of the Kanban Board
I've decomposed my Epics into stories prior to prioritizing and implementing them. Using this approach, I was able to apply the MoSCow prioritization as custom project fields to my user stories within the project settings on GitHub.
GitHub Issues served as an another Agile tool.
Github issues was mainly used to track bugs and smaller feature requests. They also contain the user stories which means that filtering is key to keep an overview over the issues.
⤴️ Screenshot of the open issues (this screenshot shows open issues of an earlier date to showcase the structure of the issues throughout development. The actual list of currently open issues can be found by following the link above.)
⤴️ Screenshot of the closed issues (the same note as above applies here as well.)
I've used my own User Story Templates to manage user stories. They can be found in the .github/ISSUE_TEMPLATE folder.
The templates are as follows:
Below is the User Story Template as an example:
file: .github/ISSUE_TEMPLATE/user-story.md
---
name: User Story
about: Generate a new user story issue
title: 'USER STORY: title'
labels: enhancement, must-have, user-story
assignees: benschaf
---
As a **role** I can **capability** so that **received benefit**
**Acceptance Criteria**
- Acceptance criteria 1
- Acceptance criteria 2
- Acceptance criteria 3
Add todo items as needed by commenting on this issue.
Below is an overview of the business model for the site. It includes information about the site's target audience, the service it provides, and how it generates revenue.
WHO
This site acts as a platform for students to find tutors and book lessons with them. It therefore follows a Business to Customer
model.
WHAT The site focuses on providing the service of connecting students with tutors. It also simplifies the process of booking lessons for tutors and handles the payment collection process for them. The site would take a commission from the tutor's earnings as a fee for providing the service.
HOW Payment transactions are individual as opposed to a subscription model. Users can choose to pay for lessons as they book them or pay for multiple lessons at once. The site uses the Stripe API to handle payments securely.
The site is still in its early development stages, although it already has a newsletter, and links for social media marketing. The Facebook page is already set up and linked to the site.
Social media can potentially build a community of users around the business, and boost site visitor numbers, especially when using larger platforms such a Facebook.
A newsletter list can be used by the business to send regular messages to site users. For example a welcome message, notifications of new tutors, and reminders of upcoming lessons, updates to business hours, notifications of events, and much more!
The business goals of the app are to provide a platform where students can find tutors for their specific needs and preferences. The app aims to set itself apart from other tutoring platforms by providing a better matching system that leverages detailed tutor profiles, ratings, and reviews. The app also aims to provide a seamless user experience for both students and tutors, with features such as detailed tutor profiles, booking requests, and online payments.
I've identified some appropriate keywords to align with my site, that should help users when searching online to find my page easily from a search engine. This included a series of the following keyword types. I've also included some that I've decided to exclude during the process.
Check out this commit to see how the keywords were implemented along with semantic HTML tags.
The keywords marked as "(too generic)" are too authoritative and would be difficult to rank for.
I also played around with Word Tracker a bit to check the frequency of some of my site's primary keywords (only until the free trial expired).
I've used XML-Sitemaps to generate a sitemap.xml file. This was generated using my deployed site URL: https://gipfel-tutor-768a610dc54f.herokuapp.com
After it finished crawling the entire site, it created a sitemap.xml which I've downloaded and included in the repository.
I've created the robots.txt file at the root-level. Inside, I've included the default settings:
User-agent: *
Disallow:
Sitemap: https://gipfel-tutor-768a610dc54f.herokuapp.com/sitemap.xml
Further links for future implementation:
Creating a strong social base (with participation) and linking that to the business site can help drive sales. Using more popular providers with a wider user base, such as Facebook, typically maximizes site views.
I've created a facebook business page for the site, and linked it to the site's footer.
compare feature: Facebook Business Page
I have incorporate a newsletter sign-up form on my application, to allow users to supply their email address if they are interested in learning more.
The newsletter form is located in the footer of the site and is linked to a Mailchimp account.
compare feature: Mailchimp Newsletter form
[!NOTE] For all testing, please refer to the TESTING.md file.
The live deployed application can be found deployed on Heroku.
This project uses a Code Institute PostgreSQL Database.
To obtain my own Postgres Database from Code Institute, I followed these steps:
[!CAUTION]
- PostgreSQL databases by Code Institute are only available to CI Students.
- You must acquire your own PostgreSQL database through some other method if you plan to clone/fork this repository.
- Code Institute students are allowed a maximum of 8 databases.
- Databases are subject to deletion after 18 months.
This project uses AWS to store media and static files online, due to the fact that Heroku doesn't persist this type of data.
Once you've created an AWS account and logged-in, follow these series of steps to get your project connected. Make sure you're on the AWS Management Console page.
Search for S3.
Create a new bucket, give it a name (matching your Heroku app name), and choose the region closest to you.
Uncheck Block all public access, and acknowledge that the bucket will be public (required for it to work on Heroku).
From Object Ownership, make sure to have ACLs enabled, and Bucket owner preferred selected.
From the Properties tab, turn on static website hosting, and type index.html
and error.html
in their respective fields, then click Save.
From the Permissions tab, paste in the following CORS configuration:
[
{
"AllowedHeaders": [
"Authorization"
],
"AllowedMethods": [
"GET"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": []
}
]
Copy your ARN string.
From the Bucket Policy tab, select the Policy Generator link, and use the following steps:
Policy Type: S3 Bucket Policy
Effect: Allow
Principal: *
Actions: GetObject
Amazon Resource Name (ARN): paste-your-ARN-here
Click Add Statement
Click Generate Policy
Copy the entire Policy, and paste it into the Bucket Policy Editor
{
"Id": "Policy1234567890",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1234567890",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::your-bucket-name/*"
"Principal": "*",
}
]
}
Before you click "Save", add /*
to the end of the Resource key in the Bucket Policy Editor (like above).
Click Save.
From the Access Control List (ACL) section, click "Edit" and enable List for Everyone (public access), and accept the warning box.
Back on the AWS Services Menu, search for and open IAM (Identity and Access Management). Once on the IAM page, follow these steps:
group-gipfel-tutor
(group + the project name)From the JSON tab, select the Import Managed Policy link.
Search for S3, select the AmazonS3FullAccess
policy, and then Import.
You'll need your ARN from the S3 Bucket copied again, which is pasted into "Resources" key on the Policy.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::your-bucket-name",
"arn:aws:s3:::your-bucket-name/*"
]
}
]
}
Click Review Policy.
Suggested Name: policy-gipfel-tutor
(policy + the project name)
Provide a description:
Click Create Policy.
user-gipfel-tutor
(user + the project name)group-gipfel-tutor
AWS_ACCESS_KEY_ID
= Access key IDAWS_SECRET_ACCESS_KEY
= Secret access keyDISABLE_COLLECTSTATIC
still, this can be removed now, so that AWS will handle the static files.media
.This project uses Stripe to handle the ecommerce payments.
Once you've created a Stripe account and logged-in, follow these series of steps to get your project connected.
STRIPE_PUBLIC_KEY
= Publishable Key (starts with pk)STRIPE_SECRET_KEY
= Secret Key (starts with sk)As a backup, in case users prematurely close the purchase-order page during payment, we can include Stripe Webhooks.
< your deployed site url >/checkout/wh/
STRIPE_WEBHOOK_SECRET
= Signing Secret (Wehbook) Key (starts with wh)This project uses Gmail to handle sending emails to users for account verification and purchase order confirmations.
Once you've created a Gmail (Google) account and logged-in, follow these series of steps to get your project connected.
EMAIL_HOST_PASS
= user's 16-character API keyEMAIL_HOST_USER
= user's own personal Gmail email addressThis project uses Calendly to handle the scheduling of tutoring sessions.
Once you've created a Calendly developer account and logged-in, follow these series of steps to get your project connected.
From your Account Settings, click on My Apps
.
Click on Create New App
.
Fill in the required fields:
gipfel-tutor-dev
(could be anything)Web
Sandbox
localhost:8000/calendly/auth
Click Save & Continue
.
Copy the Client ID
and Client Secret
keys along with the Redicrect Uri
that you specified. These will be used as environment variables in your project.
CALENDLY_DEV_CLIENT_ID
= Client IDCALENDLY_DEV_CLIENT_SECRET
= Client SecretCALENDLY_DEV_REDIRECT_URI
= localhost:8000/calendly/auth
Create another App for the Production
environment type, but with the following changes:
gipfel-tutor
(could be anything)/calendly/auth
Production
.Client ID
and Client Secret
keys and the Redirect Uri
for the production app.
CALENDLY_PROD_CLIENT_ID
= Client IDCALENDLY_PROD_CLIENT_SECRET
= Client SecretCALENDLY_PROD_REDIRECT_URI
= "your deployed heroku base url" + /calendly/auth
This project uses Google to handle the social login feature.
Once you've created a Google account and logged-in, follow these series of steps to get your project connected.
From the Google Developers Console, create a new project.
Click on the Credentials tab on the left.
Click on Create Credentials and select OAuth client ID.
Select Web application.
Add your Heroku app URL to the Authorized Redirect URIs.
Add your localhost URL to the Authorized Redirect URIs.
Click Create.
You'll be provided with a Client ID
and Client Secret
. Save these as environment variables in your project.
GOOGLE_CLIENT_ID
= Client IDGOOGLE_CLIENT_SECRET
= Client SecretIn your Django project, navigate to the settings.py
file and add the following code if not already there:
INSTALLED_APPS = [
# ...
"django.contrib.sites",
"allauth",
"allauth.account",
"allauth.socialaccount",
"allauth.socialaccount.providers.google",
# ...
]
SITE_ID = 1
# -> Credit for retrieving the email address: https://github.com/pennersr/django-allauth/issues/330 # noqa
SOCIALACCOUNT_PROVIDERS = {
"google": {
"SCOPE": [
"profile",
"email",
],
"AUTH_PARAMS": {
"access_type": "online",
},
}
}
SOCIALACCOUNT_ENABLED = True
migrate the database to include the new tables for allauth:
python3 manage.py migrate
In the Django admin panel, navigate to Sites.
Add a new site with the following details:
localhost:8000
localhost
Add another site with the following details:
Your Deployed Heroku App URL
Heroku
In the Django admin panel, navigate to Social Applications.
Add a new social application with the following details:
Google
Google
Your Google Client ID
Your Google Client Secret
localhost
and Heroku
[!TIP] For troubleshooting, refer to the Allauth Socialaccount Documentation.
This project uses Heroku, a platform as a service (PaaS) that enables developers to build, run, and operate applications entirely in the cloud.
Deployment steps are as follows, after account setup:
[!IMPORTANT] This is a sample only; you would replace the values with your own if cloning/forking my repository.
Key | Value |
---|---|
AWS_ACCESS_KEY_ID |
user's own value |
AWS_SECRET_ACCESS_KEY |
user's own value |
DATABASE_URL |
user's own value |
DISABLE_COLLECTSTATIC |
1 (this is temporary, and can be removed for the final deployment) |
EMAIL_HOST_PASS |
user's own value |
EMAIL_HOST_USER |
user's own value |
SECRET_KEY |
user's own value |
STRIPE_PUBLIC_KEY |
user's own value |
STRIPE_SECRET_KEY |
user's own value |
STRIPE_WEBHOOK_SECRET |
user's own value |
USE_AWS |
True |
CALENDLY_DEV_CLIENT_ID |
user's own value |
CALENDLY_DEV_CLIENT_SECRET |
user's own value |
CALENDLY_DEV_REDIRECT_URI |
user's own value |
CALENDLY_PROD_CLIENT_ID |
user's own value |
CALENDLY_PROD_CLIENT_SECRET |
user's own value |
CALENDLY_PROD_REDIRECT_URI |
user's own value |
GOOGLE_CLIENT_ID |
user's own value |
GOOGLE_CLIENT_SECRET |
user's own value |
Heroku needs three additional files in order to deploy properly.
You can install this project's requirements (where applicable) using:
pip3 install -r requirements.txt
If you have your own packages that have been installed, then the requirements file needs updated using:
pip3 freeze --local > requirements.txt
After you have your requirements file set up, you need to add the cryptography==36.0.0 package to the requirements file manually by pasting the line cryptography==36.0.0
at the end of the file.
The Procfile can be created with the following command:
echo web: gunicorn app_name.wsgi > Procfile
The runtime.txt file needs to know which Python version you're using:
python3 --version
in the terminal.python-3.9.19
For Heroku deployment, follow these steps to connect your own GitHub repository to the newly created app:
Either:
Or:
heroku login -i
heroku git:remote -a app_name
(replace app_name with your app name)add
, commit
, and push
to GitHub, you can now type:
git push heroku main
The project should now be connected and deployed to Heroku!
This project can be cloned or forked in order to make a local copy on your own system.
For either method, you will need to install any applicable packages found within the requirements.txt file.
pip3 install -r requirements.txt
.You will need to create a new file called env.py
at the root-level,
and include the same environment variables listed above from the Heroku deployment steps.
[!IMPORTANT] This is a sample only; you would replace the values with your own if cloning/forking my repository.
Sample env.py
file:
import os
os.environ.setdefault('DEVELOPMENT', 'True') # only include in local environment!
os.environ['DEBUG'] = 'True' # only include in local environment!
os.environ['SECRET_KEY'] = 'users own value'
os.environ.setdefault('DATABASE_URL', 'users own value')
os.environ.setdefault('EMAIL_HOST_PASS', 'users own value')
os.environ.setdefault('EMAIL_HOST_USER', 'users own value')
# AWS is disabled by default, but can be enabled by setting USE_AWS to True
# The displaying of tutor profile images will not work even with AWS enabled
# as explained in "Local VS Deployment".
# os.environ.setdefault('USE_AWS', 'True')
os.environ.setdefault('AWS_ACCESS_KEY', 'users own value')
os.environ.setdefault('AWS_SECRET_ACCESS_KEY' ,'users own value')
os.environ.setdefault('STRIPE_PUBLIC_KEY', 'users own value')
os.environ.setdefault('STRIPE_SECRET_KEY', 'users own value')
os.environ.setdefault('STRIPE_WEBHOOK_SECRET', 'users own value')
os.environ.setdefault('CALENDLY_DEV_CLIENT_ID', 'users own value')
os.environ.setdefault('CALENDLY_DEV_CLIENT_SECRET', 'users own value')
os.environ.setdefault('CALENDLY_DEV_REDIRECT_URI', 'http://localhost:8000/calendly/auth/')
os.environ.setdefault('CALENDLY_PROD_CLIENT_ID', 'users own value')
os.environ.setdefault('CALENDLY_PROD_CLIENT_SECRET', 'users own value')
os.environ.setdefault('CALENDLY_PROD_REDIRECT_URI', '< your deployed site url >/calendly/auth/')
os.environ.setdefault('GOOGLE_CLIENT_ID', 'users own value')
os.environ.setdefault('GOOGLE_CLIENT_SECRET', 'users own value')
Once the project is cloned or forked, in order to run it locally, you'll need to follow these steps:
python3 manage.py runserver
CTRL+C
or ⌘+C
(Mac)python3 manage.py makemigrations
python3 manage.py migrate
python3 manage.py createsuperuser
python3 manage.py loaddata fixtures/*.json */fixtures/*.json
(this will load all fixtures from the root fixtures directory and any fixtures directories within apps)python3 manage.py runserver
If you'd like to backup your database models, use the following command for each model you'd like to create a fixture for:
python3 manage.py dumpdata your-model > your-model.json
You can clone the repository by following these steps:
git clone https://github.com/benschaf/gipfel-tutor.git
Alternatively, if using Gitpod, you can click below to create your own workspace using this repository.
Please note that in order to directly open the project in Gitpod, you need to have the browser extension installed. A tutorial on how to do that can be found here.
By forking the GitHub Repository, we make a copy of the original repository on our GitHub account to view and/or make changes without affecting the original owner's repository. You can fork this repository by using the following steps:
All the Credits and hyperlinks can be found in the respective files on the indicated lines.
Additionaly, Chris Beams article "How to Write a Git Commit Message" was used as a guideline for writing commit messages.
For this stage, I created 4 user personas to represent the different types of users that would interact with the app.
For each persona, I considered their "5 Cs" (circumstances, constraints, context, criteria, and compensating behaviors) related to online tutoring. This helped me understand the needs and motivations of the users.
The target audience for the app is primary and secondary school and gymnasium students in Switzerland (or their parents, especially in the case of primary students). The app is also aimed at university students who are looking to become tutors and earn extra income.
The user personas are:
Lara - A 14 year old student who is struggling with math and needs a tutor to help her understand the concepts better.
Jonas - A 17 year old student who is preparing for his final exams and needs a tutor to help him with exam preparation.
Sophie - The Mother of a 9 year old student who is looking for a tutor to help her child with homework and assignments.
David - A 20 year old university student who is looking to make some extra money by tutoring students in his area of expertise.
5 C's for each persona:
Lara
Jonas
Sophie
David
Considering all the user Personas, I created a problem statement that would guide the design of the app.
The problem statement is:
"How might we create a platform that connects students with a highly suitable tutor for their specific needs and preferences, within 48 hours."
Considering the problem statement and the user personas, I brainstormed ideas for the app. I considered the features that would be most important to the users.
The Features are already sorted by priority although these priorities are subject to change, especially once the user stories are created.
Lara:
Jonas:
Sophie:
David:
After ideating I created wireframes and content for the prototype of the site which is of course this repository.
Check out the full prototype including wireframes, user stories, and the working site by browsing around the readme and the repository. Also check out the website itself.
The prototype of the site was tested manually and progamatically to ensure that it is working as intended. Testing in the sense of design thinking has not been very extensive yet. This will be done in the future.