Merge branch 'main' into development

This commit is contained in:
2025-04-21 13:04:58 +02:00
4 changed files with 104 additions and 51 deletions

View File

@@ -1,24 +1,72 @@
# How to install
## Setting up your virtual environment # Installation Guide
### Creating virtual environment
## Setting Up Your Virtual Environment
### 1. Create a Virtual Environment
To begin, create a virtual environment using the following command:
```bash
python -m venv venv python -m venv venv
```
### Activating environment for package installation (windows) ### 2. Activate the Virtual Environment
For Windows, activate the virtual environment with:
```bash
.\venv\Scripts\activate.bat .\venv\Scripts\activate.bat
```
### Installing required packages ### 3. Install Required Packages
Once the environment is activated, install the necessary packages by running:
```bash
pip install -r requirements.txt pip install -r requirements.txt
```
## Setting up the database (in venv) ---
### Initialize database
## Setting Up the Database
### 1. Initialize the Database
To initialize the database, run the following command:
```bash
flask --app app.py db init flask --app app.py db init
```
### Migrate database ### 2. Migrate the Database
Migrate the database schema to the latest version with:
```bash
flask --app app.py db migrate flask --app app.py db migrate
```
### upgrade database ### 3. Upgrade the Database
Apply the migration to update the database with:
```bash
flask --app app.py db upgrade flask --app app.py db upgrade
```
# Development commands ---
#### Updating requirements.txt
pip freeze > requirements.txt ## Seeding the Database
To populate the database with a few sample users and services, run:
```bash
python seed.py
```
---
## Starting the Application
To start the application, run:
```bash
python app.py
```
---
# Development Commands
### Updating `requirements.txt`
To update the `requirements.txt` with the currently installed packages, use the following command:
```bash
pip freeze > requirements.txt
```
---

View File

@@ -9,7 +9,7 @@ app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///services.sqlite" app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///services.sqlite"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False # Wat is dit? app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False # Wat is dit?
app.config["SECRET_KEY"] = "bvjchsygvduycgsyugc" # Andere secret key app.config["SECRET_KEY"] = "bvjchsygvduycgsyugc" # Andere secret key
app.config["UPLOAD_FOLDER"] = r"application\static\icons" app.config["UPLOAD_FOLDER"] = os.path.join("application", "static", "icons")
# Ensure the upload folder exists # Ensure the upload folder exists
os.makedirs(app.config["UPLOAD_FOLDER"], exist_ok=True) # type: ignore os.makedirs(app.config["UPLOAD_FOLDER"], exist_ok=True) # type: ignore

View File

@@ -6,45 +6,41 @@
<div class="grid-container"> <div class="grid-container">
{% for service in services%} {% for service in services%}
<div class="bg-light container-xxl"> <div class="bg-light container-xxl">
<div class="row row-cols-3"> <div class="row">
<div class="col-sm-2" onclick="location.href='{{service.url}}';" style="cursor: pointer;"> <div class="col" onclick="location.href='{{service.url}}';" style="cursor: pointer;">
{{service["name"]}}
</div>
<div class="col-sm-3 dots dropdown">
<button class="btn btn-light py-0" type="button" id="threeDotDropdown" data-bs-toggle="dropdown" aria-expanded="false">
&#x22EE;
</button>
<ul class="dropdown-menu" aria-labelledby="threeDotDropdown">
<li>
<a class="dropdown-item" href="{{ url_for('dash.edit_service', service_id=service.id) }}">Edit</a>
</li>
<li>
<hr class="dropdown-divider">
</li>
<li>
<form action="{{ url_for('dash.delete_service', service_id=service.id) }}" method="POST" style="display:inline;">
<button style="color: red;" type="submit" class="dropdown-item">Delete</button>
</form>
</li>
</ul>
</div>
</div>
<div class="row">
<div class="col-sm-9" onclick="location.href='{{service.url}}';" style="cursor: pointer;">
<img class="fit-picture" src="{{ url_for('static', filename='icons/'+service['icon'])}}"> <img class="fit-picture" src="{{ url_for('static', filename='icons/'+service['icon'])}}">
</div> </div>
<div class="col-sm-10"> </div>
<div class="row"> <div class="row">
<div class="col-sm-10" onclick="location.href='{{service.url}}';" style="cursor: pointer;"> <div class="col url text-break" onclick="location.href='{{service.url}}';" style="cursor: pointer;">
{{service["name"]}} {{service["url"]}}
</div>
<div class="col-sm-2 dots dropdown">
<button class="btn btn-light py-0" type="button" id="threeDotDropdown" data-bs-toggle="dropdown"
aria-expanded="false">
&#x22EE;
</button>
<ul class="dropdown-menu" aria-labelledby="threeDotDropdown">
<li>
<a class="dropdown-item"
href="{{ url_for('dash.edit_service', service_id=service.id) }}">Edit</a>
</li>
<li>
<hr class="dropdown-divider">
</li>
<li>
<form action="{{ url_for('dash.delete_service', service_id=service.id) }}" method="POST"
style="display:inline;">
<button style="color: red;" type="submit" class="dropdown-item">Delete</button>
</form>
</li>
</ul>
</div>
</div>
<div class="row">
<div class="col" onclick="location.href='{{service.url}}';" style="cursor: pointer;">
{{service["url"]}}
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
{%endblock%} {%endblock%}

View File

@@ -6,26 +6,29 @@ body {
/* Dashboard page */ /* Dashboard page */
.grid-container { .grid-container {
display: grid; display: grid;
grid-template-columns: auto auto auto; grid-template-columns: auto auto auto auto auto;
gap: 20px; gap: 20px;
background-color: lightslategray; background-color: lightslategray;
padding-top: 20px; padding-top: 20px;
margin-left: 10%; margin-left: 10%;
margin-right: 10%; margin-right: 10%;
justify-content: center;
} }
.grid-container > div { .grid-container > div {
height: fit-content; height: fit-content;
width: 400px; width: 200px;
padding-top: 5px; padding-top: 5px;
padding-bottom: 5px; padding-bottom: 5px;
border: 2px solid black; border: 2px solid black;
border-radius: 10px; border-radius: 10px;
box-shadow: 5px 5px 10px black; box-shadow: 5px 5px 10px black;
font-weight: bold;
} }
.fit-picture { .fit-picture {
width: 45px; width: 175px;
margin-top: 5px; margin-top: 5px;
margin-bottom: 5px; margin-bottom: 5px;
border: 1px solid black; border: 1px solid black;
@@ -33,6 +36,12 @@ body {
box-shadow: 0px 0px 5px black; box-shadow: 0px 0px 5px black;
} }
.url {
font-weight: normal;
}
/* Login page */ /* Login page */
.form { .form {
display: block; display: block;