design update and bug fix

main
Valentin 2024-01-23 20:27:58 +01:00
parent 85082a7bd9
commit 90ed4195ae
42 changed files with 373 additions and 204 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@ -1 +1,69 @@
# nba-calendar
# Synchronize-NBA-Calendar
[![Python](https://img.shields.io/badge/Python-3.6%2B-blue.svg)](https://www.python.org/)
[![Flask](https://img.shields.io/badge/Flask-2.0%2B-orange.svg)](https://flask.palletsprojects.com/en/2.0.x/)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](https://opensource.org/licenses/MIT)
## Description
SoMyCal is a Python Flask application that allow users to sync their calendar with NBA teams' schedules. The app is designed to work on any device supporting the iCalendar format (ICS), providing a web interface and oauth integration with Google.
This project serves a dual purpose - it not only acts as a useful NBA calendar synchronization tool but also was initiated to assist a friend in understanding Python and supporting their own programming endeavors.
## Features
- **Calendar Sync:** Easily synchronize NBA team schedules with your preferred calendar application that supports the ICS format (like, every calendar app)
- **Cross-Device Compatibility:** Access the application on any device with ICS support, ensuring flexibility and convenience.
- **Web Interface:** The user-friendly web interface makes navigation and synchronization a breeze.
- **Google OAuth :** Seamlessly connect with your Google account for a simple and fast experience
## Getting Started
Follow these steps to get started with the project:
1. Clone the repository:
```bash
git clone https://github.com/itsmrval/somycal.git
```
2. Install the required dependencies:
```bash
pip install -r requirements.txt
```
3. Copy then edit the env files:
```bash
cp example.env .env
```
4. Run the Flask application:
```bash
python app.py
```
4. Access the application through your web browser at [http://127.0.0.1:8000](http://127.0.0.1:8000).
## Screenshots
![Screenshot 2](https://i.ibb.co/DLLbTv3/Screenshot-6.png)
*Quick dashboard screenshot*
## Live Demo
Check out the live demo of the application currently running at [https://somycal.com](https://somycal.com).
## Contribution
Contributions are welcome! If you'd like to contribute to the project send a PR
## License
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details.

11
app.py
View File

@ -174,9 +174,10 @@ def index():
if (Team.query.filter_by(idUser=user.id, idTeam=i).first() is None): if (Team.query.filter_by(idUser=user.id, idTeam=i).first() is None):
otherTeams.append(i) otherTeams.append(i)
return render_template('index.html', userTeams=getUserTeams(user.id), otherTeams=otherTeams, getTeamName=getTeamName, getTeamLogo=get_team_logo, userId=user.id) return render_template('dashboard.html', userTeams=getUserTeams(user.id), otherTeams=otherTeams, getTeamName=getTeamName, getTeamLogo=get_team_logo, userId=user.id)
return redirect("/login", code=302)
return render_template('index.html')
@app.route('/add/<int:idTeam>') @app.route('/add/<int:idTeam>')
def addTeamRoute(idTeam): def addTeamRoute(idTeam):
@ -230,12 +231,10 @@ def generate_ical_feed(user_id):
return response return response
@app.route('/login')
def login():
return render_template('login.html')
@app.route('/login/google') @app.route('/login/google')
def google_redirect(): def google_redirect():
if 'instagram' in request.headers.get('User-Agent').lower() or 'facebook' in request.headers.get('User-Agent').lower():
return render_template('open_in_browser.html')
return google.authorize(callback=url_for('authorized', _external=True, _scheme='https')) return google.authorize(callback=url_for('authorized', _external=True, _scheme='https'))
@app.route('/logout') @app.route('/logout')

View File

@ -1,30 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<title>Login with Google</title>
</head>
<body>
<div class="container">
<div class="row justify-content-center align-items-center" style="height:100vh;">
<div class="col-md-4">
<div class="card">
<div class="card-body text-center">
<img src="static/logo/google.png" width="150px">
<h5 class="card-title">Login with Google</h5>
<p class="card-text">Click the button below to connect with Google</p>
<a href="/login/google" class="btn btn-danger btn-lg">Login with Google</a>
</div>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.10.2/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

6
static/bootstrap/js/bootstrap.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

BIN
static/img/brands/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

BIN
static/img/brands/lyft.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 890 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 811 B

View File

@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300" width="406" height="306" class="illustration styles_illustrationTablet__1DWOa"><path d="M95.85,121.73c-27.66,4.91-47.21,29-44,55.43,1.71,14,8.64,26.43,26.47,30,47.3,9.51,225.85,45.31,260.93-16.72,27.35-48.34,11.05-81.81-14.35-102.76s-78-16.6-121.53-2.26C171,96.11,146.93,112.65,95.85,121.73Z" fill="#e6e6e6" opacity="0.3"></path><ellipse cx="205.6" cy="245.02" rx="161.02" ry="11.9" fill="#e6e6e6" opacity="0.45"></ellipse><circle cx="115.32" cy="60.66" r="19.14" fill="#ffd200"></circle><circle cx="115.32" cy="60.66" r="36.49" fill="#ffd200" opacity="0.15"></circle><circle cx="195.69" cy="193.3" r="51.17" fill="#24285b"></circle><circle cx="195.69" cy="193.3" r="32.21" fill="#fff"></circle><path d="M133.91,205.51c3.39,0,4.61,1.22,4.61,4.6v5.83c0,3.39-1,4.61-4.61,4.61h-9.35V238.3c0,3.38-1.22,4.6-4.61,4.6h-6.64c-3.38,0-4.6-1.22-4.6-4.6V220.55H64c-3.38,0-4.6-1.22-4.6-4.61v-4.88A9,9,0,0,1,61,205.51l45-55.83a8.07,8.07,0,0,1,6.5-3.25H120c3.39,0,4.61.95,4.61,4.61v54.47Zm-25.2-36.32L79.3,205.51h29.41Z" fill="#68e1fd"></path><path d="M327.42,205.51c3.39,0,4.61,1.22,4.61,4.6v5.83c0,3.39-.95,4.61-4.61,4.61h-9.35V238.3c0,3.38-1.22,4.6-4.61,4.6h-6.64c-3.38,0-4.6-1.22-4.6-4.6V220.55H257.5c-3.38,0-4.6-1.22-4.6-4.61v-4.88a9,9,0,0,1,1.62-5.55l45-55.83a8.07,8.07,0,0,1,6.5-3.25h7.45c3.39,0,4.61.95,4.61,4.61v54.47Zm-25.2-36.32-29.41,36.32h29.41Z" fill="#68e1fd"></path><path d="M307.35,135.53s-8.51-2.32-10.36-10.25c0,0,13.19-2.66,13.57,10.95Z" fill="#68e1fd" opacity="0.58"></path><path d="M308.4,134.69s-5.95-9.41-.72-18.2c0,0,10,6.37,5.58,18.22Z" fill="#68e1fd" opacity="0.73"></path><path d="M309.93,134.7s3.14-9.94,12.65-11.82c0,0,1.78,6.45-6.16,11.84Z" fill="#68e1fd"></path><polygon points="303.76 134.47 305.48 146.28 316.35 146.33 317.95 134.53 303.76 134.47" fill="#24285b"></polygon><path d="M201.88,126.11s1.4,6.75.79,11.43a3.46,3.46,0,0,1-3.91,3c-2.35-.34-5.43-1.48-6.62-5l-2.76-5.75a6.21,6.21,0,0,1,1.93-6.9C194.85,119.63,201.23,122,201.88,126.11Z" fill="#f4a28c"></path><polygon points="189.88 130.8 188.98 153.41 201.47 153.01 197.11 136.72 189.88 130.8" fill="#f4a28c"></polygon><path d="M200.21,126.59a27.36,27.36,0,0,1-6.37.27,5.76,5.76,0,0,1,.74,6.27,4.68,4.68,0,0,1-5.4,2.52l-.93-8.82a7,7,0,0,1,2.8-6.64,24.34,24.34,0,0,1,2.77-1.79c2.41-1.32,6.32-.07,8.39-2.05a1.67,1.67,0,0,1,2.75.78c.72,2.63.74,6.9-2.71,8.79A6.36,6.36,0,0,1,200.21,126.59Z" fill="#24285b"></path><path d="M195.29,132.84s-.36-2.64-2.32-2.2-1.46,4.25,1.28,4.28Z" fill="#f4a28c"></path><path d="M202.54,130.41l2.23,2.41a1.11,1.11,0,0,1-.49,1.81l-2.56.8Z" fill="#f4a28c"></path><path d="M198.22,140.25a8.24,8.24,0,0,1-4.3-1.92s.66,4.09,5.66,7.61Z" fill="#ce8172" opacity="0.31"></path><path d="M189,153.41l12.49-.4s19.62-3.33,26.43,12.67S226,204.29,226,204.29,218.9,228.16,189,225.52c0,0-24.87-1.44-27.68-35.53a33.25,33.25,0,0,0-.68-4.42C159.5,180.24,158.84,164.07,189,153.41Z" fill="#68e1fd"></path><path d="M172.27,174.65s6.66.73,15.91,16.22,27.41,9.81,37.65-1.65l-19,25.14-21.28-1.71-11.57-30.8Z" opacity="0.08"></path><rect x="242.24" y="139" width="3.69" height="10.74" transform="translate(-16.97 33.59) rotate(-7.61)" fill="#ffd200"></rect><rect x="242.24" y="139" width="3.69" height="10.74" transform="translate(-16.97 33.59) rotate(-7.61)" opacity="0.08"></rect><rect x="242.52" y="146.67" width="5.67" height="13.79" transform="translate(-18.17 33.84) rotate(-7.61)" fill="#24285b"></rect><path d="M240,116.77a12.1,12.1,0,1,0,13.6,10.39A12.1,12.1,0,0,0,240,116.77Zm2.74,20.46a8.55,8.55,0,1,1,7.33-9.6A8.56,8.56,0,0,1,242.78,137.23Z" fill="#ffd200"></path><circle cx="241.67" cy="128.8" r="8.59" fill="#fff"></circle><path d="M161,176.33a6.18,6.18,0,0,1,11.25-1.68,141.62,141.62,0,0,1,12,24.39c7.15,19.06,42.21,6.49,55.15-37.95l7.38,4.59s-10.18,57.72-51.16,59.84c0,0-25.58,5.18-33.35-26.21,0,0-2-5.91-2.12-9.25l-.54-3.76a31.69,31.69,0,0,1,1.32-9.87Z" fill="#68e1fd"></path><path d="M161,176.33a6.18,6.18,0,0,1,11.25-1.68,141.62,141.62,0,0,1,12,24.39c7.15,19.06,42.21,6.49,55.15-37.95l7.38,4.59s-10.18,57.72-51.16,59.84c0,0-25.58,5.18-33.35-26.21,0,0-2-5.91-2.12-9.25l-.54-3.76a31.69,31.69,0,0,1,1.32-9.87Z" fill="#fff" opacity="0.39"></path><path d="M241.27,162.21s.75-9.51,4.67-9.49,13.13,7.06-1.09,11.71Z" fill="#f4a28c"></path><path d="M343.49,89.6a6.76,6.76,0,0,0-6.76-6.76,6.59,6.59,0,0,0-1.09.09,9.1,9.1,0,0,0-8-4.8l-.33,0a10.82,10.82,0,1,0-21,0l-.33,0a9.12,9.12,0,1,0,0,18.23h31.63V96.3A6.77,6.77,0,0,0,343.49,89.6Z" fill="#e6e6e6"></path><path d="M80.7,156.51a5.8,5.8,0,0,0-5.8-5.8,7,7,0,0,0-.93.08,7.81,7.81,0,0,0-6.89-4.11H66.8a9.28,9.28,0,1,0-18,0h-.28a7.82,7.82,0,1,0,0,15.63H75.65v-.05A5.81,5.81,0,0,0,80.7,156.51Z" fill="#e6e6e6"></path></svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300" width="406" height="306" class="illustration styles_illustrationTablet__1DWOa"><path d="M217.37,104.48s23.73,6,23.9,25.71-10.53,54.05,4.74,56.86,24.4-39.66,24.4-39.66l10.88,4.38s-11.58,72.57-51.6,60.59S217.37,104.48,217.37,104.48Z" fill="#68e1fd"></path><path d="M217.37,104.48s23.73,6,23.9,25.71-10.53,54.05,4.74,56.86,24.4-39.66,24.4-39.66l10.88,4.38s-11.58,72.57-51.6,60.59S217.37,104.48,217.37,104.48Z" fill="#fff" opacity="0.44"></path><ellipse cx="202.28" cy="230.74" rx="157.96" ry="14.45" fill="#e6e6e6" opacity="0.3"></ellipse><path d="M76.51,213.73S66.25,210.93,64,201.39c0,0,15.89-3.21,16.34,13.19Z" fill="#68e1fd" opacity="0.58"></path><path d="M77.76,212.72s-7.16-11.33-.85-21.92c0,0,12.07,7.67,6.71,21.94Z" fill="#68e1fd" opacity="0.73"></path><path d="M79.61,212.72s3.79-12,15.23-14.22c0,0,2.14,7.76-7.41,14.26Z" fill="#68e1fd"></path><polygon points="72.17 212.46 74.25 226.68 87.34 226.73 89.27 212.53 72.17 212.46" fill="#24285b"></polygon><polygon points="196.01 72.21 188.78 97.7 203.12 100.69 202.62 80.94 196.01 72.21" fill="#f4a28c"></polygon><path d="M202.92,85.25a9.57,9.57,0,0,1-4.37-3.36s-.37,4.84,4.35,10.22Z" fill="#ce8172" opacity="0.31"></path><path d="M188.78,97.71l8.5,1.76s38.9,4.19,40.48,26.15-20.39,78.06-20.39,78.06H158.43S111.2,91.9,188.78,97.71Z" fill="#68e1fd"></path><path d="M183.69,118.05s4.75,13.72-7.71,22.67-6.38,42.65,7.26,48.09-8.53,17.08-18,12.31-10.77-8-10.77-8-8.77-25.35-9.7-41.52S183.69,118.05,183.69,118.05Z" opacity="0.09"></path><path d="M158.43,203.68s-33.18-11.8-45.29-6.76-5.26,28.52,34.23,29.68,97.93,7.61,109.52-6.67S224.77,198,158.43,203.68Z" fill="#24285b"></path><path d="M183.69,118.05c0-12.07-12.23-20.32-23.71-16.55-10,3.27-22.15,9.34-29.54,20.44-14.22,21.32-46.7,83.65,35.75,86.05l2.42-9.18S119.12,185.12,141,156.16C158,133.64,183.74,135.15,183.69,118.05Z" fill="#68e1fd"></path><path d="M183.69,118.05c0-12.07-12.23-20.32-23.71-16.55-10,3.27-22.15,9.34-29.54,20.44-14.22,21.32-46.7,83.65,35.75,86.05l2.42-9.18S119.12,185.12,141,156.16C158,133.64,183.74,135.15,183.69,118.05Z" fill="#fff" opacity="0.44"></path><polygon points="166.51 209.87 207.52 209.87 217.37 165.64 160.19 165.64 166.51 209.87" fill="#ffd200"></polygon><path d="M273,148.41s.62-10.5,4.83-13.49,3.51,4.57,3.51,4.57,4.21-4.92,7.72-2.63-7.72,14.91-7.72,14.91Z" fill="#f4a28c"></path><rect x="268.45" y="97.1" width="37.48" height="48.09" transform="translate(42.89 -72.43) rotate(15.52)" fill="#e6e6e6"></rect><rect x="272.34" y="120.86" width="24.78" height="18.25" transform="translate(45.16 -71.45) rotate(15.52)" fill="#c1c1c1"></rect><rect x="295.14" y="106.58" width="7.04" height="12.28" transform="translate(41.05 -75.8) rotate(15.52)" fill="#c1c1c1" opacity="0.24"></rect><path d="M210.86,73s-.72,8.06-3,13.1a4.07,4.07,0,0,1-5.4,2c-2.52-1.18-5.59-3.51-5.72-7.87l-1.15-7.38a7.27,7.27,0,0,1,4.51-7.08C205.17,63.3,211.54,68.07,210.86,73Z" fill="#f4a28c"></path><path d="M208.83,72.93a31.48,31.48,0,0,1-7.24-1.87,6.75,6.75,0,0,1-1.3,7.29,5.48,5.48,0,0,1-6.91,1l2-10.21a8.23,8.23,0,0,1,5.39-6.5,29.4,29.4,0,0,1,3.71-1.06c3.16-.66,7.12,2.07,10.11.55a2,2,0,0,1,2.83,1.8c-.1,3.19-1.52,8-6,8.95A7.56,7.56,0,0,1,208.83,72.93Z" fill="#24285b"></path><path d="M201.19,78.27s.48-3.08-1.86-3.25-3.08,4.26,0,5.23Z" fill="#f4a28c"></path><path d="M210.14,78l1.68,3.47a1.29,1.29,0,0,1-1.16,1.85l-3.14,0Z" fill="#f4a28c"></path><circle cx="187.77" cy="184.73" r="4.08" fill="#fff"></circle><path d="M160.19,219.08s-16.73,7.25-12.32,11.66,15.71-3.47,15.71-3.47Z" fill="#68e1fd"></path><path d="M212.54,220.92s16.73,7.24,12.31,11.65-15.71-3.47-15.71-3.47Z" fill="#68e1fd"></path><circle cx="285.11" cy="108.25" r="6.32" fill="#c1c1c1"></circle><circle cx="286.69" cy="127.03" r="2.02" fill="#e6e6e6"></circle><polygon points="272.95 133.26 281.29 125.01 283.58 133.98 289.69 130.63 292.7 138.87 272.95 133.26" fill="#e6e6e6"></polygon><rect x="275.47" y="187.75" width="39.65" height="39.66" fill="#c1c1c1"></rect><rect x="298.13" y="187.75" width="39.65" height="39.66" fill="#e6e6e6"></rect></svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 10 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.8 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.7 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.7 KiB

BIN
static/img/team_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

BIN
static/img/team_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

BIN
static/img/team_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

BIN
static/img/team_4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 KiB

BIN
static/img/team_5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

BIN
static/img/team_6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

1
static/js/script.min.js vendored Normal file
View File

@ -0,0 +1 @@
!function(){"use strict";var e=document.querySelector("#mainNav");if(e){var n=function(){(void 0!==window.pageYOffset?window.pageYOffset:(document.documentElement||document.body.parentNode||document.body).scrollTop)>100?e.classList.add("navbar-shrink"):e.classList.remove("navbar-shrink")};n(),document.addEventListener("scroll",n)}}();

View File

@ -0,0 +1,26 @@
(function() {
"use strict"; // Start of use strict
var mainNav = document.querySelector('#mainNav');
if (mainNav) {
// Collapse Navbar
var collapseNavbar = function() {
var scrollTop = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
if (scrollTop > 100) {
mainNav.classList.add("navbar-shrink");
} else {
mainNav.classList.remove("navbar-shrink");
}
};
// Collapse now if page is not at top
collapseNavbar();
// Collapse the navbar when page is scrolled
document.addEventListener("scroll", collapseNavbar);
}
})(); // End of use strict

BIN
static/logo/.DS_Store vendored

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 204 KiB

108
templates/dashboard.html Normal file
View File

@ -0,0 +1,108 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>Dashboard - SMC</title>
<link rel="stylesheet" href="static/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800&amp;display=swap">
</head>
<body>
<nav class="navbar navbar-light navbar-expand-md fixed-top navbar-shrink py-3" id="mainNav">
<div class="container"><a class="navbar-brand d-flex align-items-center" href="/"><img src="static/img/brands/logo.png" style="width: 64px;"></a><button data-bs-toggle="collapse" class="navbar-toggler" data-bs-target="#navcol-1"><span class="visually-hidden">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div class="collapse navbar-collapse" id="navcol-1">
<ul class="navbar-nav mx-auto"></ul>
<ul class="navbar-nav">
<li class="nav-item"><a class="disabled nav-link">Home</a></li>
<li class="nav-item"><a class="nav-link active" href="">My teams</a></li>
<li class="nav-item"><a class="nav-link active" href="webcal://somycal.com/calendar/{{userId}}.ics">Sync. this device</a></li>
</ul>
</div><a class="btn btn-primary shadow" role="button" href="/logout">Logout</a>
</div>
</nav>
<header class="pt-5">
<div class="container pt-4 pt-xl-5">
<div class="row pt-5">
<div class="col-md-8 text-center text-md-start mx-auto">
<div class="text-center">
<h1 class="display-4 fw-bold mb-5">Welcome to your&nbsp;<span class="underline">dashboard</span>.</h1>
</div>
</div>
<div class="col-12 col-lg-10 mx-auto">
<div class="text-center position-relative"></div>
</div>
</div>
</div>
</header>
<section>
<div class="container py-4 py-xl-5">
<div class="row gy-4 row-cols-1 row-cols-md-2 row-cols-lg-3">
{% for team in userTeams %}
<div class="col">
<div class="card border-light border-1 d-flex justify-content-center p-4">
<div class="card-body">
<div class="d-flex justify-content-center align-items-center justify-content-md-start"><img src="{{ getTeamLogo(team.idTeam) }}" style="width: 100px;">
<h5 class="fw-bold mb-0 ms-2">{{ getTeamName(team.idTeam) }}</h5>
</div>
<div></div>
</div><a class="btn btn-primary" role="button" href="/del/{{ team.idTeam }}">Remove from calendar</a>
</div>
</div>
{% endfor %}
{% for team in otherTeams %}
<div class="col">
<div class="card border-light border-1 d-flex justify-content-center p-4">
<div class="card-body">
<div class="d-flex justify-content-center align-items-center justify-content-md-start"><img src="{{ getTeamLogo(team) }}" style="width: 100px;">
<h5 class="fw-bold mb-0 ms-2">{{ getTeamName(team) }}</h5>
</div>
<div></div>
</div><a class="btn btn-warning" role="button" href="/add/{{ team }}">Add to calendar</a>
</div>
</div>
{% endfor %}
</div>
</div>
</section>
<section class="py-4 py-xl-5 mb-5">
<div class="container">
<div class="row mb-2">
<div class="col-md-8 col-xl-6 text-center mx-auto">
<h2 class="display-6 fw-bold mb-5"><span class="pb-3 underline">Suggestions ?</span></h2>
<p class="text-muted mb-5">Send us your suggestions via our social networks </p>
</div>
</div>
</div>
</section>
<footer>
<div class="container py-4 py-lg-5">
<hr>
<div class="text-muted d-flex justify-content-between align-items-center pt-3">
<p class="mb-0">Copyright © 2024 So My Calendar</p>
<ul class="list-inline mb-0">
<li class="list-inline-item">
<a href="https://twitter.com/SoMy76ers" target="_blank">
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" class="bi bi-twitter">
<path d="M5.026 15c6.038 0 9.341-5.003 9.341-9.334 0-.14 0-.282-.006-.422A6.685 6.685 0 0 0 16 3.542a6.658 6.658 0 0 1-1.889.518 3.301 3.301 0 0 0 1.447-1.817 6.533 6.533 0 0 1-2.087.793A3.286 3.286 0 0 0 7.875 6.03a9.325 9.325 0 0 1-6.767-3.429 3.289 3.289 0 0 0 1.018 4.382A3.323 3.323 0 0 1 .64 6.575v.045a3.288 3.288 0 0 0 2.632 3.218 3.203 3.203 0 0 1-.865.115 3.23 3.23 0 0 1-.614-.057 3.283 3.283 0 0 0 3.067 2.277A6.588 6.588 0 0 1 .78 13.58a6.32 6.32 0 0 1-.78-.045A9.344 9.344 0 0 0 5.026 15z"></path>
</svg>
</a>
</li>
<li class="list-inline-item">
<a href="https://www.instagram.com/somymedia/" target="_blank">
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" class="bi bi-instagram">
<path d="M8 0C5.829 0 5.556.01 4.703.048 3.85.088 3.269.222 2.76.42a3.917 3.917 0 0 0-1.417.923A3.927 3.927 0 0 0 .42 2.76C.222 3.268.087 3.85.048 4.7.01 5.555 0 5.827 0 8.001c0 2.172.01 2.444.048 3.297.04.852.174 1.433.372 1.942.205.526.478.972.923 1.417.444.445.89.719 1.416.923.51.198 1.09.333 1.942.372C5.555 15.99 5.827 16 8 16s2.444-.01 3.298-.048c.851-.04 1.434-.174 1.943-.372a3.916 3.916 0 0 0 1.416-.923c.445-.445.718-.891.923-1.417.197-.509.332-1.09.372-1.942C15.99 10.445 16 10.173 16 8s-.01-2.445-.048-3.299c-.04-.851-.175-1.433-.372-1.941a3.926 3.926 0 0 0-.923-1.417A3.911 3.911 0 0 0 13.24.42c-.51-.198-1.092-.333-1.943-.372C10.443.01 10.172 0 7.998 0h.003zm-.717 1.442h.718c2.136 0 2.389.007 3.232.046.78.035 1.204.166 1.486.275.373.145.64.319.92.599.28.28.453.546.598.92.11.281.24.705.275 1.485.039.843.047 1.096.047 3.231s-.008 2.389-.047 3.232c-.035.78-.166 1.203-.275 1.485a2.47 2.47 0 0 1-.599.919c-.28.28-.546.453-.92.598-.28.11-.704.24-1.485.276-.843.038-1.096.047-3.232.047s-2.39-.009-3.233-.047c-.78-.036-1.203-.166-1.485-.276a2.478 2.478 0 0 1-.92-.598 2.48 2.48 0 0 1-.6-.92c-.109-.281-.24-.705-.275-1.485-.038-.843-.046-1.096-.046-3.233 0-2.136.008-2.388.046-3.231.036-.78.166-1.204.276-1.486.145-.373.319-.64.599-.92.28-.28.546-.453.92-.598.282-.11.705-.24 1.485-.276.738-.034 1.024-.044 2.515-.045v.002zm4.988 1.328a.96.96 0 1 0 0 1.92.96.96 0 0 0 0-1.92zm-4.27 1.122a4.109 4.109 0 1 0 0 8.217 4.109 4.109 0 0 0 0-8.217zm0 1.441a2.667 2.667 0 1 1 0 5.334 2.667 2.667 0 0 1 0-5.334z"></path>
</svg>
</a>
</li>
</ul>
</div>
</div>
</footer>
<script src="static/bootstrap/js/bootstrap.min.js"></script>
<script src="static/js/script.min.js"></script>
</body>
</html>

View File

@ -1,147 +1,139 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>Calendar settings</title> <title>Welcome to SMC</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"> <link rel="stylesheet" href="static/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous"> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800&amp;display=swap">
<style>
body {
background-color: #ffffff;
color: #000000;
margin: 0;
padding: 0;
}
.header {
background: rgba(255, 255, 255, 0.8);
padding: 20px;
display: flex;
justify-content: space-between;
align-items: center;
}
.logo {
width: 150px;
height: auto;
}
.header-links {
display: flex;
align-items: center;
}
.header-links a {
color: #000000;
margin-right: 20px;
text-decoration: none;
font-weight: bold;
}
.header-links a:hover {
color: #ffffff;
}
.container {
background: linear-gradient(rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.8)), grey;
padding: 20px;
border-radius: 10px;
margin-top: 20px;
}
.list-group-item {
display: flex;
justify-content: space-between;
align-items: center;
background-color: #343434;
color: #ffffff;
border: none;
margin-bottom: 5px;
}
.button-group a {
margin-right: 5px;
}
.team-logo {
width: 75px;
height: auto;
margin-right: 10px;
}
.list-group-item.d-none {
display: none !important;
}
</style>
</head> </head>
<body> <body>
<nav class="navbar navbar-expand-lg navbar-light bg-light"> <nav class="navbar navbar-light navbar-expand-md fixed-top navbar-shrink py-3" id="mainNav">
<a class="navbar-brand" href="#"> <div class="container"><a class="navbar-brand d-flex align-items-center" href="/"><a class="navbar-brand d-flex align-items-center" href="/"><img src="static/img/brands/logo.png" style="width: 64px;"></a><button data-bs-toggle="collapse" class="navbar-toggler" data-bs-target="#navcol-1"><span class="visually-hidden">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<img src="static/logo/logo.png" alt="Logo SC" class="logo"> <div class="collapse navbar-collapse" id="navcol-1">
<ul class="navbar-nav mx-auto"></ul>
<ul class="navbar-nav">
<li class="nav-item"><a class="nav-link active" href="">Home</a></li>
<li class="nav-item"><a class="disabled nav-link" href="">My teams</a></li>
<li class="nav-item"><a class="disabled nav-link" href="#">Sync. this device</a></li>
</ul>
</div><a class="btn btn-primary shadow" role="button" href="/login/google">Dashboard</a>
</div>
</nav>
<section class="py-5 mt-5">
<div class="container py-4 py-xl-5">
<div class="row gy-4 gy-md-0">
<div class="col-md-6 text-center text-md-start d-flex d-sm-flex d-md-flex justify-content-center align-items-center justify-content-md-start align-items-md-center justify-content-xl-center">
<div>
<h1 class="display-6 fw-bold mb-4">Your favourite teams, on a single&nbsp;<span class="underline">platform</span>.</h1>
<p class="my-4">Synchronize your favorite teams' calendars in just a few clicks from a simple, intuitive interface</p><a class="btn btn-outline-primary btn-lg" role="button" href="/login/google">Continue with Google</a>
</div>
</div>
<div class="col-md-6">
<div><img class="rounded img-fluid w-100 fit-cover" style="min-height: 300px;" src="static/img/illustrations/web-development.svg"></div>
</div>
</div>
<div class="text-center mt-5">
<p class="mb-4" style="font-size: 1.6rem;">Currently lists more than&nbsp;<span class="bg-warning p-1"><strong>2531</strong></span>&nbsp;events</p>
</div>
</div>
</section>
<section>
<div class="container py-4 py-xl-5">
<div class="row mb-5">
<div class="col-md-8 col-xl-6">
<h3 class="display-6 fw-bold pb-4 mb-4">Available&nbsp;<span class="underline">features</span></h3>
</div>
<div class="col-md-8 col-xl-6 pt-4">
<p class="text-muted">Here is a quick list of currently available features</p>
</div>
</div>
<div class="row gy-4 row-cols-1 row-cols-md-2 row-cols-xl-3">
<div class="col">
<div class="card border-light border-1 d-flex justify-content-center p-4">
<div class="card-body">
<div>
<div class="bs-icon-lg bs-icon-rounded bs-icon-secondary d-flex flex-shrink-0 justify-content-center align-items-center d-inline-block mb-4 bs-icon"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icon-tabler-rss">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<circle cx="5" cy="19" r="1"></circle>
<path d="M4 4a16 16 0 0 1 16 16"></path>
<path d="M4 11a9 9 0 0 1 9 9"></path>
</svg></div>
<h4 class="fw-bold">Real time sync</h4>
<p class="text-muted">Real-time synchronization with official APIs</p>
</div>
</div>
</div>
</div>
<div class="col">
<div class="card border-light border-1 d-flex justify-content-center p-4">
<div class="card-body">
<div>
<div class="bs-icon-lg bs-icon-rounded bs-icon-secondary d-flex flex-shrink-0 justify-content-center align-items-center d-inline-block mb-4 bs-icon"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icon-tabler-ruler">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M5 4h14a1 1 0 0 1 1 1v5a1 1 0 0 1 -1 1h-7a1 1 0 0 0 -1 1v7a1 1 0 0 1 -1 1h-5a1 1 0 0 1 -1 -1v-14a1 1 0 0 1 1 -1"></path>
<line x1="4" y1="8" x2="6" y2="8"></line>
<line x1="4" y1="12" x2="7" y2="12"></line>
<line x1="4" y1="16" x2="6" y2="16"></line>
<line x1="8" y1="4" x2="8" y2="6"></line>
<polyline points="12 4 12 7 "></polyline>
<polyline points="16 4 16 6 "></polyline>
</svg></div>
<h4 class="fw-bold">Quick changes</h4>
<p class="text-muted">Modify your subscriptions in just a few clicks</p>
</div>
</div>
</div>
</div>
<div class="col">
<div class="card border-light border-1 d-flex justify-content-center p-4">
<div class="card-body">
<div>
<div class="bs-icon-lg bs-icon-rounded bs-icon-secondary d-flex flex-shrink-0 justify-content-center align-items-center d-inline-block mb-4 bs-icon"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icon-tabler-friends">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<circle cx="7" cy="5" r="2"></circle>
<path d="M5 22v-5l-1-1v-4a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4l-1 1v5"></path>
<circle cx="17" cy="5" r="2"></circle>
<path d="M15 22v-4h-2l2 -6a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1l2 6h-2v4"></path>
</svg></div>
<h4 class="fw-bold">Friend system</h4>
<p class="text-muted">Share your next matches with your friends</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<footer>
<div class="container py-4 py-lg-5">
<hr>
<div class="text-muted d-flex justify-content-between align-items-center pt-3">
<p class="mb-0">Copyright © 2024 So My Calendar</p>
<ul class="list-inline mb-0">
<li class="list-inline-item">
<a href="https://twitter.com/SoMy76ers" target="_blank">
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" class="bi bi-twitter">
<path d="M5.026 15c6.038 0 9.341-5.003 9.341-9.334 0-.14 0-.282-.006-.422A6.685 6.685 0 0 0 16 3.542a6.658 6.658 0 0 1-1.889.518 3.301 3.301 0 0 0 1.447-1.817 6.533 6.533 0 0 1-2.087.793A3.286 3.286 0 0 0 7.875 6.03a9.325 9.325 0 0 1-6.767-3.429 3.289 3.289 0 0 0 1.018 4.382A3.323 3.323 0 0 1 .64 6.575v.045a3.288 3.288 0 0 0 2.632 3.218 3.203 3.203 0 0 1-.865.115 3.23 3.23 0 0 1-.614-.057 3.283 3.283 0 0 0 3.067 2.277A6.588 6.588 0 0 1 .78 13.58a6.32 6.32 0 0 1-.78-.045A9.344 9.344 0 0 0 5.026 15z"></path>
</svg>
</a> </a>
<div class="navbar-nav header-links ml-auto">
<a class="nav-item nav-link" href="#">Accueil</a>
<a class="nav-item nav-link" href="webcal://somycal.com/calendar/{{userId}}.ics" target="_blank">S'abonner au calendrier</a>
<a class="nav-item nav-link" href="/logout">Déconnexion</a>
</div>
</nav>
<div class="container">
<div class="d-flex align-items-center mb-4">
<h2 class="mr-2">Equipes:</h2>&nbsp;&nbsp;&nbsp;&nbsp;
<input type="text" id="searchInput" class="form-control" oninput="filterTeams()">
</div>
<div class="row" id="teamList">
{% for team in userTeams %}
<div class="col-md-4 mb-3">
<li class="list-group-item">
<img src="{{ getTeamLogo(team.idTeam) }}" alt="Logo de l'équipe" class="team-logo">
{{ getTeamName(team.idTeam) }}
<div class="button-group">
<a class="btn btn-danger" href="/del/{{ team.idTeam }}">Retirer</a>
</div>
</li> </li>
</div> <li class="list-inline-item">
{% endfor %} <a href="https://www.instagram.com/somymedia/" target="_blank">
{% for team in otherTeams %} <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" class="bi bi-instagram">
<div class="col-md-4 mb-3"> <path d="M8 0C5.829 0 5.556.01 4.703.048 3.85.088 3.269.222 2.76.42a3.917 3.917 0 0 0-1.417.923A3.927 3.927 0 0 0 .42 2.76C.222 3.268.087 3.85.048 4.7.01 5.555 0 5.827 0 8.001c0 2.172.01 2.444.048 3.297.04.852.174 1.433.372 1.942.205.526.478.972.923 1.417.444.445.89.719 1.416.923.51.198 1.09.333 1.942.372C5.555 15.99 5.827 16 8 16s2.444-.01 3.298-.048c.851-.04 1.434-.174 1.943-.372a3.916 3.916 0 0 0 1.416-.923c.445-.445.718-.891.923-1.417.197-.509.332-1.09.372-1.942C15.99 10.445 16 10.173 16 8s-.01-2.445-.048-3.299c-.04-.851-.175-1.433-.372-1.941a3.926 3.926 0 0 0-.923-1.417A3.911 3.911 0 0 0 13.24.42c-.51-.198-1.092-.333-1.943-.372C10.443.01 10.172 0 7.998 0h.003zm-.717 1.442h.718c2.136 0 2.389.007 3.232.046.78.035 1.204.166 1.486.275.373.145.64.319.92.599.28.28.453.546.598.92.11.281.24.705.275 1.485.039.843.047 1.096.047 3.231s-.008 2.389-.047 3.232c-.035.78-.166 1.203-.275 1.485a2.47 2.47 0 0 1-.599.919c-.28.28-.546.453-.92.598-.28.11-.704.24-1.485.276-.843.038-1.096.047-3.232.047s-2.39-.009-3.233-.047c-.78-.036-1.203-.166-1.485-.276a2.478 2.478 0 0 1-.92-.598 2.48 2.48 0 0 1-.6-.92c-.109-.281-.24-.705-.275-1.485-.038-.843-.046-1.096-.046-3.233 0-2.136.008-2.388.046-3.231.036-.78.166-1.204.276-1.486.145-.373.319-.64.599-.92.28-.28.546-.453.92-.598.282-.11.705-.24 1.485-.276.738-.034 1.024-.044 2.515-.045v.002zm4.988 1.328a.96.96 0 1 0 0 1.92.96.96 0 0 0 0-1.92zm-4.27 1.122a4.109 4.109 0 1 0 0 8.217 4.109 4.109 0 0 0 0-8.217zm0 1.441a2.667 2.667 0 1 1 0 5.334 2.667 2.667 0 0 1 0-5.334z"></path>
<li class="list-group-item"> </svg>
<img src="{{ getTeamLogo(team) }}" alt="Logo de l'équipe" class="team-logo">
{{ getTeamName(team) }}
<div class="button-group">
<a class="btn btn-success" href="/add/{{ team }}">Ajouter</a>
</div>
</li>
</div>
{% endfor %}
</div>
</div>
<footer class="footer mt-auto py-3">
<div class="container text-center">
<a href="https://github.com/itsmrval/nba-calendar" target="_blank" class="ml-3 text-muted text-decoration-none">
<i class="fab fa-github"></i> &copy; 2023 Sport Calendar
</a> </a>
</li>
</ul>
</div> </div>
</footer> </div>
</footer>
<script src="static/bootstrap/js/bootstrap.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script> <script src="static/js/script.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<script>
function filterTeams() {
var input, filter, ul, li, a, i, txtValue;
input = document.getElementById("searchInput");
filter = input.value.toUpperCase();
ul = document.getElementById("teamList");
li = ul.getElementsByClassName("col-md-4");
for (i = 0; i < li.length; i++) {
a = li[i];
txtValue = a.textContent || a.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
a.classList.remove("d-none");
} else {
a.classList.add("d-none");
}
}
}
</script>
</body> </body>
</html> </html>

View File

@ -1,30 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<title>SportsCalendar</title> <!-- Add the title of the site here -->
</head>
<body>
<div class="container">
<div class="row justify-content-center align-items-center" style="height:100vh;">
<div class="col-md-4">
<div class="card">
<div class="card-body text-center">
<img src="static/logo/google.png" width="150px">
<h5 class="card-title">Login with Google</h5>
<p class="card-text">Click the button below to connect with Google</p>
<a href="/login/google" class="btn btn-danger btn-lg">Login with Google</a>
</div>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.10.2/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>