Consolidate repos
11
.gitignore
vendored
@@ -1,11 +1,10 @@
|
||||
# Python
|
||||
app/__pycache__/
|
||||
app/*/__pycache__/
|
||||
app/*.pyc
|
||||
backend/*/__pycache__/
|
||||
backend/*.pyc
|
||||
|
||||
# Logs
|
||||
app/logs/
|
||||
app/*.log
|
||||
backend/logs/
|
||||
backend/*.log
|
||||
|
||||
# Environment variables
|
||||
app/config/.env
|
||||
backend/config/.env
|
||||
@@ -8,7 +8,7 @@ RUN apt-get update && apt-get install -y pkg-config python3-dev default-libmysql
|
||||
WORKDIR /app
|
||||
|
||||
# Copy the current directory contents into the container at /app
|
||||
COPY app/ /app
|
||||
COPY backend/ /app
|
||||
|
||||
# Create a virtual environment and install dependencies
|
||||
RUN python -m venv /venv
|
||||
@@ -20,7 +20,6 @@ RUN pip install --no-cache-dir -r requirements.txt
|
||||
EXPOSE 8000
|
||||
|
||||
# Define environment variable
|
||||
#ENV NAME World
|
||||
ENV DB_HOST=""
|
||||
ENV DB_PORT=3306
|
||||
ENV DB_USER=""
|
||||
16
Dockerfile_frontend
Normal file
@@ -0,0 +1,16 @@
|
||||
# Use an official Nginx image as a base image
|
||||
FROM nginx:latest
|
||||
|
||||
# Set the working directory to /app
|
||||
WORKDIR /app
|
||||
|
||||
# Copy the PHP files into the container
|
||||
COPY frontend/ /app
|
||||
|
||||
# Copy the Nginx configuration file
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
# Expose port 80 to the outside world
|
||||
EXPOSE 80
|
||||
|
||||
# Define environment variable
|
||||
@@ -1,9 +1,21 @@
|
||||
version: '3'
|
||||
services:
|
||||
gearguardian-frontend:
|
||||
image: gearguardian-frontend:latest
|
||||
volumes:
|
||||
- ./app:/app
|
||||
- ./nginx.conf:/etc/nginx/conf.d/default.conf
|
||||
ports:
|
||||
- "8080:80"
|
||||
networks:
|
||||
- frontend_network
|
||||
- backend_network
|
||||
restart: unless-stopped
|
||||
|
||||
# API logic
|
||||
gearguardian-api:
|
||||
container_name: gearguardian-api
|
||||
image: your-image-name
|
||||
gearguardian-backend:
|
||||
container_name: gearguardian-backend
|
||||
image: gearguardian-backend:latest
|
||||
environment:
|
||||
- DB_HOST=<change me> #required
|
||||
- DB_PORT=3306 #optional - will use port 3306 by default
|
||||
@@ -85,4 +97,6 @@ services:
|
||||
|
||||
networks:
|
||||
backend_network:
|
||||
driver: bridge
|
||||
frontend_network:
|
||||
driver: bridge
|
||||
755
frontend/activities/activity.php
Normal file
@@ -0,0 +1,755 @@
|
||||
<?php
|
||||
if(!isset($_SESSION)){
|
||||
session_start();
|
||||
}
|
||||
|
||||
require_once $_SERVER['DOCUMENT_ROOT']."/inc/sqlFunctions.php";
|
||||
|
||||
$page="activity";
|
||||
$activity = [];
|
||||
$addGearToActivity = -9000;
|
||||
$editGearActivity = -9000;
|
||||
$deleteGearActivity = -9000;
|
||||
$deleteActivity = -9000;
|
||||
|
||||
if(!isLogged()){
|
||||
header("Location: ../login.php");
|
||||
}
|
||||
|
||||
if(!isTokenValid($_SESSION["token"])){
|
||||
header("Location: ../logout.php?sessionExpired=1");
|
||||
}
|
||||
|
||||
if(!isset($_GET["activityID"])){
|
||||
header("Location: ../index.php?invalidActivity=1");
|
||||
}
|
||||
|
||||
// Load the language file based on the user's preferred language
|
||||
switch ($_SESSION["preferred_language"]) {
|
||||
case 'en':
|
||||
$translationsActivitiesActivity = include $_SERVER['DOCUMENT_ROOT'].'/lang/activities/en.php';
|
||||
break;
|
||||
case 'pt':
|
||||
$translationsActivitiesActivity = include $_SERVER['DOCUMENT_ROOT'].'/lang/activities/pt.php';
|
||||
break;
|
||||
// ...
|
||||
default:
|
||||
$translationsActivitiesActivity = include $_SERVER['DOCUMENT_ROOT'].'/lang/activities/en.php';
|
||||
|
||||
}
|
||||
|
||||
/* Add gear to activity action */
|
||||
if(isset($_GET["addGearToActivity"]) && $_GET["addGearToActivity"] == 1){
|
||||
$addGearToActivity = addGearToActivity($_GET["activityID"], $_POST["gearIDAdd"]);
|
||||
}
|
||||
|
||||
/* Edit activity gear */
|
||||
if(isset($_GET["editGearActivity"]) && $_GET["editGearActivity"] == 1){
|
||||
$editGearActivity = addGearToActivity($_GET["activityID"], $_POST["gearIDEdit"]);
|
||||
}
|
||||
|
||||
/* Delete activity gear */
|
||||
if(isset($_GET["deleteGearActivity"]) && $_GET["deleteGearActivity"] == 1){
|
||||
$deleteGearActivity = unsetActivityGear($_GET["activityID"]);
|
||||
}
|
||||
|
||||
/* Delete activity */
|
||||
if(isset($_GET["deleteActivity"]) && $_GET["deleteActivity"] == 1){
|
||||
$deleteActivity = deleteActivity($_GET["activityID"]);
|
||||
if($deleteActivity == 0){
|
||||
header("Location: ../index.php?deleteActivity=1");
|
||||
}
|
||||
}
|
||||
|
||||
$activity = getActivityFromId($_GET["activityID"]);
|
||||
if ($activity == NULL){
|
||||
header("Location: ../index.php?invalidActivity=1");
|
||||
}
|
||||
|
||||
// HR data for activity
|
||||
$hrData = [];
|
||||
$cadData = [];
|
||||
$powerData = [];
|
||||
$eleData = [];
|
||||
$velData = [];
|
||||
$paceData = [];
|
||||
foreach ($activity[0]['waypoints'] as $waypoint) {
|
||||
$hrData[] = $waypoint['hr'];
|
||||
$cadData[] = $waypoint['cad'];
|
||||
$powerData[] = $waypoint['power'];
|
||||
$eleData[] = $waypoint['ele'];
|
||||
$velData[] = (float)number_format(($waypoint['vel']*3.6),0);
|
||||
if($activity[0]["activity_type"] == 1 || $activity[0]["activity_type"] == 2 || $activity[0]["activity_type"] == 3){
|
||||
if($waypoint['pace'] == 0 || $waypoint['pace'] == null){
|
||||
$paceData[] = 0;
|
||||
}else{
|
||||
$paceData[] = ($waypoint["pace"] * 1000) / 60;
|
||||
}
|
||||
}else{
|
||||
if($activity[0]["activity_type"] == 9){
|
||||
if($waypoint['pace'] == 0 || $waypoint['pace'] == null){
|
||||
$paceData[] = 0;
|
||||
}else{
|
||||
$paceData[] = ($waypoint["pace"] * 100) / 60;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$activityUser = getUserFromId($activity[0]['user_id']);
|
||||
|
||||
if($activity[0]["gear_id"] != null){
|
||||
$activityGear = getGearFromId($activity[0]["gear_id"]);
|
||||
}
|
||||
|
||||
if($activity[0]["activity_type"] == 1 || $activity[0]["activity_type"] == 2 || $activity[0]["activity_type"] == 3){
|
||||
$activityGearOptions = getGearForRunning();
|
||||
}else{
|
||||
if($activity[0]["activity_type"] == 4 || $activity[0]["activity_type"] == 5 || $activity[0]["activity_type"] == 6 || $activity[0]["activity_type"] == 7 || $activity[0]["activity_type"] == 8){
|
||||
$activityGearOptions = getGearForCycling();
|
||||
}else{
|
||||
if($activity[0]["activity_type"] == 9){
|
||||
$activityGearOptions = getGearForSwimming();
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<?php require_once $_SERVER['DOCUMENT_ROOT']."/inc/Template-Top.php" ?>
|
||||
|
||||
<div class="container mt-4">
|
||||
<!-- Error banners -->
|
||||
<?php if($addGearToActivity == -1 || $addGearToActivity == -2 || $editGearActivity == -1 || $editGearActivity == -2 || $deleteGearActivity == -1 || $deleteGearActivity == -2 || $deleteActivity == -1 || $deleteActivity == -2){ ?>
|
||||
<div class="alert alert-danger alert-dismissible d-flex align-items-center" role="alert">
|
||||
<i class="fa-solid fa-circle-exclamation me-1"></i>
|
||||
<div>
|
||||
<?php if($addGearToActivity == -1 || $editGearActivity == -1 || $deleteActivity == -1){ ?>
|
||||
API ERROR | <?php echo $translationsActivitiesActivity['activity_addEditGear_API_error_-1']; ?> (-1).
|
||||
<?php }else{ ?>
|
||||
<?php if($addGearToActivity == -2 || $editGearActivity == -2 || $deleteActivity == -2){ ?>
|
||||
API ERROR | <?php echo $translationsActivitiesActivity['activity_addEditGear_API_error_-2']; ?> (-2).
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<!-- Info banners -->
|
||||
|
||||
<!-- Success banners -->
|
||||
<?php if($addGearToActivity == 0 || $editGearActivity == 0 || $deleteGearActivity == 0){ ?>
|
||||
<div class="alert alert-success alert-dismissible d-flex align-items-center" role="alert">
|
||||
<div>
|
||||
<i class="fa-regular fa-circle-check me-1"></i>
|
||||
<?php if($addGearToActivity == 0){ ?>
|
||||
<?php echo $translationsActivitiesActivity['activity_success_gearAdded']; ?>
|
||||
<?php }else{ ?>
|
||||
<?php if($editGearActivity == 0){ ?>
|
||||
<?php echo $translationsActivitiesActivity['activity_success_gearEdited']; ?>
|
||||
<?php }else{ ?>
|
||||
<?php if($deleteGearActivity == 0){ ?>
|
||||
<?php echo $translationsActivitiesActivity['activity_success_gearDeleted']; ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
|
||||
<div class="d-flex justify-content-between">
|
||||
<!-- Activity user details -->
|
||||
<div class="d-flex align-items-center">
|
||||
<img src=<?php if(is_null($activityUser[0]["photo_path"])){ if($activityUser[0]["gender"] == 1){ echo ("../img/avatar/male1.png"); }else{ echo ("../img/avatar/female1.png"); } }else{ echo ($activityUser[0]["photo_path"]); }?> alt="userPicture" class="rounded-circle" width="55" height="55">
|
||||
<div class="ms-3 me-3">
|
||||
<div class="fw-bold">
|
||||
<a href="../users/user.php?userID=<?php echo ($activityUser[0]["id"]); ?>"><?php echo ($activityUser[0]["name"]); ?></a>
|
||||
</div>
|
||||
<!-- Activity time and place details -->
|
||||
<h7><?php if($activity[0]["activity_type"] == 1){ echo '<i class="fa-solid fa-person-running"></i>'; }else{ if($activity[0]["activity_type"] == 4 || $activity[0]["activity_type"] == 5 || $activity[0]["activity_type"] == 6 || $activity[0]["activity_type"] == 7 || $activity[0]["activity_type"] == 8){ echo '<i class="fa-solid fa-person-biking"></i>'; }else{ if($activity[0]["activity_type"] == 9){ echo '<i class="fa-solid fa-person-swimming"></i>'; } } } ?> <?php echo (new DateTime($activity[0]["start_time"]))->format("d/m/y"); ?>@<?php echo (new DateTime($activity[0]["start_time"]))->format("H:i"); ?><?php if(isset($activity[0]["city"]) || isset($activity[0]["country"])){ echo " - "; }?><?php if(isset($activity[0]["city"]) && !empty($activity[0]["city"])){ echo $activity[0]["city"].", " ; }?><?php if(isset($activity[0]["country"]) && !empty($activity[0]["country"])){ echo $activity[0]["country"]; } ?></h7>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown d-flex">
|
||||
<button class="btn btn-link btn-lg" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<i class="fa-solid fa-ellipsis-vertical"></i>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="https://www.strava.com/activities/<?php echo $activity[0]['strava_activity_id']; ?>"><?php echo $translationsActivitiesActivity['activity_title_dropdown_seeItOnStrava']; ?></a></li>
|
||||
<li><a class="dropdown-item" href="#" data-bs-toggle="modal" data-bs-target="#deleteActivityModal"><?php echo $translationsActivitiesActivity['activity_title_dropdown_deleteActivity']; ?></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal delete gear -->
|
||||
<div class="modal fade" id="deleteActivityModal" tabindex="-1" aria-labelledby="deleteActivityModal" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="deleteActivityModal"><?php echo $translationsActivitiesActivity['activity_title_dropdown_deleteActivity']; ?></h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<?php echo $translationsActivitiesActivity['activity_title_dropdown_deleteActivity_modal_body']; ?> <b><?php echo $activity[0]['name']; ?></b>?
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo $translationsTemplateTop['template_top_global_close']; ?></button>
|
||||
<a type="button" class="btn btn-danger" href="../activities/activity.php?activityID=<?php echo $activity[0]["id"]; ?>&deleteActivity=1"><?php echo $translationsActivitiesActivity['activity_title_dropdown_deleteActivity']; ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Activity title -->
|
||||
<h1 class="mt-3"><?php echo $activity[0]["name"]; ?></h1>
|
||||
|
||||
<!-- Details -->
|
||||
<div class=" row d-flex mt-3">
|
||||
<div class="col">
|
||||
<span class="fw-lighter"><?php echo $translationsActivitiesActivity['activity_detail_distance']; ?></span>
|
||||
<br>
|
||||
<?php if($activity[0]["activity_type"] != 9){ ?>
|
||||
<?php echo number_format(($activity[0]["distance"] / 1000),2); ?> km
|
||||
<?php }else{ ?>
|
||||
<?php echo ($activity[0]["distance"]); ?> m
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div class="col border-start border-opacity-50">
|
||||
<span class="fw-lighter"><?php echo $translationsActivitiesActivity['activity_detail_time']; ?></span>
|
||||
<br>
|
||||
<?php
|
||||
$startDateTime = DateTime::createFromFormat("Y-m-d\TH:i:s", $activity[0]["start_time"]);
|
||||
$endDateTime = DateTime::createFromFormat("Y-m-d\TH:i:s", $activity[0]["end_time"]);
|
||||
$interval = $startDateTime->diff($endDateTime);
|
||||
|
||||
if ($interval->h < 1) {
|
||||
// If the difference is less than one hour
|
||||
echo $interval->i . "m " . $interval->s . "s";
|
||||
} else {
|
||||
// If the difference is one hour or more
|
||||
echo $interval->h . "h " . $interval->i . "m";
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="col border-start border-opacity-50">
|
||||
<?php if($activity[0]["activity_type"] != 9 && $activity[0]["activity_type"] != 1){ ?>
|
||||
<span class="fw-lighter"><?php echo $translationsActivitiesActivity['activity_detail_elevationGain']; ?></span>
|
||||
<br>
|
||||
<?php echo ($activity[0]["elevation_gain"]); ?> m
|
||||
<?php }else{ ?>
|
||||
<?php if($activity[0]["activity_type"] == 1 || $activity[0]["activity_type"] == 2 || $activity[0]["activity_type"] == 3){ ?>
|
||||
<span class="fw-lighter"><?php echo $translationsActivitiesActivity['activity_detail_pace']; ?></span>
|
||||
<br>
|
||||
<?php echo floor(($activity[0]["pace"]*1000)/60).":".number_format((((($activity[0]["pace"]*1000)/60) - floor(($activity[0]["pace"]*1000)/60)) * 60),0); ?> min/km
|
||||
<?php }else{ ?>
|
||||
<?php if($activity[0]["activity_type"] == 9){ ?>
|
||||
<span class="fw-lighter"><?php echo $translationsActivitiesActivity['activity_detail_pace']; ?></span>
|
||||
<br>
|
||||
<?php echo floor(($activity[0]["pace"]*100)/60).":".number_format((((($activity[0]["pace"]*100)/60) - floor(($activity[0]["pace"]*100)/60)) * 60),0); ?> min/100m
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
<!-- other metrics -->
|
||||
<div class="row d-flex mt-3">
|
||||
<?php if($activity[0]["activity_type"] == 1 || $activity[0]["activity_type"] == 2 || $activity[0]["activity_type"] == 3){ ?>
|
||||
<div class="col">
|
||||
<span class="fw-lighter"><?php echo $translationsActivitiesActivity['activity_detail_avgPower']; ?></span>
|
||||
<br>
|
||||
<?php if($activity[0]["average_power"]){
|
||||
echo ($activity[0]["average_power"]); ?> W
|
||||
<?php }else{
|
||||
echo "No data";
|
||||
} ?>
|
||||
</div>
|
||||
<div class="col border-start border-opacity-50">
|
||||
<span class="fw-lighter"><?php echo $translationsActivitiesActivity['activity_detail_elevationGain']; ?></span>
|
||||
<br>
|
||||
<?php echo ($activity[0]["elevation_gain"]); ?> m
|
||||
</div>
|
||||
<div class="col border-start border-opacity-50">
|
||||
<span class="fw-lighter"><?php echo $translationsActivitiesActivity['activity_detail_elevationLoss']; ?></span>
|
||||
<br>
|
||||
<?php echo ($activity[0]["elevation_loss"]); ?> m
|
||||
</div>
|
||||
<?php } ?>
|
||||
<?php if($activity[0]["activity_type"] != 9 && $activity[0]["activity_type"] != 1){ ?>
|
||||
<div class="col">
|
||||
<span class="fw-lighter"><?php echo $translationsActivitiesActivity['activity_detail_avgSpeed']; ?></span>
|
||||
<br>
|
||||
<?php echo (number_format($activity[0]["average_speed"]*3.6)); ?> km/h
|
||||
</div>
|
||||
<div class="col border-start border-opacity-50">
|
||||
<span class="fw-lighter"><?php echo $translationsActivitiesActivity['activity_detail_avgPower']; ?></span>
|
||||
<br>
|
||||
<?php if($activity[0]["average_power"]){
|
||||
echo ($activity[0]["average_power"]); ?> W
|
||||
<?php }else{
|
||||
echo "No data";
|
||||
} ?>
|
||||
</div>
|
||||
<div class="col border-start border-opacity-50">
|
||||
<span class="fw-lighter"><?php echo $translationsActivitiesActivity['activity_detail_elevationLoss']; ?></span>
|
||||
<br>
|
||||
<?php echo $activity[0]["elevation_loss"]; ?> m
|
||||
</div>
|
||||
<?php } ?>
|
||||
<div>
|
||||
|
||||
<!-- Map -->
|
||||
<div class="mt-3 mb-3" id="map" style="height: 500px"></div>
|
||||
|
||||
|
||||
<script>
|
||||
// JavaScript code to create the map for this activity
|
||||
var waypoints = <?php echo json_encode($activity[0]['waypoints']); ?>;
|
||||
var mapId = "map";
|
||||
|
||||
var map = L.map(mapId, {
|
||||
//dragging: false, // Disable panning
|
||||
//touchZoom: false, // Disable touch zoom
|
||||
//scrollWheelZoom: false, // Disable scroll wheel zoom
|
||||
//zoomControl: false // Remove zoom control buttons
|
||||
});
|
||||
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
maxZoom: 19,
|
||||
}).addTo(map);
|
||||
|
||||
var latlngs = waypoints.map(function(waypoint) {
|
||||
return [waypoint.lat, waypoint.lon];
|
||||
});
|
||||
|
||||
L.polyline(latlngs, { color: 'blue' }).addTo(map);
|
||||
|
||||
// Calculate the bounds of the polyline and fit the map to those bounds
|
||||
var bounds = L.latLngBounds(latlngs);
|
||||
map.fitBounds(bounds);
|
||||
|
||||
// Add green dot for the first waypoint
|
||||
L.marker([waypoints[0].lat, waypoints[0].lon], { icon: L.divIcon({ className: 'bg-success dot' }) }).addTo(map);
|
||||
|
||||
// Add red dot for the last waypoint
|
||||
L.marker([waypoints[waypoints.length - 1].lat, waypoints[waypoints.length - 1].lon], { icon: L.divIcon({ className: 'bg-danger dot' }) }).addTo(map);
|
||||
</script>
|
||||
|
||||
<!-- gear -->
|
||||
<hr class="mb-2 mt-2">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<p class="pt-2">
|
||||
<span class="fw-lighter"><?php echo $translationsActivitiesActivity['activity_gear_title']; ?></span>
|
||||
<br>
|
||||
<?php if($activity[0]["activity_type"] == 1){ echo '<i class="fa-solid fa-person-running"></i>'; }else{ if($activity[0]["activity_type"] == 4 || $activity[0]["activity_type"] == 5 || $activity[0]["activity_type"] == 6 || $activity[0]["activity_type"] == 7 || $activity[0]["activity_type"] == 8){ echo '<i class="fa-solid fa-person-biking"></i>'; }else{ if($activity[0]["activity_type"] == 9){ echo '<i class="fa-solid fa-person-swimming"></i>'; } } } ?>
|
||||
<?php if($activity[0]["gear_id"] == null){ ?>
|
||||
<?php echo $translationsActivitiesActivity['activity_gear_notset']; ?>
|
||||
<?php }else{ ?>
|
||||
<?php echo $activityGear[0]['nickname']; ?>
|
||||
<?php } ?>
|
||||
</p>
|
||||
<div class="justify-content-end">
|
||||
<?php if($activity[0]["gear_id"] == null){ ?>
|
||||
<!-- add gear zone -->
|
||||
<a class="btn btn-link btn-lg" href="#" role="button" data-bs-toggle="modal" data-bs-target="#addGearToActivityModal"><i class="fa-solid fa-plus"></i></a>
|
||||
|
||||
<!-- modal -->
|
||||
<div class="modal fade" id="addGearToActivityModal" tabindex="-1" aria-labelledby="addGearToActivityModal" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="addGearToActivityModal"><?php echo $translationsActivitiesActivity['activity_gear_addGear_title']; ?></h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form action="../activities/activity.php?activityID=<?php echo $activity[0]["id"]; ?>&addGearToActivity=1" method="post" enctype="multipart/form-data">
|
||||
<div class="modal-body">
|
||||
<!-- gear type fields -->
|
||||
<label for="gearIDAdd"><b>* <?php echo $translationsActivitiesActivity['activity_gear_addGear_label']; ?></b></label>
|
||||
<select class="form-control" name="gearIDAdd">
|
||||
<?php foreach($activityGearOptions as $option) { ?>
|
||||
<option value="<?php echo $option["id"]; ?>"><?php echo $option["nickname"]; ?></option>
|
||||
<?php } ?>
|
||||
</select required>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo $translationsTemplateTop['template_top_global_close']; ?></button>
|
||||
<button type="submit" class="btn btn-success" name="addGearToActivity"><?php echo $translationsActivitiesActivity['activity_gear_addGear_submit']; ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php }else{ ?>
|
||||
<!-- Edit zone -->
|
||||
<a class="btn btn-link btn-lg" href="#" role="button" data-bs-toggle="modal" data-bs-target="#editGearActivityModal"><i class="fa-regular fa-pen-to-square"></i></a>
|
||||
|
||||
<!-- modal -->
|
||||
<div class="modal fade" id="editGearActivityModal" tabindex="-1" aria-labelledby="editGearActivityModal" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="editGearActivityModal"><?php echo $translationsActivitiesActivity['activity_gear_editGear_title']; ?></h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form action="../activities/activity.php?activityID=<?php echo $activity[0]["id"]; ?>&editGearActivity=1" method="post" enctype="multipart/form-data">
|
||||
<div class="modal-body">
|
||||
<!-- gear type fields -->
|
||||
<label for="gearIDEdit"><b>* <?php echo $translationsActivitiesActivity['activity_gear_addGear_label']; ?></b></label>
|
||||
<select class="form-control" name="gearIDEdit">
|
||||
<?php foreach($activityGearOptions as $option) { ?>
|
||||
<option value="<?php echo $option["id"]; ?>"><?php echo $option["nickname"]; ?></option>
|
||||
<?php } ?>
|
||||
</select required>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo $translationsTemplateTop['template_top_global_close']; ?></button>
|
||||
<button type="submit" class="btn btn-success" name="editGearActivity"><?php echo $translationsActivitiesActivity['activity_gear_editGear_submit']; ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Delete zone -->
|
||||
<a class="btn btn-link btn-lg" href="#" role="button" data-bs-toggle="modal" data-bs-target="#deleteGearActivityModal"><i class="fa-solid fa-trash"></i></a>
|
||||
|
||||
<!-- Modal delete gear -->
|
||||
<div class="modal fade" id="deleteGearActivityModal" tabindex="-1" aria-labelledby="deleteGearActivityModal" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="deleteGearActivityModal"><?php echo $translationsActivitiesActivity['activity_gear_deleteGear_title']; ?></h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<?php echo $translationsActivitiesActivity['activity_gear_deleteGear_body']; ?> <b><?php echo $activityGear[0]['nickname']; ?></b>?
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo $translationsTemplateTop['template_top_global_close']; ?></button>
|
||||
<a type="button" class="btn btn-danger" href="../activities/activity.php?activityID=<?php echo $activity[0]["id"]; ?>&deleteGearActivity=1"><?php echo $translationsActivitiesActivity['activity_gear_deleteGear_title']; ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- waypoints graph -->
|
||||
<hr class="mb-2 mt-2">
|
||||
<div class="row">
|
||||
|
||||
<!--<h2 class="mb-3"><?php echo $translationsActivitiesActivity['activity_dataGraph_title']; ?></h2>-->
|
||||
|
||||
<div class="col-md-2">
|
||||
<p><?php echo $translationsActivitiesActivity['activity_dataGraph_dataSelection']; ?></p>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="hrCheckbox" checked>
|
||||
<label class="form-check-label" for="hrCheckbox"><?php echo $translationsActivitiesActivity['activity_dataGraph_hr']; ?></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="cadenceCheckbox">
|
||||
<label class="form-check-label" for="cadenceCheckbox"><?php echo $translationsActivitiesActivity['activity_dataGraph_cad']; ?></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="powerCheckbox">
|
||||
<label class="form-check-label" for="powerCheckbox"><?php echo $translationsActivitiesActivity['activity_dataGraph_power']; ?></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="elevationCheckbox">
|
||||
<label class="form-check-label" for="elevationCheckbox"><?php echo $translationsActivitiesActivity['activity_dataGraph_ele']; ?></label>
|
||||
</div>
|
||||
<?php if($activity[0]["activity_type"] == 4 || $activity[0]["activity_type"] == 5 || $activity[0]["activity_type"] == 6 || $activity[0]["activity_type"] == 7 || $activity[0]["activity_type"] == 8){ ?>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="velocityCheckbox">
|
||||
<label class="form-check-label" for="velocityCheckbox"><?php echo $translationsActivitiesActivity['activity_dataGraph_vel']; ?></label>
|
||||
</div>
|
||||
<?php }else{ ?>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="paceCheckbox">
|
||||
<label class="form-check-label" for="paceCheckbox"><?php echo $translationsActivitiesActivity['activity_dataGraph_pace']; ?></label>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div class="col">
|
||||
<canvas id="dataChart" height="100"></canvas>
|
||||
<p class="fw-lighter"><?php echo $translationsActivitiesActivity['activity_dataGraph_downsampleDataInfo']; ?></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var ctx = document.getElementById('dataChart').getContext('2d');
|
||||
var activityType = <?php echo $activity[0]["activity_type"]; ?>;
|
||||
const downsampledDataHr = downsampleData(<?php echo json_encode($hrData); ?>, 200);
|
||||
const downsampledDataCad = downsampleData(<?php echo json_encode($cadData); ?>, 200);
|
||||
const downsampledDataPower = downsampleData(<?php echo json_encode($powerData); ?>, 200);
|
||||
const downsampledDataEle = downsampleData(<?php echo json_encode($eleData); ?>, 200);
|
||||
|
||||
if (activityType === 4 || activityType === 5 || activityType === 6 || activityType === 7 || activityType === 8){
|
||||
const downsampledDataVel = downsampleData(<?php echo json_encode($velData); ?>, 200);
|
||||
|
||||
var selectedData = {
|
||||
hr: true,
|
||||
cadence: false,
|
||||
power: false,
|
||||
elevation: false,
|
||||
velocity: false
|
||||
};
|
||||
|
||||
var data = {
|
||||
hr: downsampledDataHr,
|
||||
cadence: downsampledDataCad,
|
||||
power: downsampledDataPower,
|
||||
elevation: downsampledDataEle,
|
||||
velocity: downsampledDataVel
|
||||
};
|
||||
}else{
|
||||
const downsampledDataPace = downsampleData(<?php echo json_encode($paceData); ?>, 200);
|
||||
|
||||
var selectedData = {
|
||||
hr: true,
|
||||
cadence: false,
|
||||
power: false,
|
||||
elevation: false,
|
||||
pace: false
|
||||
};
|
||||
|
||||
var data = {
|
||||
hr: downsampledDataHr,
|
||||
cadence: downsampledDataCad,
|
||||
power: downsampledDataPower,
|
||||
elevation: downsampledDataEle,
|
||||
pace: downsampledDataPace
|
||||
};
|
||||
}
|
||||
|
||||
var timestamps = data.hr.map(function(value, index) {
|
||||
return index;
|
||||
});
|
||||
|
||||
var dataChart = new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: timestamps,
|
||||
datasets: []
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
scales: {
|
||||
x: {
|
||||
display: false
|
||||
},
|
||||
y: {
|
||||
beginAtZero: false,
|
||||
title: {
|
||||
display: false
|
||||
}
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true
|
||||
},
|
||||
tooltips: {
|
||||
enabled: true,
|
||||
mode: 'index',
|
||||
intersect: false,
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
function downsampleData(data, threshold) {
|
||||
if (data.length <= threshold) {
|
||||
return data;
|
||||
}
|
||||
|
||||
const factor = Math.ceil(data.length / threshold);
|
||||
const downsampledData = [];
|
||||
|
||||
for (let i = 0; i < data.length; i += factor) {
|
||||
const chunk = data.slice(i, i + factor);
|
||||
const average = chunk.reduce((a, b) => a + b) / chunk.length;
|
||||
downsampledData.push(average);
|
||||
}
|
||||
|
||||
return downsampledData;
|
||||
}
|
||||
|
||||
function formatPace(pace) {
|
||||
const minutes = Math.floor(pace); // Extract whole minutes
|
||||
let decimalFraction = pace - minutes; // Get the decimal fraction
|
||||
let seconds = Math.round(decimalFraction * 60); // Convert the fraction to seconds
|
||||
return `${minutes}:${seconds.toString().padStart(2, '0')} min/km`;
|
||||
}
|
||||
|
||||
function updateChart() {
|
||||
// Determine which data series to display
|
||||
var datasets = [];
|
||||
|
||||
if (selectedData.hr) {
|
||||
datasets.push({
|
||||
label: 'Heart Rate',
|
||||
data: data.hr,
|
||||
borderColor: 'rgb(255, 0, 0)',
|
||||
fill: false,
|
||||
});
|
||||
}
|
||||
|
||||
if (selectedData.cadence) {
|
||||
datasets.push({
|
||||
label: 'Cadence',
|
||||
data: data.cadence,
|
||||
borderColor: 'rgb(75, 192, 192)',
|
||||
fill: false,
|
||||
});
|
||||
}
|
||||
|
||||
if (selectedData.power) {
|
||||
datasets.push({
|
||||
label: 'Power (W)',
|
||||
data: data.power,
|
||||
borderColor: 'rgb(0, 0, 255)',
|
||||
fill: false,
|
||||
});
|
||||
}
|
||||
|
||||
if (selectedData.elevation) {
|
||||
datasets.push({
|
||||
label: 'Elevation',
|
||||
data: data.elevation,
|
||||
borderColor: 'rgb(0, 255, 0)',
|
||||
fill: false,
|
||||
});
|
||||
}
|
||||
if (activityType === 4 || activityType === 5 || activityType === 6 || activityType === 7|| activityType === 8){
|
||||
if (selectedData.velocity) {
|
||||
datasets.push({
|
||||
label: 'Velocity (km/h)',
|
||||
data: data.velocity,
|
||||
borderColor: 'rgb(255, 255, 0)',
|
||||
fill: false,
|
||||
});
|
||||
}
|
||||
}else{
|
||||
if (activityType === 1 || activityType === 2 || activityType === 3){
|
||||
if (selectedData.pace) {
|
||||
datasets.push({
|
||||
label: 'Pace (min/km)',
|
||||
data: data.pace,
|
||||
borderColor: 'rgb(255, 255, 0)',
|
||||
fill: false,
|
||||
});
|
||||
}
|
||||
}else{
|
||||
if (selectedData.pace) {
|
||||
datasets.push({
|
||||
label: 'Pace (min/100m)',
|
||||
data: data.pace,
|
||||
borderColor: 'rgb(255, 255, 0)',
|
||||
fill: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the chart
|
||||
dataChart.data.datasets = datasets;
|
||||
dataChart.options.scales.y.title.display = datasets.length === 1; // Show Y-axis label if only one dataset is selected
|
||||
dataChart.update();
|
||||
}
|
||||
|
||||
// Listen for checkbox changes
|
||||
document.getElementById('hrCheckbox').addEventListener('change', function() {
|
||||
selectedData.hr = this.checked;
|
||||
updateChart();
|
||||
});
|
||||
|
||||
document.getElementById('cadenceCheckbox').addEventListener('change', function() {
|
||||
selectedData.cadence = this.checked;
|
||||
updateChart();
|
||||
});
|
||||
|
||||
document.getElementById('powerCheckbox').addEventListener('change', function() {
|
||||
selectedData.power = this.checked;
|
||||
updateChart();
|
||||
});
|
||||
|
||||
document.getElementById('elevationCheckbox').addEventListener('change', function() {
|
||||
selectedData.elevation = this.checked;
|
||||
updateChart();
|
||||
});
|
||||
|
||||
if (activityType === 4 || activityType === 5 || activityType === 6 || activityType === 7 || activityType === 8){
|
||||
document.getElementById('velocityCheckbox').addEventListener('change', function() {
|
||||
selectedData.velocity = this.checked;
|
||||
updateChart();
|
||||
});
|
||||
}else{
|
||||
document.getElementById('paceCheckbox').addEventListener('change', function() {
|
||||
selectedData.pace = this.checked;
|
||||
updateChart();
|
||||
});
|
||||
}
|
||||
|
||||
// Initial chart update
|
||||
updateChart();
|
||||
</script>
|
||||
|
||||
<!-- <script>
|
||||
var ctx = document.getElementById('hrChart').getContext('2d');
|
||||
|
||||
var hrData = <?php echo json_encode($hrData); ?>;
|
||||
var timestamps = hrData.map(function(value, index) {
|
||||
return index;
|
||||
});
|
||||
|
||||
var hrChart = new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: timestamps,
|
||||
datasets: [{
|
||||
label: 'Heart Rate',
|
||||
data: hrData,
|
||||
borderColor: 'rgb(75, 192, 192)',
|
||||
fill: false,
|
||||
}],
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
scales: {
|
||||
x: {
|
||||
display: false, // Hide x-axis
|
||||
},
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Heart Rate',
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false, // Hide legend
|
||||
},
|
||||
tooltips: {
|
||||
enabled: true, // Enable tooltips
|
||||
mode: 'index',
|
||||
intersect: false,
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
</script> -->
|
||||
|
||||
<div>
|
||||
<br class="d-lg-none">
|
||||
<button onclick="window.history.back();" type="button" class="w-100 btn btn-primary d-lg-none"><?php echo $translationsTemplateTop['template_top_global_back']; ?></button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<?php require_once $_SERVER['DOCUMENT_ROOT']."/inc/Template-Bottom.php" ?>
|
||||
255
frontend/gear/gear.php
Normal file
@@ -0,0 +1,255 @@
|
||||
<?php
|
||||
if(!isset($_SESSION)){
|
||||
session_start();
|
||||
}
|
||||
|
||||
require_once $_SERVER['DOCUMENT_ROOT']."/inc/sqlFunctions.php";
|
||||
|
||||
$page="gear";
|
||||
$gear = [];
|
||||
$editGearAction = -9000;
|
||||
$deleteGearAction = -9000;
|
||||
|
||||
if(!isLogged()){
|
||||
header("Location: ../login.php");
|
||||
}
|
||||
|
||||
if(!isTokenValid($_SESSION["token"])){
|
||||
header("Location: ../logout.php?sessionExpired=1");
|
||||
}
|
||||
|
||||
// Load the language file based on the user's preferred language
|
||||
switch ($_SESSION["preferred_language"]) {
|
||||
case 'en':
|
||||
$translationsGearGear = include $_SERVER['DOCUMENT_ROOT'].'/lang/gear/gear/en.php';
|
||||
break;
|
||||
case 'pt':
|
||||
$translationsGearGear = include $_SERVER['DOCUMENT_ROOT'].'/lang/gear/gear/pt.php';
|
||||
break;
|
||||
// ...
|
||||
default:
|
||||
$translationsGearGear = include $_SERVER['DOCUMENT_ROOT'].'/lang/gear/gear/en.php';
|
||||
|
||||
}
|
||||
|
||||
/* Edit action */
|
||||
if (isset($_POST["editGear"]) && $_GET["editGear"] == 1) {
|
||||
if(empty(trim($_POST["gearBrandEdit"]))){
|
||||
$_POST["gearBrandEdit"] = NULL;
|
||||
}
|
||||
if(empty(trim($_POST["gearModelEdit"]))){
|
||||
$_POST["gearModelEdit"] = NULL;
|
||||
}
|
||||
$editGearAction = editGear($_GET["gearID"], urlencode(trim($_POST["gearBrandEdit"])), urlencode(trim($_POST["gearModelEdit"])), urlencode(trim($_POST["gearNicknameEdit"])), $_POST["gearTypeEdit"], date("Y-m-d H:i:s", strtotime($_POST["gearDateEdit"] . " 00:00:00")), $_POST["gearIsActiveEdit"]);
|
||||
}
|
||||
|
||||
/* Delete gear */
|
||||
if(isset($_GET["deleteGear"]) && $_GET["deleteGear"] == 1){
|
||||
$deleteGearAction = deleteGear($_GET["gearID"]);
|
||||
if($deleteGearAction == 0){
|
||||
header("Location: ../gear/gears.php?deleteGear=1");
|
||||
}
|
||||
}
|
||||
|
||||
$gear = getGearFromId($_GET["gearID"]);
|
||||
if ($gear == NULL){
|
||||
header("Location: ../gear/gears.php?invalidGear=1");
|
||||
}
|
||||
|
||||
$gearActivities = getGearActivities($_GET["gearID"]);
|
||||
|
||||
$gearTotalDistance = 0;
|
||||
foreach($gearActivities as $activity){
|
||||
$gearTotalDistance += $activity["distance"];
|
||||
}
|
||||
?>
|
||||
|
||||
<?php require_once $_SERVER['DOCUMENT_ROOT']."/inc/Template-Top.php" ?>
|
||||
|
||||
<div class="container mt-4">
|
||||
<h1><?php echo $gear[0]["nickname"]; ?></h1>
|
||||
</div>
|
||||
|
||||
<div class="container mt-4">
|
||||
<!-- Error banners -->
|
||||
<?php if($editGearAction == -1 || $editGearAction == -2 || $deleteGearAction == -1 || $deleteGearAction == -2){ ?>
|
||||
<div class="alert alert-danger alert-dismissible d-flex align-items-center" role="alert">
|
||||
<i class="fa-solid fa-circle-exclamation me-1"></i>
|
||||
<div>
|
||||
<?php if($editGearAction == -1 || $deleteGearAction == -1){ ?>
|
||||
API ERROR | <?php echo $translationsGearGear['gear_API_error_-1']; ?> (-1).
|
||||
<?php }else{ ?>
|
||||
<?php if($editGearAction == -2 || $deleteGearAction == -2){ ?>
|
||||
API ERROR | <?php echo $translationsGearGear['gear_API_error_-2']; ?> (-2).
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<!-- Success banners -->
|
||||
<?php if($editGearAction == 0){ ?>
|
||||
<div class="alert alert-success alert-dismissible d-flex align-items-center" role="alert">
|
||||
<div>
|
||||
<i class="fa-regular fa-circle-check me-1"></i>
|
||||
<?php if($editGearAction == 0){ ?>
|
||||
<?php echo $translationsGearGear['gear_success_gearEdited']; ?>
|
||||
<?php } ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<div class="row row-gap-3">
|
||||
<!-- left column -->
|
||||
<div class="col-lg-3 col-md-12">
|
||||
<!-- Gear photo -->
|
||||
<div class="justify-content-center align-items-center d-flex">
|
||||
<img src=<?php if($gear[0]["gear_type"] == 1){ echo ("../img/avatar/bicycle1.png"); }else{ if($gear[0]["gear_type"] == 2){ echo ("../img/avatar/running_shoe1.png"); }else{ echo ("../img/avatar/wetsuit1.png"); }} ?> alt="gearPicture" width="180" height="180">
|
||||
<!--<img src=<?php if($gear[0]["gear_type"] == 1){ echo ("../img/avatar/bicycle1.png"); }else{ if($gear[0]["gear_type"] == 2){ echo ("../img/avatar/running_shoe1.png"); }else{ echo ("../img/avatar/wetsuit1.png"); }} ?> alt="gearPicture" class="rounded-circle" width="180" height="180">-->
|
||||
</div>
|
||||
<br>
|
||||
<div class="vstack justify-content-center align-items-center d-flex">
|
||||
<!-- badges -->
|
||||
<div class="hstack justify-content-center">
|
||||
<?php if($gear[0]["is_active"] == 1){ ?>
|
||||
<span class="badge bg-success-subtle border border-success-subtle text-success-emphasis rounded-pill align-middle"><?php echo $translationsGearGear['gear_gear_infoZone_isactive']; ?></span>
|
||||
<?php }else{ ?>
|
||||
<span class="badge bg-danger-subtle border border-danger-subtle text-danger-emphasis rounded-pill align-middle"><?php echo $translationsGearGear['gear_gear_infoZone_isinactive']; ?></span>
|
||||
<?php } ?>
|
||||
<?php if($gear[0]["gear_type"] == 1){ ?>
|
||||
<span class="ms-2 badge bg-primary-subtle border border-primary-subtle text-primary-emphasis rounded-pill align-middle"><?php echo $translationsGearGear['gear_gear_infoZone_gearisbike']; ?></span>
|
||||
<?php }else{
|
||||
if($gear[0]["gear_type"] == 2){ ?>
|
||||
<span class="ms-2 badge bg-primary-subtle border border-primary-subtle text-primary-emphasis rounded-pill align-middle"><?php echo $translationsGearGear['gear_gear_infoZone_gearisshoe']; ?></span>
|
||||
<?php }else{ ?>
|
||||
<span class="ms-2 badge bg-primary-subtle border border-primary-subtle text-primary-emphasis rounded-pill align-middle"><?php echo $translationsGearGear['gear_gear_infoZone_geariswetsuit']; ?></span>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
||||
<!-- edit gear zone -->
|
||||
<a class="mt-2 w-100 btn btn-primary" href="#" role="button" data-bs-toggle="modal" data-bs-target="#editGearModal"><?php echo $translationsGearGear['gear_gear_infoZone_editbutton']; ?></a>
|
||||
|
||||
<!-- Modal edit gear -->
|
||||
<div class="modal fade" id="editGearModal" tabindex="-1" aria-labelledby="editGearModal" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="editGearModal"><?php echo $translationsGearGear['gear_gear_infoZone_editbutton']; ?></h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form action="../gear/gear.php?gearID=<?php echo ($gear[0]["id"]); ?>&editGear=1" method="post" enctype="multipart/form-data">
|
||||
<div class="modal-body">
|
||||
<!-- brand fields -->
|
||||
<label for="gearBrandEdit"><b><?php echo $translationsGearGear['gear_gear_infoZone_modal_editGear_brandLabel']; ?></b></label>
|
||||
<input class="form-control" type="text" name="gearBrandEdit" placeholder="<?php echo $translationsGearGear['gear_gear_infoZone_modal_editGear_brandPlaceholder']; ?>" maxlength="45" value="<?php echo($gear[0]["brand"]); ?>">
|
||||
<!-- model fields -->
|
||||
<label for="gearModelEdit"><b><?php echo $translationsGearGear['gear_gear_infoZone_modal_editGear_modelLabel']; ?></b></label>
|
||||
<input class="form-control" type="text" name="gearModelEdit" placeholder="<?php echo $translationsGearGear['gear_gear_infoZone_modal_editGear_modelPlaceholder']; ?>" maxlength="45" value="<?php echo($gear[0]["model"]); ?>">
|
||||
<!-- nickname fields -->
|
||||
<label for="gearNicknameEdit"><b><?php echo $translationsGearGear['gear_gear_infoZone_modal_editGear_nicknameLabel']; ?></b></label>
|
||||
<input class="form-control" type="text" name="gearNicknameEdit" placeholder="<?php echo $translationsGearGear['gear_gear_infoZone_modal_editGear_nicknamePlaceholder']; ?>" maxlength="45" value="<?php echo($gear[0]["nickname"]); ?>">
|
||||
<!-- gear type fields -->
|
||||
<label for="gearTypeEdit"><b>* <?php echo $translationsGearGear['gear_gear_infoZone_modal_editGear_gearTypeLabel']; ?></b></label>
|
||||
<select class="form-control" name="gearTypeEdit">
|
||||
<option value="1" <?php if($gear[0]["gear_type"] == 1){ ?> selected="selected" <?php } ?>><?php echo $translationsGearGear['gear_gear_infoZone_modal_editGear_gearTypeOption1']; ?></option>
|
||||
<option value="2" <?php if($gear[0]["gear_type"] == 2){ ?> selected="selected" <?php } ?>><?php echo $translationsGearGear['gear_gear_infoZone_modal_editGear_gearTypeOption2']; ?></option>
|
||||
<option value="3" <?php if($gear[0]["gear_type"] == 3){ ?> selected="selected" <?php } ?>><?php echo $translationsGearGear['gear_gear_infoZone_modal_editGear_gearTypeOption3']; ?></option>
|
||||
</select required>
|
||||
<!-- date fields -->
|
||||
<label for="gearDateEdit"><b><?php echo $translationsGearGear['gear_gear_infoZone_modal_editGear_dateLabel']; ?></b></label>
|
||||
<input class="form-control" type="date" name="gearDateEdit" placeholder="<?php echo $translationsGearGear['gear_gear_infoZone_modal_editGear_datePlaceholder']; ?>" value="<?php echo date("Y-m-d", strtotime($gear[0]["created_at"])); ?>" required>
|
||||
<!-- gear is_active fields -->
|
||||
<label for="gearIsActiveEdit"><b>* <?php echo $translationsGearGear['gear_gear_infoZone_modal_editGear_gearIsActiveLabel']; ?></b></label>
|
||||
<select class="form-control" name="gearIsActiveEdit">
|
||||
<option value="1" <?php if($gear[0]["is_active"] == 1){ ?> selected="selected" <?php } ?>><?php echo $translationsGearGear['gear_gear_infoZone_modal_editGear_gearIsActiveOption1']; ?></option>
|
||||
<option value="2" <?php if($gear[0]["is_active"] == 2){ ?> selected="selected" <?php } ?>><?php echo $translationsGearGear['gear_gear_infoZone_modal_editGear_gearIsActiveOption2']; ?></option>
|
||||
</select required>
|
||||
* <?php echo $translationsTemplateTop['template_top_global_requiredFields']; ?>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo $translationsTemplateTop['template_top_global_close']; ?></button>
|
||||
<button type="submit" class="btn btn-success" name="editGear"><?php echo $translationsGearGear['gear_gear_infoZone_editbutton']; ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- delete gear zone -->
|
||||
<a class="mt-2 w-100 btn btn-danger <?php if(count($gearActivities) != 0){ echo "disabled"; } ?>" href="#" role="button" data-bs-toggle="modal" data-bs-target="#deleteGearModal" <?php if(count($gearActivities) != 0){ echo 'aria-disabled="true"' ; } ?>><?php echo $translationsGearGear['gear_gear_infoZone_deletebutton']; ?></a>
|
||||
|
||||
<!-- Modal delete gear -->
|
||||
<div class="modal fade" id="deleteGearModal" tabindex="-1" aria-labelledby="deleteGearModal" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="deleteGearModal"><?php echo $translationsGearGear['gear_gear_infoZone_deletebutton']; ?></h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<?php echo $translationsGearGear['gear_gear_infoZone_modal_deleteGear_body']; ?> <b><?php echo ($gear[0]["nickname"]); ?></b><span>?</span>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo $translationsTemplateTop['template_top_global_close']; ?></button>
|
||||
<a type="button" class="btn btn-danger" href="../gear/gear.php?gearID=<?php echo ($gear[0]["id"]); ?>&deleteGear=1"><?php echo $translationsGearGear['gear_gear_infoZone_deletebutton']; ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- details -->
|
||||
<div class="vstack align-items-center">
|
||||
<span class="mt-2"><strong><?php echo $translationsGearGear['gear_gear_infoZone_distance']; ?>: </strong><?php echo number_format($gearTotalDistance/1000,2); ?> km</span>
|
||||
<?php if(isset($gear[0]["brand"])){ ?>
|
||||
<span class="mt-2"><strong><?php echo $translationsGearGear['gear_gear_infoZone_brand']; ?>: </strong><?php echo $gear[0]["brand"]; ?></span>
|
||||
<?php } ?>
|
||||
<?php if(isset($gear[0]["model"])){ ?>
|
||||
<span class="mt-2"><strong><?php echo $translationsGearGear['gear_gear_infoZone_model']; ?>: </strong><?php echo $gear[0]["model"]; ?></span>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- right column -->
|
||||
<div class="col">
|
||||
<div>
|
||||
<!-- Gear components -->
|
||||
|
||||
<!-- Last 10 gear activities -->
|
||||
<hr class="mb-2 mt-2 d-sm-none d-block">
|
||||
<div class="hstack align-items-baseline">
|
||||
<h5><?php echo $translationsGearGear['gear_gear_gearActivities_title']; ?></h5>
|
||||
<h7 class="ms-1"><?php echo $translationsGearGear['gear_gear_gearActivities_number']; ?></h7>
|
||||
</div>
|
||||
<?php if(count($gearActivities) == 0){ ?>
|
||||
<div class="alert alert-warning alert-dismissible d-flex align-items-center" role="alert">
|
||||
<i class="fa-solid fa-circle-info me-1"></i>
|
||||
<div>
|
||||
<?php echo $translationsGearGear['gear_gear_gearActivities_noactivities']; ?>.
|
||||
</div>
|
||||
</div>
|
||||
<?php }else{ ?>
|
||||
<ul class="list-group list-group-flush">
|
||||
<?php for ($x = 0; $x < 10; $x+=1) { ?>
|
||||
<?php if($x < count($gearActivities)){ ?>
|
||||
<li class="vstack list-group-item d-flex justify-content-between">
|
||||
<a href="../activities/activity.php?activityID=<?php echo $gearActivities[$x]["id"];?>"><?php echo $gearActivities[$x]["name"];?></a>
|
||||
<span><strong><?php echo $translationsGearGear['gear_gear_gearActivities_datelabel']; ?>: </strong><?php echo (new DateTime($gearActivities[$x]["start_time"]))->format("d/m/y"); ?>@<?php echo (new DateTime($gearActivities[$x]["start_time"]))->format("H:i"); ?></span>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<br>
|
||||
<button onclick="window.history.back();" type="button" class="w-100 btn btn-primary d-lg-none"><?php echo $translationsTemplateTop['template_top_global_back']; ?></button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<?php require_once $_SERVER['DOCUMENT_ROOT']."/inc/Template-Bottom.php" ?>
|
||||
349
frontend/gear/gear_old.php
Normal file
@@ -0,0 +1,349 @@
|
||||
<?php
|
||||
if(!isset($_SESSION)){
|
||||
session_start();
|
||||
}
|
||||
|
||||
require_once $_SERVER['DOCUMENT_ROOT']."/inc/sqlFunctions.php";
|
||||
|
||||
$page="gear";
|
||||
$addGearAction = -9000;
|
||||
$editGearAction = -9000;
|
||||
$deleteGearAction = -9000;
|
||||
$numGear = 0;
|
||||
$gears = [];
|
||||
$pageNumber = 1;
|
||||
$numRecords = 5;
|
||||
|
||||
if(!isLogged()){
|
||||
header("Location: ../login.php");
|
||||
}
|
||||
|
||||
if(!isTokenValid($_SESSION["token"])){
|
||||
header("Location: ../logout.php?sessionExpired=1");
|
||||
}
|
||||
|
||||
// Load the language file based on the user's preferred language
|
||||
switch ($_SESSION["preferred_language"]) {
|
||||
case 'en':
|
||||
$translationsGearGear = include $_SERVER['DOCUMENT_ROOT'].'/lang/gear/en.php';
|
||||
break;
|
||||
case 'pt':
|
||||
$translationsGearGear = include $_SERVER['DOCUMENT_ROOT'].'/lang/gear/pt.php';
|
||||
break;
|
||||
// ...
|
||||
default:
|
||||
$translationsGearGear = include $_SERVER['DOCUMENT_ROOT'].'/lang/gear/en.php';
|
||||
|
||||
}
|
||||
|
||||
/* Add action */
|
||||
if(isset($_POST["addGear"]) && $_GET["addGear"] == 1){
|
||||
if(empty(trim($_POST["gearBrandAdd"]))){
|
||||
$_POST["gearBrandAdd"] = NULL;
|
||||
}
|
||||
if(empty(trim($_POST["gearModelAdd"]))){
|
||||
$_POST["gearModelAdd"] = NULL;
|
||||
}
|
||||
|
||||
$addGearAction = newGear(urlencode(trim($_POST["gearBrandAdd"])), urlencode(trim($_POST["gearModelAdd"])), urlencode(trim($_POST["gearNicknameAdd"])), $_POST["gearTypeAdd"], $_SESSION["id"], $_POST["gearDateAdd"]);
|
||||
}
|
||||
|
||||
/* Edit action */
|
||||
if (isset($_POST["editGear"]) && $_GET["editGear"] == 1) {
|
||||
if(empty(trim($_POST["gearBrandEdit"]))){
|
||||
$_POST["gearBrandEdit"] = NULL;
|
||||
}
|
||||
if(empty(trim($_POST["gearModelEdit"]))){
|
||||
$_POST["gearModelEdit"] = NULL;
|
||||
}
|
||||
$editGearAction = editGear($_GET["gearID"], urlencode(trim($_POST["gearBrandEdit"])), urlencode(trim($_POST["gearModelEdit"])), urlencode(trim($_POST["gearNicknameEdit"])), $_POST["gearTypeEdit"], $_POST["gearDateEdit"], $_POST["gearIsActiveEdit"]);
|
||||
}
|
||||
|
||||
/* Delete gear */
|
||||
if(isset($_GET["deleteGear"]) && $_GET["deleteGear"] == 1){
|
||||
$deleteGearAction = deleteGear($_GET["gearID"]);
|
||||
}
|
||||
|
||||
if(isset($_GET["pageNumber"])){
|
||||
$pageNumber = $_GET["pageNumber"];
|
||||
}
|
||||
|
||||
if(!isset($_POST["gearSearch"])){
|
||||
$gears = getGearPagination($pageNumber, $numRecords);
|
||||
$numGear = numGear();
|
||||
$total_pages = ceil($numGear / $numRecords);
|
||||
}else{
|
||||
$gears = getGearFromNickname(urlencode(trim($_POST["gearNickname"])));
|
||||
if($gears == NULL){
|
||||
$numGear=0;
|
||||
}else{
|
||||
$numGear=1;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<?php require_once $_SERVER['DOCUMENT_ROOT']."/inc/Template-Top.php" ?>
|
||||
|
||||
<div class="container mt-4">
|
||||
<h1><?php echo $translationsGearGear['gear_title']; ?></h1>
|
||||
</div>
|
||||
|
||||
<div class="container mt-4">
|
||||
<!-- Error banners -->
|
||||
<?php if($gears == -1 || $gears == -2 || $editGearAction == -1 || $editGearAction == -2 || $editGearAction == -3 || $deleteGearAction == -1 || $deleteGearAction == -2 || $deleteGearAction == -3 || $addGearAction == -1 || $addGearAction == -2 || $addGearAction == -3){ ?>
|
||||
<div class="alert alert-danger alert-dismissible d-flex align-items-center" role="alert">
|
||||
<i class="fa-solid fa-circle-exclamation me-1"></i>
|
||||
<div>
|
||||
<?php if($gears == -1 || $addGearAction == -1 || $editGearAction == -1 || $deleteGearAction == -1){ ?>
|
||||
API ERROR | <?php echo $translationsGearGear['gear_gear_API_error_-1']; ?> (-1).
|
||||
<?php }else{ ?>
|
||||
<?php if($gears == -2 || $addGearAction == -2 || $editGearAction == -2 || $deleteGearAction == -2){ ?>
|
||||
API ERROR | <?php echo $translationsGearGear['gear_gear_API_error_-2']; ?> (-2).
|
||||
<?php }else{ ?>
|
||||
<?php if($editGearAction == -3){ ?>
|
||||
<?php echo $translationsGearGear['gear_gear_error_editGear_-3']; ?> (-3).
|
||||
<?php }else{ ?>
|
||||
<?php if($addGearAction == -3){ ?>
|
||||
<?php echo $translationsGearGear['gear_gear_error_addGear_-3']; ?> (-3).
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<!-- Info banners -->
|
||||
<?php if($gears == NULL){ ?>
|
||||
<div class="alert alert-warning alert-dismissible d-flex align-items-center" role="alert">
|
||||
<i class="fa-solid fa-triangle-exclamation me-1"></i>
|
||||
<div>
|
||||
<?php if($users == NULL){ ?>
|
||||
<?php echo $translationsGearGear['gear_gear_error_searchGear_NULL']; ?> (NULL).
|
||||
<?php } ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<!-- Success banners -->
|
||||
<?php if($addGearAction == 0 || $editGearAction == 0 || $deleteGearAction == 0){ ?>
|
||||
<div class="alert alert-success alert-dismissible d-flex align-items-center" role="alert">
|
||||
<div>
|
||||
<i class="fa-regular fa-circle-check me-1"></i>
|
||||
<?php if($addGearAction == 0){ ?>
|
||||
<?php echo $translationsGearGear['gear_gear_success_gearAdded']; ?>
|
||||
<?php }else{ ?>
|
||||
<?php if($editGearAction == 0){ ?>
|
||||
<?php echo $translationsGearGear['gear_gear_success_gearEdited']; ?>
|
||||
<?php }else{ ?>
|
||||
<?php if($deleteGearAction == 0){ ?>
|
||||
<?php echo $translationsGearGear['gear_gear_success_gearDeleted']; ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<div class="row row-gap-3">
|
||||
<div class="col-lg-4 col-md-12">
|
||||
<!-- Add gear zone -->
|
||||
<p><?php echo $translationsGearGear['gear_gear_buttonLabel_addGear']; ?></p>
|
||||
<a class="w-100 btn btn-primary" href="#" role="button" data-bs-toggle="modal" data-bs-target="#addGearModal"><?php echo $translationsGearGear['gear_gear_button_addGear']; ?></a>
|
||||
|
||||
<!-- Modal add gear -->
|
||||
<div class="modal fade" id="addGearModal" tabindex="-1" aria-labelledby="addGearModal" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="addGearModal"><?php echo $translationsGearGear['gear_gear_modal_addGear_title']; ?></h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form action="../gear/gear.php?addGear=1" method="post" enctype="multipart/form-data">
|
||||
<div class="modal-body">
|
||||
<!-- brand fields -->
|
||||
<label for="gearBrandAdd"><b><?php echo $translationsGearGear['gear_gear_modal_addEditGear_brandLabel']; ?></b></label>
|
||||
<input class="form-control" type="text" name="gearBrandAdd" placeholder="<?php echo $translationsGearGear['gear_gear_modal_addEditGear_brandPlaceholder']; ?>" maxlength="45" value="<?php echo($_POST["gearBrandAdd"]); ?>">
|
||||
<!-- model fields -->
|
||||
<label for="gearModelAdd"><b><?php echo $translationsGearGear['gear_gear_modal_addEditGear_modelLabel']; ?></b></label>
|
||||
<input class="form-control" type="text" name="gearModelAdd" placeholder="<?php echo $translationsGearGear['gear_gear_modal_addEditGear_modelPlaceholder']; ?>" maxlength="45" value="<?php echo($_POST["gearModelAdd"]); ?>">
|
||||
<!-- nickname fields -->
|
||||
<label for="gearNicknameAdd"><b><?php echo $translationsGearGear['gear_gear_modal_addEditGear_nicknameLabel']; ?></b></label>
|
||||
<input class="form-control" type="text" name="gearNicknameAdd" placeholder="<?php echo $translationsGearGear['gear_gear_modal_addEditGear_nicknamePlaceholder']; ?>" maxlength="45" value="<?php echo($_POST["gearNicknameAdd"]); ?>">
|
||||
<!-- gear type fields -->
|
||||
<label for="gearTypeAdd"><b>* <?php echo $translationsGearGear['gear_gear_modal_addEditUser_gearTypeLabel']; ?></b></label>
|
||||
<select class="form-control" name="gearTypeAdd">
|
||||
<option value="1" <?php if($_POST["gearTypeAdd"] == 1){ ?> selected="selected" <?php } ?>><?php echo $translationsGearGear['gear_gear_modal_addEditUser_gearTypeOption1']; ?></option>
|
||||
<option value="2" <?php if($_POST["gearTypeAdd"] == 2){ ?> selected="selected" <?php } ?>><?php echo $translationsGearGear['gear_gear_modal_addEditUser_gearTypeOption2']; ?></option>
|
||||
<option value="3" <?php if($_POST["gearTypeAdd"] == 3){ ?> selected="selected" <?php } ?>><?php echo $translationsGearGear['gear_gear_modal_addEditUser_gearTypeOption3']; ?></option>
|
||||
</select required>
|
||||
<!-- date fields -->
|
||||
<label for="gearDateAdd"><b><?php echo $translationsGearGear['gear_gear_modal_addEditGear_dateLabel']; ?></b></label>
|
||||
<input class="form-control" type="date" name="gearDateAdd" placeholder="<?php echo $translationsGearGear['gear_gear_modal_addEditGear_datePlaceholder']; ?>" value="<?php echo($_POST["gearDateAdd"]); ?>" required>
|
||||
* <?php echo $translationsTemplateTop['template_top_global_requiredFields']; ?>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo $translationsTemplateTop['template_top_global_close']; ?></button>
|
||||
<button type="submit" class="btn btn-success" name="addGear"><?php echo $translationsGearGear['gear_gear_modal_addGear_title']; ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<p><?php echo $translationsGearGear['gear_gear_buttonLabel_searchGear']; ?></p>
|
||||
<form action="../gear/gear.php" method="post">
|
||||
<div class="mb-3">
|
||||
<!--<label for="userUsername"><b>Username</b></label>-->
|
||||
<input class="form-control" type="text" name="gearNickname" placeholder="<?php echo $translationsGearGear['gear_gear_form_searchGear_nicknamePlaceholder']; ?>" required>
|
||||
</div>
|
||||
<button class="w-100 btn btn-success" type="submit" name="gearSearch"><?php echo $translationsGearGear['gear_gear_button_searchGear']; ?></button>
|
||||
</form>
|
||||
<?php if(isset($_POST["gearSearch"])){ ?>
|
||||
<br>
|
||||
<a class="w-100 btn btn-primary" href="../gear/gear.php" role="button"><?php echo $translationsTemplateTop['template_top_global_button_listAll']; ?></a>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div class="col">
|
||||
<?php if($gears == -1 || $numGear == -1 || $gears == -2){ ?>
|
||||
<div class="alert alert-danger alert-dismissible d-flex align-items-center" role="alert">
|
||||
<i class="fa-solid fa-circle-exclamation"></i>
|
||||
<div>
|
||||
<?php if($gears == -1 || $numGear == -1 || $gears == -2){ ?>
|
||||
<?php echo $translationsGearGear['gear_gear_error_listGear_-1-2']; ?> (-1/-2).
|
||||
<?php } ?>
|
||||
</div>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
<?php }else{ ?>
|
||||
<!-- Info banners -->
|
||||
<?php if($gears == -3){ ?>
|
||||
<div class="alert alert-warning alert-dismissible d-flex align-items-center" role="alert">
|
||||
<i class="fa-solid fa-triangle-exclamation"></i>
|
||||
<div>
|
||||
<?php if($gears == -3){ ?>
|
||||
<?php echo $translationsGearGear['gear_gear_error_listGear_-3']; ?> (-3).
|
||||
<?php } ?>
|
||||
</div>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
<?php }else{ ?>
|
||||
<p><?php echo $translationsGearGear['gear_gear_list_title1']; ?> <?php echo ($numGear); ?> <?php echo $translationsGearGear['gear_gear_list_title2']; ?> (<?php echo $numRecords; ?> <?php echo $translationsGearGear['gear_gear_list_title3']; ?>:</p>
|
||||
<ul class="list-group list-group-flush">
|
||||
<?php foreach ($gears as $gear) { ?>
|
||||
<li class="list-group-item d-flex justify-content-between">
|
||||
<div class="d-flex align-items-center">
|
||||
<img src=<?php if($gear["gear_type"] == 1){ echo ("../img/avatar/male1.png"); }else{ if($gear["gear_type"] == 2){ echo ("../img/avatar/male1.png"); }else{ echo ("../img/avatar/female1.png"); }} ?> alt="gearPicture" class="rounded-circle" width="55" height="55">
|
||||
<div class="ms-3">
|
||||
<div class="fw-bold">
|
||||
<?php echo ($gear["nickname"]); ?>
|
||||
</div>
|
||||
<b><?php echo $translationsGearGear['gear_gear_gear_type']; ?></b><?php if($gear["gear_type"] == 1){ echo $translationsGearGear['gear_gear_modal_addEditUser_gearTypeOption1']; }else{ if($gear["gear_type"] == 2){ echo $translationsGearGear['gear_gear_modal_addEditUser_gearTypeOption2']; }else{ if($gear["gear_type"] == 3){ echo $translationsGearGear['gear_gear_modal_addEditUser_gearTypeOption3']; }}} ?>
|
||||
</br>
|
||||
<?php if($gear["is_active"] == 1){ ?>
|
||||
<span class="badge bg-success-subtle border border-success-subtle text-success-emphasis align-middle"><?php echo $translationsGearGear['gear_gear_list_isactive']; ?></span>
|
||||
<?php }else{ ?>
|
||||
<span class="badge bg-danger-subtle border border-danger-subtle text-danger-emphasis align-middle"><?php echo $translationsGearGear['gear_gear_list_isinactive']; ?></span>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<a class="btn btn-link btn-lg" href="#" role="button" data-bs-toggle="modal" data-bs-target="#editGearModal<?php echo ($gear["id"]); ?>"><i class="fa-solid fa-pen-to-square"></i></a>
|
||||
|
||||
<!-- Modal edit user -->
|
||||
<div class="modal fade" id="editGearModal<?php echo ($gear["id"]); ?>" tabindex="-1" aria-labelledby="editGearModal<?php echo ($gear["id"]); ?>" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="editGearModal<?php echo ($user["id"]); ?>"><?php echo $translationsGearGear['gear_gear_modal_editGear_title']; ?></h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form action="../gear/gear.php?gearID=<?php echo ($gear["id"]); ?>&editGear=1" method="post" enctype="multipart/form-data">
|
||||
<div class="modal-body">
|
||||
<!-- brand fields -->
|
||||
<label for="gearBrandEdit"><b><?php echo $translationsGearGear['gear_gear_modal_addEditGear_brandLabel']; ?></b></label>
|
||||
<input class="form-control" type="text" name="gearBrandEdit" placeholder="<?php echo $translationsGearGear['gear_gear_modal_addEditGear_brandPlaceholder']; ?>" maxlength="45" value="<?php echo($gear["brand"]); ?>">
|
||||
<!-- model fields -->
|
||||
<label for="gearModelEdit"><b><?php echo $translationsGearGear['gear_gear_modal_addEditGear_modelLabel']; ?></b></label>
|
||||
<input class="form-control" type="text" name="gearModelEdit" placeholder="<?php echo $translationsGearGear['gear_gear_modal_addEditGear_modelPlaceholder']; ?>" maxlength="45" value="<?php echo($gear["model"]); ?>">
|
||||
<!-- nickname fields -->
|
||||
<label for="gearNicknameEdit"><b><?php echo $translationsGearGear['gear_gear_modal_addEditGear_nicknameLabel']; ?></b></label>
|
||||
<input class="form-control" type="text" name="gearNicknameEdit" placeholder="<?php echo $translationsGearGear['gear_gear_modal_addEditGear_nicknamePlaceholder']; ?>" maxlength="45" value="<?php echo($gear["nickname"]); ?>">
|
||||
<!-- gear type fields -->
|
||||
<label for="gearTypeEdit"><b>* <?php echo $translationsGearGear['gear_gear_modal_addEditUser_gearTypeLabel']; ?></b></label>
|
||||
<select class="form-control" name="gearTypeEdit">
|
||||
<option value="1" <?php if($gear["gear_type"] == 1){ ?> selected="selected" <?php } ?>><?php echo $translationsGearGear['gear_gear_modal_addEditUser_gearTypeOption1']; ?></option>
|
||||
<option value="2" <?php if($gear["gear_type"] == 2){ ?> selected="selected" <?php } ?>><?php echo $translationsGearGear['gear_gear_modal_addEditUser_gearTypeOption2']; ?></option>
|
||||
<option value="3" <?php if($gear["gear_type"] == 3){ ?> selected="selected" <?php } ?>><?php echo $translationsGearGear['gear_gear_modal_addEditUser_gearTypeOption3']; ?></option>
|
||||
</select required>
|
||||
<!-- date fields -->
|
||||
<label for="gearDateEdit"><b><?php echo $translationsGearGear['gear_gear_modal_addEditGear_dateLabel']; ?></b></label>
|
||||
<input class="form-control" type="date" name="gearDateEdit" placeholder="<?php echo $translationsGearGear['gear_gear_modal_addEditGear_datePlaceholder']; ?>" value="<?php echo (new DateTime($gear["created_at"]))->format('Y-m-d'); ?>" required>
|
||||
<!-- is active fields -->
|
||||
<label for="gearIsActiveEdit"><b>* <?php echo $translationsGearGear['gear_gear_modal_editUser_gearIsActiveLabel']; ?></b></label>
|
||||
<select class="form-control" name="gearIsActiveEdit">
|
||||
<option value="1" <?php if($gear["is_active"] == 1){ ?> selected="selected" <?php } ?>><?php echo $translationsGearGear['gear_gear_modal_editUser_gearIsActiveOption1']; ?></option>
|
||||
<option value="0" <?php if($gear["is_active"] == 0){ ?> selected="selected" <?php } ?>><?php echo $translationsGearGear['gear_gear_modal_editUser_gearIsActiveOption2']; ?></option>
|
||||
</select required>
|
||||
* <?php echo $translationsTemplateTop['template_top_global_requiredFields']; ?>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo $translationsTemplateTop['template_top_global_close']; ?></button>
|
||||
<button type="submit" class="btn btn-success" name="editGear"><?php echo $translationsGearGear['gear_gear_modal_editGear_title']; ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-link btn-lg" href="#" role="button" data-bs-toggle="modal" data-bs-target="#deleteGearModal<?php echo ($gear["id"]); ?>"><i class="fa-solid fa-trash-can"></i></a>
|
||||
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="deleteGearModal<?php echo ($gear["id"]); ?>" tabindex="-1" aria-labelledby="deleteGearModal<?php echo ($gear["id"]); ?>" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="deleteGearModal<?php echo ($gear["id"]); ?>"><?php echo $translationsGearGear['gear_gear_modal_deleteGear_title']; ?></h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<?php echo $translationsGearGear['gear_gear_modal_deleteGear_body']; ?> <b><?php echo ($gear["nickname"]); ?></b>?
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo $translationsTemplateTop['template_top_global_close']; ?></button>
|
||||
<a type="button" class="btn btn-danger" href="../gear/gear.php?gearID=<?php echo ($gear["id"]); ?>&deleteGear=1"><?php echo $translationsGearGear['gear_gear_modal_deleteGear_title']; ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
<?php if(!isset($_POST["gearSearch"])){ ?>
|
||||
<br>
|
||||
<nav>
|
||||
<ul class="pagination justify-content-center">
|
||||
<li class="page-item <?php if($pageNumber == 1){ echo "disabled"; } ?>"><a class="page-link" href="?pageNumber=1">«</a></li>
|
||||
<?php for ($i = 1; $i <= $total_pages; $i++) { ?>
|
||||
<li class="page-item <?php if($i == $pageNumber){ echo "active"; } ?>"><a class="page-link" href="?pageNumber=<?php echo ($i);?>"><?php echo ($i);?></a></li>
|
||||
<?php } ?>
|
||||
<li class="page-item <?php if($pageNumber == $total_pages){ echo "disabled"; } ?>"><a class="page-link" href="?pageNumber=<?php echo ($total_pages);?>">»</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<br>
|
||||
<button onclick="window.history.back();" type="button" class="w-100 btn btn-primary d-lg-none"><?php echo $translationsTemplateTop['template_top_global_back']; ?></button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<?php require_once $_SERVER['DOCUMENT_ROOT']."/inc/Template-Bottom.php" ?>
|
||||
264
frontend/gear/gears.php
Normal file
@@ -0,0 +1,264 @@
|
||||
<?php
|
||||
if(!isset($_SESSION)){
|
||||
session_start();
|
||||
}
|
||||
|
||||
require_once $_SERVER['DOCUMENT_ROOT']."/inc/sqlFunctions.php";
|
||||
|
||||
$page="gears";
|
||||
$addGearAction = -9000;
|
||||
$numGears = 0;
|
||||
$gears = [];
|
||||
$pageNumber = 1;
|
||||
$numRecords = 5;
|
||||
|
||||
if(!isLogged()){
|
||||
header("Location: ../login.php");
|
||||
}
|
||||
|
||||
if(!isTokenValid($_SESSION["token"])){
|
||||
header("Location: ../logout.php?sessionExpired=1");
|
||||
}
|
||||
|
||||
// Load the language file based on the user's preferred language
|
||||
switch ($_SESSION["preferred_language"]) {
|
||||
case 'en':
|
||||
$translationsGearGears = include $_SERVER['DOCUMENT_ROOT'].'/lang/gear/gears/en.php';
|
||||
break;
|
||||
case 'pt':
|
||||
$translationsGearGears = include $_SERVER['DOCUMENT_ROOT'].'/lang/gear/gears/pt.php';
|
||||
break;
|
||||
// ...
|
||||
default:
|
||||
$translationsGearGears = include $_SERVER['DOCUMENT_ROOT'].'/lang/gear/gears/en.php';
|
||||
|
||||
}
|
||||
|
||||
/* Add action */
|
||||
if(isset($_POST["addGear"]) && $_GET["addGear"] == 1){
|
||||
if(empty(trim($_POST["gearBrandAdd"]))){
|
||||
$_POST["gearBrandAdd"] = NULL;
|
||||
}
|
||||
if(empty(trim($_POST["gearModelAdd"]))){
|
||||
$_POST["gearModelAdd"] = NULL;
|
||||
}
|
||||
|
||||
$addGearAction = newGear(urlencode(trim($_POST["gearBrandAdd"])), urlencode(trim($_POST["gearModelAdd"])), urlencode(trim($_POST["gearNicknameAdd"])), $_POST["gearTypeAdd"], $_POST["gearDateAdd"]);
|
||||
}
|
||||
|
||||
if(isset($_GET["pageNumber"])){
|
||||
$pageNumber = $_GET["pageNumber"];
|
||||
}
|
||||
|
||||
if(!isset($_POST["gearSearch"])){
|
||||
$gears = getGearPagination($pageNumber, $numRecords);
|
||||
$numGears = numGears();
|
||||
$total_pages = ceil($numGears / $numRecords);
|
||||
}else{
|
||||
$gears = getGearFromNickname(urlencode(trim($_POST["gearNickname"])));
|
||||
if($gears == NULL){
|
||||
$numGears=0;
|
||||
}else{
|
||||
$numGears=1;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<?php require_once $_SERVER['DOCUMENT_ROOT']."/inc/Template-Top.php" ?>
|
||||
|
||||
<div class="container mt-4">
|
||||
<h1><?php echo $translationsGearGears['gear_title']; ?></h1>
|
||||
</div>
|
||||
|
||||
<div class="container mt-4">
|
||||
<!-- Error banners -->
|
||||
<?php if($gears == -1 || $gears == -2 || $addGearAction == -1 || $addGearAction == -2 || $addGearAction == -3){ ?>
|
||||
<div class="alert alert-danger alert-dismissible d-flex align-items-center" role="alert">
|
||||
<i class="fa-solid fa-circle-exclamation me-1"></i>
|
||||
<div>
|
||||
<?php if($gears == -1 || $addGearAction == -1){ ?>
|
||||
API ERROR | <?php echo $translationsGearGears['gear_gear_API_error_-1']; ?> (-1).
|
||||
<?php }else{ ?>
|
||||
<?php if($gears == -2 || $addGearAction == -2){ ?>
|
||||
API ERROR | <?php echo $translationsGearGears['gear_gear_API_error_-2']; ?> (-2).
|
||||
<?php }else{ ?>
|
||||
<?php if($addGearAction == -3){ ?>
|
||||
<?php echo $translationsGearGears['gear_gear_error_addGear_-3']; ?> (-3).
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<!-- Info banners -->
|
||||
<?php if($gears == NULL || $_GET["invalidGear"] == 1){ ?>
|
||||
<div class="alert alert-warning alert-dismissible d-flex align-items-center" role="alert">
|
||||
<i class="fa-solid fa-triangle-exclamation me-1"></i>
|
||||
<div>
|
||||
<?php if($users == NULL){ ?>
|
||||
<?php echo $translationsGearGears['gear_gear_info_searchGear_NULL']; ?> (NULL).
|
||||
<?php }else{ ?>
|
||||
<?php if($_GET["invalidGear"] == 1){ ?>
|
||||
<?php echo $translationsGearGears['gear_gear_info_fromGear_invalidGear']; ?> (1).
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<!-- Success banners -->
|
||||
<?php if($addGearAction == 0 || $_GET["deleteGear"] == 1){ ?>
|
||||
<div class="alert alert-success alert-dismissible d-flex align-items-center" role="alert">
|
||||
<div>
|
||||
<i class="fa-regular fa-circle-check me-1"></i>
|
||||
<?php if($addGearAction == 0){ ?>
|
||||
<?php echo $translationsGearGears['gear_gear_success_gearAdded']; ?>
|
||||
<?php }else{ ?>
|
||||
<?php if($_GET["deleteGear"] == 1){ ?>
|
||||
<?php echo $translationsGearGears['gear_gear_success_gearDeleted']; ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<div class="row row-gap-3">
|
||||
<div class="col-lg-4 col-md-12">
|
||||
<!-- Add gear zone -->
|
||||
<p><?php echo $translationsGearGears['gear_gear_buttonLabel_addGear']; ?></p>
|
||||
<a class="w-100 btn btn-primary" href="#" role="button" data-bs-toggle="modal" data-bs-target="#addGearModal"><?php echo $translationsGearGears['gear_gear_button_addGear']; ?></a>
|
||||
|
||||
<!-- Modal add gear -->
|
||||
<div class="modal fade" id="addGearModal" tabindex="-1" aria-labelledby="addGearModal" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="addGearModal"><?php echo $translationsGearGears['gear_gear_modal_addGear_title']; ?></h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form action="../gear/gears.php?addGear=1" method="post" enctype="multipart/form-data">
|
||||
<div class="modal-body">
|
||||
<!-- brand fields -->
|
||||
<label for="gearBrandAdd"><b><?php echo $translationsGearGears['gear_gear_modal_addEditGear_brandLabel']; ?></b></label>
|
||||
<input class="form-control" type="text" name="gearBrandAdd" placeholder="<?php echo $translationsGearGears['gear_gear_modal_addEditGear_brandPlaceholder']; ?>" maxlength="45" value="<?php echo($_POST["gearBrandAdd"]); ?>">
|
||||
<!-- model fields -->
|
||||
<label for="gearModelAdd"><b><?php echo $translationsGearGears['gear_gear_modal_addEditGear_modelLabel']; ?></b></label>
|
||||
<input class="form-control" type="text" name="gearModelAdd" placeholder="<?php echo $translationsGearGears['gear_gear_modal_addEditGear_modelPlaceholder']; ?>" maxlength="45" value="<?php echo($_POST["gearModelAdd"]); ?>">
|
||||
<!-- nickname fields -->
|
||||
<label for="gearNicknameAdd"><b><?php echo $translationsGearGears['gear_gear_modal_addEditGear_nicknameLabel']; ?></b></label>
|
||||
<input class="form-control" type="text" name="gearNicknameAdd" placeholder="<?php echo $translationsGearGears['gear_gear_modal_addEditGear_nicknamePlaceholder']; ?>" maxlength="45" value="<?php echo($_POST["gearNicknameAdd"]); ?>">
|
||||
<!-- gear type fields -->
|
||||
<label for="gearTypeAdd"><b>* <?php echo $translationsGearGears['gear_gear_modal_addEditUser_gearTypeLabel']; ?></b></label>
|
||||
<select class="form-control" name="gearTypeAdd">
|
||||
<option value="1" <?php if($_POST["gearTypeAdd"] == 1){ ?> selected="selected" <?php } ?>><?php echo $translationsGearGears['gear_gear_modal_addEditUser_gearTypeOption1']; ?></option>
|
||||
<option value="2" <?php if($_POST["gearTypeAdd"] == 2){ ?> selected="selected" <?php } ?>><?php echo $translationsGearGears['gear_gear_modal_addEditUser_gearTypeOption2']; ?></option>
|
||||
<option value="3" <?php if($_POST["gearTypeAdd"] == 3){ ?> selected="selected" <?php } ?>><?php echo $translationsGearGears['gear_gear_modal_addEditUser_gearTypeOption3']; ?></option>
|
||||
</select required>
|
||||
<!-- date fields -->
|
||||
<label for="gearDateAdd"><b><?php echo $translationsGearGears['gear_gear_modal_addEditGear_dateLabel']; ?></b></label>
|
||||
<input class="form-control" type="date" name="gearDateAdd" placeholder="<?php echo $translationsGearGears['gear_gear_modal_addEditGear_datePlaceholder']; ?>" value="<?php echo($_POST["gearDateAdd"]); ?>" required>
|
||||
* <?php echo $translationsTemplateTop['template_top_global_requiredFields']; ?>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo $translationsTemplateTop['template_top_global_close']; ?></button>
|
||||
<button type="submit" class="btn btn-success" name="addGear"><?php echo $translationsGearGears['gear_gear_modal_addGear_title']; ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<p><?php echo $translationsGearGears['gear_gear_buttonLabel_searchGear']; ?></p>
|
||||
<form action="../gear/gears.php" method="post">
|
||||
<div class="mb-3">
|
||||
<!--<label for="userUsername"><b>Username</b></label>-->
|
||||
<input class="form-control" type="text" name="gearNickname" placeholder="<?php echo $translationsGearGears['gear_gear_form_searchGear_nicknamePlaceholder']; ?>" required>
|
||||
</div>
|
||||
<button class="w-100 btn btn-success" type="submit" name="gearSearch"><?php echo $translationsGearGears['gear_gear_button_searchGear']; ?></button>
|
||||
</form>
|
||||
<?php if(isset($_POST["gearSearch"])){ ?>
|
||||
<br>
|
||||
<a class="w-100 btn btn-primary" href="../gear/gears.php" role="button"><?php echo $translationsTemplateTop['template_top_global_button_listAll']; ?></a>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div class="col">
|
||||
<?php if($gears == -1 || $numGears == -1 || $gears == -2){ ?>
|
||||
<div class="alert alert-danger alert-dismissible d-flex align-items-center" role="alert">
|
||||
<i class="fa-solid fa-circle-exclamation"></i>
|
||||
<div>
|
||||
<?php if($gears == -1 || $numGears == -1 || $gears == -2){ ?>
|
||||
<?php echo $translationsGearGears['gear_gear_error_listGear_-1-2']; ?> (-1/-2).
|
||||
<?php } ?>
|
||||
</div>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
<?php }else{ ?>
|
||||
<!-- Info banners -->
|
||||
<?php if($gears == -3){ ?>
|
||||
<div class="alert alert-warning alert-dismissible d-flex align-items-center" role="alert">
|
||||
<i class="fa-solid fa-triangle-exclamation"></i>
|
||||
<div>
|
||||
<?php if($gears == -3){ ?>
|
||||
<?php echo $translationsGearGears['gear_gear_error_listGear_-3']; ?> (-3).
|
||||
<?php } ?>
|
||||
</div>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
<?php }else{ ?>
|
||||
<p><?php echo $translationsGearGears['gear_gear_list_title1']; ?> <?php echo ($numGears); ?> <?php echo $translationsGearGears['gear_gear_list_title2']; ?> (<?php echo $numRecords; ?> <?php echo $translationsGearGears['gear_gear_list_title3']; ?>:</p>
|
||||
<ul class="list-group list-group-flush">
|
||||
<?php foreach ($gears as $gear) { ?>
|
||||
<li class="list-group-item d-flex justify-content-between">
|
||||
<div class="d-flex align-items-center">
|
||||
<img src=<?php if($gear["gear_type"] == 1){ echo ("../img/avatar/bicycle1.png"); }else{ if($gear["gear_type"] == 2){ echo ("../img/avatar/running_shoe1.png"); }else{ echo ("../img/avatar/wetsuit1.png"); }} ?> alt="gearPicture" width="55" height="55">
|
||||
<!--<img src=<?php if($gear["gear_type"] == 1){ echo ("../img/avatar/bicycle1.png"); }else{ if($gear["gear_type"] == 2){ echo ("../img/avatar/running_shoe1.png"); }else{ echo ("../img/avatar/wetsuit1.png"); }} ?> alt="gearPicture" class="rounded-circle" width="55" height="55">-->
|
||||
<div class="ms-3">
|
||||
<div class="fw-bold">
|
||||
<!--<?php echo ($gear["nickname"]); ?>-->
|
||||
<a href="../gear/gear.php?gearID=<?php echo ($gear["id"]); ?>" class="link-underline-opacity-25 link-underline-opacity-100-hover"><?php echo ($gear["nickname"]); ?></a>
|
||||
</div>
|
||||
<b><?php echo $translationsGearGears['gear_gear_gear_type']; ?></b><?php if($gear["gear_type"] == 1){ echo $translationsGearGears['gear_gear_modal_addEditUser_gearTypeOption1']; }else{ if($gear["gear_type"] == 2){ echo $translationsGearGears['gear_gear_modal_addEditUser_gearTypeOption2']; }else{ if($gear["gear_type"] == 3){ echo $translationsGearGears['gear_gear_modal_addEditUser_gearTypeOption3']; }}} ?>
|
||||
</br>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<?php if($gear["is_active"] == 1){ ?>
|
||||
<span class="badge bg-success-subtle border border-success-subtle text-success-emphasis align-middle"><?php echo $translationsGearGears['gear_gear_list_isactive']; ?></span>
|
||||
<?php }else{ ?>
|
||||
<span class="badge bg-danger-subtle border border-danger-subtle text-danger-emphasis align-middle"><?php echo $translationsGearGears['gear_gear_list_isinactive']; ?></span>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<!--<a class="btn btn-link btn-rounded btn-lg" href="../gear/gear.php?gearID=<?php echo ($gear["id"]); ?>" role="button">View</a>
|
||||
<a class="btn btn-link btn-lg" href="../gear/gear.php?gearID=<?php echo ($gear["id"]); ?>" role="button" ><i class="fa-solid fa-arrow-up-right-from-square"></i></a>-->
|
||||
</li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
<?php if(!isset($_POST["gearSearch"])){ ?>
|
||||
<br>
|
||||
<nav>
|
||||
<ul class="pagination justify-content-center">
|
||||
<li class="page-item <?php if($pageNumber == 1){ echo "disabled"; } ?>"><a class="page-link" href="?pageNumber=1">«</a></li>
|
||||
<?php for ($i = 1; $i <= $total_pages; $i++) { ?>
|
||||
<li class="page-item <?php if($i == $pageNumber){ echo "active"; } ?>"><a class="page-link" href="?pageNumber=<?php echo ($i);?>"><?php echo ($i);?></a></li>
|
||||
<?php } ?>
|
||||
<li class="page-item <?php if($pageNumber == $total_pages){ echo "disabled"; } ?>"><a class="page-link" href="?pageNumber=<?php echo ($total_pages);?>">»</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<br>
|
||||
<button onclick="window.history.back();" type="button" class="w-100 btn btn-primary d-lg-none"><?php echo $translationsTemplateTop['template_top_global_back']; ?></button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<?php require_once $_SERVER['DOCUMENT_ROOT']."/inc/Template-Bottom.php" ?>
|
||||
BIN
frontend/img/avatar/bicycle1.png
Normal file
|
After Width: | Height: | Size: 41 KiB |
BIN
frontend/img/avatar/bicycle2.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
frontend/img/avatar/female1.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
frontend/img/avatar/male1.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
frontend/img/avatar/running_shoe1.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
frontend/img/avatar/running_shoe2.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
frontend/img/avatar/wetsuit1.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
frontend/img/avatar/wetsuit2.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
frontend/img/logo/logo.png
Normal file
|
After Width: | Height: | Size: 464 KiB |
BIN
frontend/img/strava/api_logo_cptblWith_strava_horiz_light.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
frontend/img/strava/api_logo_cptblWith_strava_stack_light.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
frontend/img/strava/btn_strava_connectwith_orange.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
frontend/img/users_img/img_12_9656950_12.JPG
Normal file
|
After Width: | Height: | Size: 72 KiB |
10
frontend/inc/Template-Bottom.php
Executable file
@@ -0,0 +1,10 @@
|
||||
<!-- Footer -->
|
||||
<footer class="border-top py-3 my-4 bg-body-tertiar">
|
||||
<p class="text-center text-muted">© <?php if(date("Y") == 2023) {
|
||||
echo date("Y");
|
||||
}else{ ?>2023-<?php echo date("Y");
|
||||
}?> Gear Guardian | <a href="https://github.com/joaovitoriasilva/gearguardian" role="button">Frontend <i class="fa-brands fa-github"></i></a> | <a href="https://github.com/joaovitoriasilva/gearguardian-backend" role="button">Backend <i class="fa-brands fa-github"></i></a>
|
||||
</p>
|
||||
<p class="text-center text-muted"><img src="../img/strava/api_logo_cptblWith_strava_horiz_light.png" alt="Compatible with STRAVA image" height="25"/></p>
|
||||
</body>
|
||||
</html>
|
||||
91
frontend/inc/Template-Top.php
Executable file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
// Load the language file based on the user's preferred language
|
||||
switch ($_SESSION["preferred_language"]) {
|
||||
case 'en':
|
||||
$translationsTemplateTop = include $_SERVER['DOCUMENT_ROOT'].'/lang/inc/Template-Top/en.php';
|
||||
break;
|
||||
case 'pt':
|
||||
$translationsTemplateTop = include $_SERVER['DOCUMENT_ROOT'].'/lang/inc/Template-Top/pt.php';
|
||||
break;
|
||||
// ...
|
||||
default:
|
||||
$translationsTemplateTop = include $_SERVER['DOCUMENT_ROOT'].'/lang/inc/Template-Top/en.php';
|
||||
}
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html data-bs-theme="default" lang="pt">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Gear Guardian</title>
|
||||
<!--<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>-->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
|
||||
<!--<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.2.0/chart.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>-->
|
||||
<script src="https://kit.fontawesome.com/8c44ee63d9.js"></script>
|
||||
<link rel="shortcut icon" href="../img/logo/logo.png">
|
||||
<link rel="apple-touch-icon" href="../img/logo/logo.png">
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
// Used to toggle the menu on small screens when clicking on the menu button
|
||||
function showNav() {
|
||||
var x = document.getElementById("navSmallScreens");
|
||||
if (x.className.indexOf("w3-show") == -1) {
|
||||
x.className += " w3-show";
|
||||
} else {
|
||||
x.className = x.className.replace(" w3-show", "");
|
||||
}
|
||||
}
|
||||
|
||||
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
const html = document.querySelector('html');
|
||||
if (prefersDark) {
|
||||
html.setAttribute('data-bs-theme', 'dark');
|
||||
} else {
|
||||
html.setAttribute('data-bs-theme', 'default');
|
||||
}
|
||||
</script>
|
||||
<nav class="navbar navbar-expand-lg bg-body-tertiary">
|
||||
<div class="container-fluid">
|
||||
<!--<img src="../img/logo/logo.png" alt="Logo" width="24" height="24" class="rounded-circle d-inline-block align-text-top m-2">-->
|
||||
<img src="../img/logo/logo.png" alt="Logo" width="30" class="d-inline-block align-text-top m-2">
|
||||
<a class="navbar-brand" href="../index.php">Gear Guardian</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
|
||||
<div class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
<?php if(isLogged()) {?>
|
||||
<a class="nav-link <?php if(str_contains($page, "gear")){ echo ("active"); }?>" href="../gear/gears.php"><i class="fa-solid fa-bicycle"></i> <?php echo $translationsTemplateTop['template_top_navbar_gear']; ?></a>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div class="navbar-nav d-flex">
|
||||
<?php if(isLogged()) {?>
|
||||
<span class="border-top d-sm-none d-block mb-2"></span>
|
||||
<a class="nav-link" href="../settings/settings.php?profileSettings=1">
|
||||
<img src="<?php if(is_null($_SESSION["photo_path"])){ if($_SESSION["gender"] == 1) { echo ("../img/avatar/farmer_avatar_male_1.png"); }else{ echo ("../img/avatar/farmer_avatar_female_1.png"); } }else{ echo ($_SESSION["photo_path"]); }?>" alt="userPhoto" width="24" height="24" class="rounded-circle"><span class="ms-2"><?php echo $translationsTemplateTop['template_top_navbar_profile']; ?></span>
|
||||
</a>
|
||||
<span class="border-top d-sm-none d-block mb-2"></span>
|
||||
<a class="nav-link d-none d-sm-block">|</a>
|
||||
<a class="nav-link" href="../settings/settings.php"><i class="fa-solid fa-gear"></i> <?php echo $translationsTemplateTop['template_top_navbar_settings']; ?></a>
|
||||
<a class="nav-link" href="../logout.php"><i class="fas fa-sign-out-alt"></i> <?php echo $translationsTemplateTop['template_top_navbar_logout']; ?></a>
|
||||
<?php }else{ ?>
|
||||
<a class="nav-link" href="../login.php"><i class="fas fa-sign-in-alt"></i> <?php echo $translationsTemplateTop['template_top_navbar_login']; ?></a>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="alert alert-warning alert-dismissible d-flex align-items-center mx-2 my-2 justify-content-center" role="alert">
|
||||
<i class="fa-solid fa-triangle-exclamation me-1"></i>
|
||||
<div>
|
||||
<span><?php echo $translationsTemplateTop['template_top_warning_zone']; ?></span>
|
||||
</div>
|
||||
</div>
|
||||
447
frontend/inc/func/activities-funcs.php
Normal file
@@ -0,0 +1,447 @@
|
||||
<?php
|
||||
/* ************************************************************************** */
|
||||
/* Activies */
|
||||
/* ************************************************************************** */
|
||||
/* Get all activities */
|
||||
function getActivities(){
|
||||
$response = callAPIRoute("/activities/all", 1, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return json_decode($response[0], true);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get user activities */
|
||||
function getUserActivities(){
|
||||
$response = callAPIRoute("/activities/useractivities", 1, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return json_decode($response[0], true);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get user activities */
|
||||
function getUserActivitiesThisWeekDistances($userID){
|
||||
$response = callAPIRoute("/activities/useractivities/$userID/thisweek/distances", 0, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return json_decode($response[0], true);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get all gear activities */
|
||||
function getGearActivities($gearID){
|
||||
$response = callAPIRoute("/activities/gear/$gearID", 1, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return json_decode($response[0], true);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Get all activities with pagination */
|
||||
function getActivitiesPagination($pageNumber, $numRecords){
|
||||
$response = callAPIRoute("/activities/all/pagenumber/$pageNumber/numRecords/$numRecords", 1, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return json_decode($response[0], true);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get user activities with pagination */
|
||||
function getUserActivitiesPagination($pageNumber, $numRecords){
|
||||
$response = callAPIRoute("/activities/useractivities/pagenumber/$pageNumber/numRecords/$numRecords", 1, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return json_decode($response[0], true);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get number of activities */
|
||||
function numActivities(){
|
||||
$response = callAPIRoute("/activities/all/number", 0, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
$data = json_decode($response[0], true);
|
||||
return $data[0];
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get user number of activities */
|
||||
function numUserActivities(){
|
||||
$response = callAPIRoute("/activities/useractivities/number", 0, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
$data = json_decode($response[0], true);
|
||||
return $data[0];
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get gear from id */
|
||||
function getActivityFromId($id){
|
||||
$response = callAPIRoute("/activities/$id/activityfromid", 1, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return json_decode($response[0], true);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* adds gear_id to activity */
|
||||
function addGearToActivity($activityID, $gearID){
|
||||
$response = callAPIRoute("/activities/$activityID/addgear/$gearID", 0, 3, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return 0;
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Creates a new activity */
|
||||
function newActivity($distance, $name, $type, $starttime, $endtime, $town, $country, $city, $waypoints, $elevationGain, $elevationLoss, $pace, $averageSpeed, $averagePower, $strava_id){
|
||||
$response = callAPIRoute("/activities/create", 0, 4, json_encode(array(
|
||||
'distance' => $distance,
|
||||
'name' => $name,
|
||||
'type' => $type,
|
||||
'starttime' => $starttime,
|
||||
'endtime' => $endtime,
|
||||
'city' => $city,
|
||||
'town' => $town,
|
||||
'country' => $country,
|
||||
'waypoints' => $waypoints,
|
||||
'elevationGain' => $elevationGain,
|
||||
'elevationLoss' => $elevationLoss,
|
||||
'pace' => $pace,
|
||||
'averageSpeed' => $averageSpeed,
|
||||
'averagePower' => $averagePower,
|
||||
'strava_id' => $strava_id,
|
||||
)));
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return 0;
|
||||
// $data = json_decode($response[0], true);
|
||||
// if (isset($data['id'])) {
|
||||
// return $data['id']; // Return the activity ID.
|
||||
// } else {
|
||||
// return -2; // Response doesn't contain the ID.
|
||||
// }
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function parseActivityGPX($gpx_file){
|
||||
try {
|
||||
$xml = simplexml_load_file($gpx_file);
|
||||
if ($xml === false) {
|
||||
throw new Exception("Invalid GPX file or could not load the file.");
|
||||
}
|
||||
|
||||
if ((string)$xml['creator'] != 'StravaGPX' && (string)$xml['creator'] != 'Garmin Connect') {
|
||||
return -5;
|
||||
}
|
||||
|
||||
// Extract metadata
|
||||
$activityType = (string)($xml->trk->type ?? "Workout"); // Extract activity type
|
||||
$activityName = (string)($xml->trk->name ?? "Workout" ); // Extract activity name
|
||||
$distance = 0; // Initialize total distance to 0
|
||||
$firstWaypointTime = null; // Variable to store the first waypoint time
|
||||
$lastWaypointTime = null; // Variable to store the last waypoint time
|
||||
$city = null; // Variable to store the last waypoint time
|
||||
$town = null; // Variable to store the last waypoint time
|
||||
$country = null; // Variable to store the last waypoint time
|
||||
$processOneTimeFields = 0;
|
||||
$elevationGain = 0;
|
||||
$elevationLoss = 0;
|
||||
$pace = 0;
|
||||
// Extract the start time from metadata
|
||||
#$startTime = (string)$xml->metadata->time;
|
||||
|
||||
$waypoints = [];
|
||||
$prevLatitude = null;
|
||||
$prevLongitude = null;
|
||||
|
||||
// Iterate through track segments and track points
|
||||
foreach ($xml->trk->trkseg->trkpt as $point) {
|
||||
$latitude = (float)$point['lat'];
|
||||
$longitude = (float)$point['lon'];
|
||||
|
||||
if ($prevLatitude !== null && $prevLongitude !== null) {
|
||||
// Calculate distance between waypoints (Haversine formula) and add to total distance
|
||||
$distance += calculateDistance($prevLatitude, $prevLongitude, $latitude, $longitude);
|
||||
}
|
||||
|
||||
$elevation = (float)$point->ele;
|
||||
|
||||
// You can access other data like time, heart rate, cadence, etc. from the extensions as needed
|
||||
$time = (string)$point->time;
|
||||
// Store the first and last waypoint times
|
||||
if ($firstWaypointTime === null) {
|
||||
$firstWaypointTime = $time;
|
||||
}
|
||||
|
||||
// Store the town and country
|
||||
if($processOneTimeFields == 0){
|
||||
$url = "https://geocode.maps.co/reverse?lat=$latitude&lon=$longitude";
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
try {
|
||||
$response = curl_exec($ch);
|
||||
#echo $response;
|
||||
if ($response !== false) {
|
||||
// Parse the JSON response
|
||||
$data = json_decode($response);
|
||||
#echo $data;
|
||||
// Extract the town and country from the address components
|
||||
if(isset($data->address->city)){
|
||||
$city = (string)$data->address->city;
|
||||
}
|
||||
if(isset($data->address->town)){
|
||||
$town = (string)$data->address->town;
|
||||
}
|
||||
if(isset($data->address->country)){
|
||||
$country = (string)$data->address->country;
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
echo "An error occurred: " . $e->getMessage();
|
||||
}
|
||||
curl_close($ch);
|
||||
$processOneTimeFields = 1;
|
||||
}
|
||||
|
||||
if ((string)$xml['creator'] === 'StravaGPX') {
|
||||
$heartRate = (int)$point->extensions->children('gpxtpx', true)->TrackPointExtension->hr;
|
||||
$cadence = (int)$point->extensions->children('gpxtpx', true)->TrackPointExtension->cad;
|
||||
}else{
|
||||
$heartRate = (int)$point->extensions->children('ns3', true)->TrackPointExtension->hr;
|
||||
$cadence = (int)$point->extensions->children('ns3', true)->TrackPointExtension->cad;
|
||||
}
|
||||
$power = (int)$point->extensions->power;
|
||||
|
||||
$instantSpeed = (float)calculateInstantSpeed($lastWaypointTime, $time, $latitude, $longitude, $prevLatitude, $prevLongitude);
|
||||
|
||||
if ($instantSpeed > 0) {
|
||||
$instantPace = 1/$instantSpeed; // Calculate instant pace in s/m
|
||||
} else {
|
||||
$instantPace = 0; // Avoid division by zero for points with zero speed
|
||||
}
|
||||
|
||||
$waypoints[] = [
|
||||
'lat' => $latitude,
|
||||
'lon' => $longitude,
|
||||
'ele' => $elevation,
|
||||
'time' => $time,
|
||||
'hr' => $heartRate,
|
||||
'cad' => $cadence,
|
||||
'power' => $power,
|
||||
'vel' => $instantSpeed,
|
||||
'pace' => $instantPace,
|
||||
];
|
||||
|
||||
// Update previous latitude and longitude for the next iteration
|
||||
$prevLatitude = $latitude;
|
||||
$prevLongitude = $longitude;
|
||||
$lastWaypointTime = $time;
|
||||
}
|
||||
|
||||
$elevationData = calculateElevationGainLoss($waypoints);
|
||||
$elevationGain = $elevationData['elevationGain'];
|
||||
$elevationLoss = $elevationData['elevationLoss'];
|
||||
$pace = calculatePace($distance, $firstWaypointTime, $lastWaypointTime);
|
||||
|
||||
$averageSpeed = calculateAverageSpeed($distance, $firstWaypointTime, $lastWaypointTime);
|
||||
|
||||
$averagePower = calculateAveragePower($waypoints);
|
||||
|
||||
return newActivity(intval(number_format($distance, 0, '', '')), $activityName, $activityType, $firstWaypointTime, $lastWaypointTime, $town, $country, $city, $waypoints, $elevationGain, $elevationLoss, number_format($pace,10), number_format($averageSpeed,10), $averagePower, null);
|
||||
|
||||
} catch (Exception $e) {
|
||||
// Handle the exception
|
||||
#echo "Error: " . $e->getMessage();
|
||||
// You can log the error, redirect the user, or take appropriate action.
|
||||
return -4;
|
||||
}
|
||||
}
|
||||
|
||||
// Function to calculate distance
|
||||
function calculateDistance($lat1, $lon1, $lat2, $lon2) {
|
||||
// The radius of the Earth in meters (mean value)
|
||||
$earthRadius = 6371000; // 6,371 km = 6,371,000 meters
|
||||
|
||||
// Convert latitude and longitude from degrees to radians
|
||||
$lat1 = deg2rad($lat1);
|
||||
$lon1 = deg2rad($lon1);
|
||||
$lat2 = deg2rad($lat2);
|
||||
$lon2 = deg2rad($lon2);
|
||||
|
||||
// Haversine formula
|
||||
$latDiff = $lat2 - $lat1;
|
||||
$lonDiff = $lon2 - $lon1;
|
||||
$a = sin($latDiff / 2) * sin($latDiff / 2) + cos($lat1) * cos($lat2) * sin($lonDiff / 2) * sin($lonDiff / 2);
|
||||
$c = 2 * atan2(sqrt($a), sqrt(1 - $a));
|
||||
$distance = $earthRadius * $c;
|
||||
|
||||
return $distance;
|
||||
}
|
||||
|
||||
// Add this function to calculate elevation gain and loss
|
||||
function calculateElevationGainLoss($waypoints) {
|
||||
$elevationGain = 0;
|
||||
$elevationLoss = 0;
|
||||
$prevElevation = null;
|
||||
|
||||
foreach ($waypoints as $waypoint) {
|
||||
$elevation = $waypoint['ele'];
|
||||
|
||||
if ($prevElevation !== null) {
|
||||
$elevationChange = $elevation - $prevElevation;
|
||||
if ($elevationChange > 0) {
|
||||
$elevationGain += $elevationChange;
|
||||
} else {
|
||||
$elevationLoss -= $elevationChange;
|
||||
}
|
||||
}
|
||||
|
||||
$prevElevation = $elevation;
|
||||
}
|
||||
|
||||
return ['elevationGain' => $elevationGain, 'elevationLoss' => $elevationLoss];
|
||||
}
|
||||
|
||||
// Add this function to calculate pace
|
||||
function calculatePace($distance, $firstWaypointTime, $lastWaypointTime) {
|
||||
// Convert the time strings to DateTime objects
|
||||
$startDateTime = new DateTime($firstWaypointTime);
|
||||
$endDateTime = new DateTime($lastWaypointTime);
|
||||
|
||||
// Calculate the time difference in seconds
|
||||
$totalTimeInSeconds = $endDateTime->getTimestamp() - $startDateTime->getTimestamp();
|
||||
|
||||
// Calculate pace in seconds per meter
|
||||
$paceInSecondsPerMeter = $totalTimeInSeconds / $distance;
|
||||
return $paceInSecondsPerMeter;
|
||||
}
|
||||
|
||||
function calculateInstantSpeed($prevTime, $time, $latitude, $longitude, $prevLatitude, $prevLongitude) {
|
||||
$timeCalc = new DateTime($time);
|
||||
$prevTimeCalc = new DateTime($prevTime);
|
||||
if ($prevTimeCalc !== null) {
|
||||
$timeDifference = $timeCalc->getTimestamp() - $prevTimeCalc->getTimestamp();
|
||||
if ($timeDifference > 0) {
|
||||
$distance = calculateDistance($prevLatitude, $prevLongitude, $latitude, $longitude);
|
||||
$instantSpeed = $distance / $timeDifference;
|
||||
}
|
||||
}
|
||||
|
||||
return $instantSpeed; // output in m/s
|
||||
}
|
||||
|
||||
function calculateAverageSpeed($distance, $firstWaypointTime, $lastWaypointTime) {
|
||||
// Convert the time strings to DateTime objects
|
||||
$startDateTime = new DateTime($firstWaypointTime);
|
||||
$endDateTime = new DateTime($lastWaypointTime);
|
||||
|
||||
// Calculate the time difference in seconds
|
||||
$totalTimeInSeconds = $endDateTime->getTimestamp() - $startDateTime->getTimestamp();
|
||||
|
||||
// Calculate average speed in meters per second
|
||||
$averageSpeed = $distance / $totalTimeInSeconds;
|
||||
|
||||
return $averageSpeed;
|
||||
}
|
||||
|
||||
function calculateAveragePower($waypoints) {
|
||||
$totalPower = 0;
|
||||
$numDataPoints = count($waypoints);
|
||||
|
||||
foreach ($waypoints as $waypoint) {
|
||||
$totalPower += $waypoint['power'];
|
||||
}
|
||||
|
||||
if ($numDataPoints > 0) {
|
||||
$averagePower = $totalPower / $numDataPoints;
|
||||
return $averagePower;
|
||||
} else {
|
||||
return 0; // Avoid division by zero in case of no data points
|
||||
}
|
||||
}
|
||||
|
||||
/* Unset activity gear */
|
||||
function unsetActivityGear($id){
|
||||
$response = callAPIRoute("/activities/$id/deletegear", 0, 3, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return 0;
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Deletes an activity based on its ID */
|
||||
function deleteActivity($id){
|
||||
$response = callAPIRoute("/activities/$id/delete", 0, 1, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return 0;
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
176
frontend/inc/func/gear-funcs.php
Normal file
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
/* ************************************************************************** */
|
||||
/* Gear */
|
||||
/* ************************************************************************** */
|
||||
/* Get all gear */
|
||||
function getGear(){
|
||||
$response = callAPIRoute("/gear/all", 1, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return json_decode($response[0], true);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get all gear for running*/
|
||||
function getGearForRunning(){
|
||||
$response = callAPIRoute("/gear/all/running", 1, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return json_decode($response[0], true);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get all gear for running*/
|
||||
function getGearForCycling(){
|
||||
$response = callAPIRoute("/gear/all/cycling", 1, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return json_decode($response[0], true);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get all gear for running*/
|
||||
function getGearForSwimming(){
|
||||
$response = callAPIRoute("/gear/all/swimming", 1, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return json_decode($response[0], true);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get all gear with pagination */
|
||||
function getGearPagination($pageNumber, $numRecords){
|
||||
$response = callAPIRoute("/gear/all/pagenumber/$pageNumber/numRecords/$numRecords", 1, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return json_decode($response[0], true);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get number of gear */
|
||||
function numGears(){
|
||||
$response = callAPIRoute("/gear/number", 0, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
$data = json_decode($response[0], true);
|
||||
return $data[0];
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get gear from nickname */
|
||||
function getGearFromNickname($nickname){
|
||||
$response = callAPIRoute("/gear/$nickname/gearfromnickname", 1, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return json_decode($response[0], true);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get gear from id */
|
||||
function getGearFromId($id){
|
||||
$response = callAPIRoute("/gear/$id/gearfromid", 1, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return json_decode($response[0], true);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Creates a new gear */
|
||||
function newGear($brand, $model, $nickname, $gear_type, $date){
|
||||
if(getGearFromNickname($nickname) != NULL){
|
||||
return -3;
|
||||
}
|
||||
|
||||
$response = callAPIRoute("/gear/create", 0, 4, json_encode(array(
|
||||
'brand' => $brand,
|
||||
'model' => $model,
|
||||
'nickname' => $nickname,
|
||||
'gear_type' => $gear_type,
|
||||
'date' => $date,
|
||||
)));
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return 0;
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Edit gear */
|
||||
function editGear($id, $brand, $model, $nickname, $gear_type, $date, $is_active){
|
||||
$response = callAPIRoute("/gear/$id/edit", 0, 3, json_encode(array(
|
||||
'brand' => $brand,
|
||||
'model' => $model,
|
||||
'nickname' => $nickname,
|
||||
'gear_type' => $gear_type,
|
||||
'date' => $date,
|
||||
'is_active' => $is_active,
|
||||
)));
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return 0;
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Deletes a gear based on its ID */
|
||||
function deleteGear($id){
|
||||
$response = callAPIRoute("/gear/$id/delete", 0, 1, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return 0;
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
82
frontend/inc/func/main-api-funcs.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/* ************************************************************************** */
|
||||
/* Main API Funcs */
|
||||
/* ************************************************************************** */
|
||||
/* Get to call a API route */
|
||||
function callAPIRoute($endpoint, $multipleReturns, $callType, $dataFields){
|
||||
$api_url = 'http://192.168.2.80:98';
|
||||
$responseArray = [];
|
||||
|
||||
// Initialize a new cURL session
|
||||
$ch = curl_init();
|
||||
// Set the cURL options to make an HTTP GET request to the API endpoint with an OAuth2 bearer token in the Authorization header
|
||||
curl_setopt($ch, CURLOPT_URL, $api_url . $endpoint);
|
||||
|
||||
// 0 GET, 1 DELETE, 2 POST, 3 PUT
|
||||
if($callType == 1){
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
|
||||
}else{
|
||||
if($callType == 2){
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
if($dataFields != NULL){
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($dataFields));
|
||||
}
|
||||
}else{
|
||||
if($callType == 3){
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
|
||||
if($dataFields != NULL){
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $dataFields);
|
||||
}
|
||||
}else{
|
||||
if($callType == 4 || $callType == 5){
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
if($dataFields != NULL){
|
||||
// Set the Content-Type header to specify JSON data
|
||||
#curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
||||
# 'Content-Type: application/json'
|
||||
#));
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $dataFields);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($multipleReturns == 1){
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
||||
"Authorization: Bearer {$_SESSION["token"]}"
|
||||
));
|
||||
}else{
|
||||
if($callType == 4 || $callType == 3){
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
||||
"Content-Type: application/json",
|
||||
"Authorization: Bearer {$_SESSION["token"]}"
|
||||
));
|
||||
}else{
|
||||
if($callType == 5){
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
||||
"Content-Type: application/json"
|
||||
));
|
||||
}else{
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
"Authorization: Bearer {$_SESSION["token"]}"
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
// Execute the cURL request and store the response in a variable
|
||||
$response = curl_exec($ch);
|
||||
|
||||
$responseArray[] = $response;
|
||||
$responseArray[] = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
|
||||
#echo $responseArray[0]." + ".$responseArray[1];
|
||||
|
||||
curl_close($ch);
|
||||
|
||||
return $responseArray;
|
||||
}
|
||||
?>
|
||||
|
||||
111
frontend/inc/func/session-funcs.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/* ************************************************************************** */
|
||||
/* Session info */
|
||||
/* ************************************************************************** */
|
||||
|
||||
/* Check if a user is logged */
|
||||
function isLogged(){
|
||||
if (isset($_SESSION["id"])){
|
||||
if ($_SESSION["id"]>=0){
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check if user token is valid */
|
||||
function isTokenValid($token){
|
||||
$response = callAPIRoute("/validate_token", 1, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
$data = json_decode($response[0], true);
|
||||
if (isset($data["message"]) && $data["message"] === "Token is valid") {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Do a login */
|
||||
function loginUser($username, $password, $neverExpires){
|
||||
#$api_url = 'http://192.168.2.80:98';
|
||||
#$ch = curl_init();
|
||||
#curl_setopt($ch, CURLOPT_URL, $api_url . '/token');
|
||||
#curl_setopt($ch, CURLOPT_POST, 1);
|
||||
#curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
|
||||
# 'username' => $username,
|
||||
# 'password' => $password,
|
||||
# 'loginNeverExpires' => $neverExpires,
|
||||
#]));
|
||||
#curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
#$response = curl_exec($ch);
|
||||
#curl_close($ch);
|
||||
$response = callAPIRoute("/token", 0, 5, json_encode(array(
|
||||
'username' => $username,
|
||||
'password' => $password,
|
||||
'neverExpires' => $neverExpires,
|
||||
)));
|
||||
return $response[0];
|
||||
}
|
||||
|
||||
|
||||
/* Unset user info */
|
||||
function clearUserRelatedInfoSession(){
|
||||
unset($_SESSION["token"]);
|
||||
unset($_SESSION["id"]);
|
||||
unset($_SESSION["username"]);
|
||||
unset($_SESSION["email"]);
|
||||
unset($_SESSION["name"]);
|
||||
unset($_SESSION["city"]);
|
||||
unset($_SESSION["birthdate"]);
|
||||
unset($_SESSION["preferred_language"]);
|
||||
unset($_SESSION["gender"]);
|
||||
unset($_SESSION["access_type"]);
|
||||
unset($_SESSION["photo_path"]);
|
||||
unset($_SESSION["photo_path_aux"]);
|
||||
}
|
||||
|
||||
/* Set user info */
|
||||
function setUserRelatedInfoSession($token){
|
||||
clearUserRelatedInfoSession();
|
||||
|
||||
$_SESSION["token"] = $token;
|
||||
|
||||
$response = callAPIRoute("/users/me", 1, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
$user = json_decode($response[0], true);
|
||||
if($user['is_active'] == 0){
|
||||
clearUserRelatedInfoSession();
|
||||
return -3;
|
||||
}
|
||||
// Populate the $_SESSION variable with user information
|
||||
// $_SESSION["token"] = $token;
|
||||
$_SESSION["id"] = $user['id'];
|
||||
$_SESSION["name"] = $user['name'];
|
||||
$_SESSION["username"] = $user['username'];
|
||||
$_SESSION["email"] = $user['email'];
|
||||
$_SESSION["city"] = $user['city'];
|
||||
#$_SESSION["birthdate"] = date("d/m/Y", strtotime($user['birthdate']));
|
||||
$_SESSION["birthdate"] = $user['birthdate'];
|
||||
$_SESSION["preferred_language"] = $user['preferred_language'];
|
||||
$_SESSION["gender"] = $user['gender'];
|
||||
$_SESSION["access_type"] = $user['access_type'];
|
||||
$_SESSION["photo_path"] = $user['photo_path'];
|
||||
$_SESSION["photo_path_aux"] = $user['photo_path_aux'];
|
||||
$_SESSION["is_strava_linked"] = $user['is_strava_linked'];
|
||||
return 0;
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
56
frontend/inc/func/strava-funcs.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/* ************************************************************************** */
|
||||
/* Strava */
|
||||
/* ************************************************************************** */
|
||||
/* Generate unique user state for strava link */
|
||||
function setUniqueUserStateStravaLink($state){
|
||||
$response = callAPIRoute("/strava/set-user-unique-state/$state", 0, 3, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return 0;
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function unsetUniqueUserStateStravaLink(){
|
||||
$response = callAPIRoute("/strava/unset-user-unique-state", 0, 3, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return 0;
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function linkStrava($state){
|
||||
// Example PHP code for the authentication link
|
||||
$client_id = '115321';
|
||||
$redirect_uri = urlencode('https://api-gearguardian.jvslab.pt/strava/strava-callback');
|
||||
$scope = 'read,read_all,profile:read_all,activity:read,activity:read_all'; // Set your required scope
|
||||
|
||||
$strava_auth_url = "http://www.strava.com/oauth/authorize?client_id={$client_id}&response_type=code&redirect_uri={$redirect_uri}&approval_prompt=force&scope={$scope}&state={$state}";
|
||||
|
||||
header("Location: ".$strava_auth_url);
|
||||
}
|
||||
|
||||
function getStravaActivities(){
|
||||
$response = callAPIRoute("/strava/retrieve/activities", 0, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return 0;
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
206
frontend/inc/func/users-funcs.php
Normal file
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
/* ************************************************************************** */
|
||||
/* Users */
|
||||
/* ************************************************************************** */
|
||||
/* Get all users */
|
||||
function getUsers(){
|
||||
$response = callAPIRoute("/users/all", 1, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return json_decode($response[0], true);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get all users with pagination */
|
||||
function getUsersPagination($pageNumber, $numRecords){
|
||||
$response = callAPIRoute("/users/all/pagenumber/$pageNumber/numRecords/$numRecords", 1, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return json_decode($response[0], true);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get number of users */
|
||||
function numUsers(){
|
||||
$response = callAPIRoute("/users/number", 0, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
$data = json_decode($response[0], true);
|
||||
return $data[0];
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get user from username */
|
||||
function getUserFromUsername($usernameUser){
|
||||
$response = callAPIRoute("/users/$usernameUser/userfromusername", 1, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return json_decode($response[0], true);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get user from ID */
|
||||
function getUserFromId($id){
|
||||
$response = callAPIRoute("/users/$id/userfromid", 1, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return json_decode($response[0], true);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get user from ID */
|
||||
function getUserIdFromUsername($usernameUser){
|
||||
$response = callAPIRoute("/users/$id/useridfromusername", 1, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return json_decode($response[0], true);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get user photo path from ID */
|
||||
function getUserPhotoFromID($id){
|
||||
$response = callAPIRoute("/users/$id/userphotofromid", 0, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return json_decode($response[0], true);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get user photo path aux from ID */
|
||||
function getUserPhotoAuxFromID($id){
|
||||
$response = callAPIRoute("/users/$id/userphotoauxfromid", 0, 0, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return json_decode($response[0], true);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Creates a new user */
|
||||
function newUser($name, $username, $email, $password, $gender, $preferred_language, $city, $birthdate, $access_type, $photo_path, $photo_path_aux, $is_active){
|
||||
if(getUserFromUsername($username) != NULL){
|
||||
return -3;
|
||||
}
|
||||
|
||||
$response = callAPIRoute("/users/create", 0, 4, json_encode(array(
|
||||
'name' => $name,
|
||||
'username' => $username,
|
||||
'email' => $email,
|
||||
'password' => hash("sha256",$password),
|
||||
'preferred_language' => $preferred_language,
|
||||
'city' => $city,
|
||||
'birthdate' => $birthdate,
|
||||
'gender' => $gender,
|
||||
'access_type' => $access_type,
|
||||
'photo_path' => $photo_path,
|
||||
'photo_path_aux' => $photo_path_aux,
|
||||
'is_active' => $is_active,
|
||||
)));
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return 0;
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Edit user */
|
||||
function editUser($name, $username, $email, $id, $preferred_language, $city, $birthdate, $gender, $access_type, $photo_path, $photo_path_aux, $is_active){
|
||||
$response = callAPIRoute("/users/$id/edit", 0, 3, json_encode(array(
|
||||
'name' => $name,
|
||||
'username' => $username,
|
||||
'email' => $email,
|
||||
'preferred_language' => $preferred_language,
|
||||
'city' => $city,
|
||||
'birthdate' => $birthdate,
|
||||
'gender' => $gender,
|
||||
'access_type' => $access_type,
|
||||
'photo_path' => $photo_path,
|
||||
'photo_path_aux' => $photo_path_aux,
|
||||
'is_active' => $is_active,
|
||||
)));
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return 0;
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Unset user photo */
|
||||
function unsetUserPhoto($id){
|
||||
$response = callAPIRoute("/users/$id/delete-photo", 0, 3, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return 0;
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Deletes a user based on its ID */
|
||||
function deleteUser($id){
|
||||
$response = callAPIRoute("/users/$id/delete", 0, 1, NULL);
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return 0;
|
||||
} else {
|
||||
if ($response[1] === 409) {
|
||||
return -409;
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
21
frontend/inc/func/waypoints-funcs.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/* ************************************************************************** */
|
||||
/* Waypoints */
|
||||
/* ************************************************************************** */
|
||||
function newWaypoint($activityID, $waypoints){
|
||||
#$response = callAPIRoute("/waypoints/create/$activityID", 0, 4, array(
|
||||
# 'waypoints' => json_encode($waypoints),
|
||||
#));
|
||||
#echo json_encode($waypoints);
|
||||
$response = callAPIRoute("/waypoints/create/$activityID", 0, 4, json_encode($waypoints));
|
||||
if ($response[0] === false) {
|
||||
return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
return 0;
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
9
frontend/inc/sqlFunctions.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
require_once $_SERVER['DOCUMENT_ROOT']."/inc/func/main-api-funcs.php";
|
||||
require_once $_SERVER['DOCUMENT_ROOT']."/inc/func/session-funcs.php";
|
||||
require_once $_SERVER['DOCUMENT_ROOT']."/inc/func/users-funcs.php";
|
||||
require_once $_SERVER['DOCUMENT_ROOT']."/inc/func/gear-funcs.php";
|
||||
require_once $_SERVER['DOCUMENT_ROOT']."/inc/func/activities-funcs.php";
|
||||
require_once $_SERVER['DOCUMENT_ROOT']."/inc/func/waypoints-funcs.php";
|
||||
require_once $_SERVER['DOCUMENT_ROOT']."/inc/func/strava-funcs.php";
|
||||
?>
|
||||
410
frontend/index.php
Executable file
@@ -0,0 +1,410 @@
|
||||
<?php
|
||||
if(!isset($_SESSION)){
|
||||
session_start();
|
||||
}
|
||||
|
||||
require_once $_SERVER['DOCUMENT_ROOT']."/inc/sqlFunctions.php";
|
||||
|
||||
$page="index";
|
||||
|
||||
if(!isLogged()){
|
||||
header("Location: ../login.php");
|
||||
}
|
||||
|
||||
if(!isTokenValid($_SESSION["token"])){
|
||||
header("Location: ../logout.php?sessionExpired=1");
|
||||
}
|
||||
|
||||
#header("Location: ../gear/gears.php");
|
||||
|
||||
// Load the language file based on the user's preferred language
|
||||
switch ($_SESSION["preferred_language"]) {
|
||||
case 'en':
|
||||
$translationsIndex = include $_SERVER['DOCUMENT_ROOT'].'/lang/index/en.php';
|
||||
break;
|
||||
case 'pt':
|
||||
$translationsIndex = include $_SERVER['DOCUMENT_ROOT'].'/lang/index/pt.php';
|
||||
break;
|
||||
// ...
|
||||
default:
|
||||
$translationsIndex = include $_SERVER['DOCUMENT_ROOT'].'/lang/index/en.php';
|
||||
|
||||
}
|
||||
|
||||
// activities
|
||||
$numActivities = 0;
|
||||
$activities = [];
|
||||
$pageNumberActivities = 1;
|
||||
$addActivityAction = -9000;
|
||||
$editActivityAction = -9000;
|
||||
$deleteActivityAction = -9000;
|
||||
|
||||
// general
|
||||
$numRecords = 5;
|
||||
|
||||
/* Add action */
|
||||
if(isset($_POST["addActivity"]) && $_GET["addActivity"] == 1){
|
||||
$fileExtension = pathinfo($_FILES["activityGpxFileAdd"]["name"], PATHINFO_EXTENSION);
|
||||
if ($fileExtension == "gpx") {
|
||||
$addActivityAction = parseActivityGPX($_FILES["activityGpxFileAdd"]["tmp_name"]);
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($_GET["pageNumberActivities"])){
|
||||
$pageNumberActivities = $_GET["pageNumberActivities"];
|
||||
}
|
||||
|
||||
if(!isset($_POST["activitySearch"])){
|
||||
$activities = getUserActivitiesPagination($pageNumberActivities, $numRecords);
|
||||
$numActivities = numUserActivities();
|
||||
$total_pages = ceil($numActivities / $numRecords);
|
||||
}else{
|
||||
#$activities = getGearFromName(urlencode(trim($_POST["gearNickname"])));
|
||||
#if($activities == NULL){
|
||||
# $numActivities=0;
|
||||
#}else{
|
||||
# $numActivities=1;
|
||||
#}
|
||||
}
|
||||
|
||||
$thisWeekDistances = getUserActivitiesThisWeekDistances($_SESSION["id"]);
|
||||
?>
|
||||
|
||||
<?php require_once $_SERVER['DOCUMENT_ROOT']."/inc/Template-Top.php" ?>
|
||||
|
||||
<div class="container mt-4">
|
||||
<!--<h1><?php echo $translationsIndex['index_title']; ?></h1>-->
|
||||
</div>
|
||||
|
||||
<!-- Page Container -->
|
||||
<div class="container mt-4">
|
||||
<div class="row row-gap-3">
|
||||
<!-- sidebar zone -->
|
||||
<div class="col-lg-3 col-md-12">
|
||||
<div class="d-none d-lg-block mt-3 mb-3 d-flex justify-content-center">
|
||||
<div class="justify-content-center d-flex">
|
||||
<img src=<?php if(is_null($_SESSION["photo_path"])){
|
||||
if($_SESSION["gender"] == 1){
|
||||
echo ("../img/avatar/male1.png");
|
||||
}else{
|
||||
echo ("../img/avatar/female1.png");
|
||||
}
|
||||
}else{
|
||||
echo ($_SESSION["photo_path"]);
|
||||
}?> alt="userPicture" class="rounded-circle" width="120" height="120">
|
||||
</div>
|
||||
<div class="text-center mt-3 mb-3 fw-bold">
|
||||
<a href="../settings/settings.php?profileSettings=1"><?php echo $_SESSION["name"]; ?></a>
|
||||
</div>
|
||||
|
||||
<!-- this week distances zone -->
|
||||
<span class="fw-lighter"><?php echo $translationsIndex['index_userZone_thisWeekDistances_title']; ?></span>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="fw-lighter"><?php echo $translationsIndex['index_userZone_thisWeekDistances_run']; ?></span>
|
||||
<br>
|
||||
<?php if($thisWeekDistances["run"] != null){ ?>
|
||||
<?php echo number_format(($thisWeekDistances["run"] / 1000),2); ?> km
|
||||
<?php }else{ ?>
|
||||
0 km
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div class="col border-start border-opacity-50">
|
||||
<span class="fw-lighter"><?php echo $translationsIndex['index_userZone_thisWeekDistances_bike']; ?></span>
|
||||
<br>
|
||||
<?php if($thisWeekDistances["bike"] != null){ ?>
|
||||
<?php echo number_format(($thisWeekDistances["bike"] / 1000),2); ?> km
|
||||
<?php }else{ ?>
|
||||
0 km
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div class="col border-start border-opacity-50">
|
||||
<span class="fw-lighter"><?php echo $translationsIndex['index_userZone_thisWeekDistances_swim']; ?></span>
|
||||
<br>
|
||||
<?php if($thisWeekDistances["swim"] != null){ ?>
|
||||
<?php if($thisWeekDistances["swim"] > 10000){ ?>
|
||||
<?php echo number_format(($thisWeekDistances["swim"] / 1000),2); ?> km
|
||||
<?php }else{ ?>
|
||||
<?php echo $thisWeekDistances["swim"]; ?> m
|
||||
<?php } ?>
|
||||
<?php }else{ ?>
|
||||
0 m
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="w-100 btn btn-primary" href="#" role="button" data-bs-toggle="modal" data-bs-target="#addActivityModal"><?php echo $translationsIndex['index_sidebar_addActivity']; ?></a>
|
||||
|
||||
<!-- Modal add actvity -->
|
||||
<div class="modal fade" id="addActivityModal" tabindex="-1" aria-labelledby="addActivityModal" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="addActivityModal"><?php echo $translationsIndex['index_sidebar_addActivity']; ?></h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form action="../index.php?addActivity=1" method="post" enctype="multipart/form-data">
|
||||
<div class="modal-body">
|
||||
|
||||
<!-- date fields -->
|
||||
<label for="activityGpxFileAdd"><b>* <?php echo $translationsIndex['index_sidebar_addActivity_modal_addGpxFile_placeholder']; ?></b></label>
|
||||
<input class="form-control" type="file" name="activityGpxFileAdd" accept=".gpx" placeholder="<?php echo $translationsIndex['index_sidebar_addActivity_modal_addGpxFile_placeholder']; ?>" value="<?php echo($_POST["activityGpxFileAdd"]); ?>" required>
|
||||
* <?php echo $translationsTemplateTop['template_top_global_requiredFields']; ?>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo $translationsTemplateTop['template_top_global_close']; ?></button>
|
||||
<button type="submit" class="btn btn-success" name="addActivity"><?php echo $translationsIndex['index_sidebar_addActivity']; ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<!-- Error banners -->
|
||||
<?php if($activities == -1 || $activities == -2 || $addActivityAction == -1 || $addActivityAction == -2 || $addActivityAction == -3 || $addActivityAction == -4 || $_GET["invalidActivity"] == 1){ ?>
|
||||
<div class="alert alert-danger alert-dismissible d-flex align-items-center" role="alert">
|
||||
<i class="fa-solid fa-circle-exclamation me-1"></i>
|
||||
<div>
|
||||
<?php if($activities == -1 || $addActivityAction == -1){ ?>
|
||||
API ERROR | <?php echo $translationsIndex['index_sidebar_addActivity_API_error_-1']; ?> (-1).
|
||||
<?php }else{ ?>
|
||||
<?php if($activities == -2 || $addActivityAction == -2){ ?>
|
||||
API ERROR | <?php echo $translationsIndex['index_sidebar_addActivity_API_error_-2']; ?> (-2).
|
||||
<?php }else{ ?>
|
||||
<?php if($addActivityAction == -3){ ?>
|
||||
<?php echo $translationsIndex['index_sidebar_addActivity_fileExtensionNotSupported_-3']; ?> (-3).
|
||||
<?php }else{ ?>
|
||||
<?php if($addActivityAction == -4){ ?>
|
||||
<?php echo $translationsIndex['index_sidebar_addActivity_GPXError_-4']; ?> (-4).
|
||||
<?php }else{ ?>
|
||||
<?php if($_GET["invalidActivity"] == 1){ ?>
|
||||
<?php echo $translationsIndex['index_sidebar_invalidActivity']; ?>.
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<!-- Info banners -->
|
||||
<?php if($activities == NULL){ ?>
|
||||
<div class="alert alert-warning alert-dismissible d-flex align-items-center" role="alert">
|
||||
<i class="fa-solid fa-triangle-exclamation me-1"></i>
|
||||
<div>
|
||||
<?php if($activities == NULL){ ?>
|
||||
<?php echo $translationsIndex['index_sidebar_addActivity_info_searchActivity_NULL']; ?> (NULL).
|
||||
<?php } ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<!-- Success banners -->
|
||||
<?php if($addActivityAction == 0 || $_GET["deleteActivity"] == 1){ ?>
|
||||
<div class="alert alert-success alert-dismissible d-flex align-items-center" role="alert">
|
||||
<div>
|
||||
<i class="fa-regular fa-circle-check me-1"></i>
|
||||
<?php if($addActivityAction == 0){ ?>
|
||||
<?php echo $translationsIndex['index_sidebar_addActivity_success_activityAdded']; ?>
|
||||
<?php }else{ ?>
|
||||
<?php if($_GET["deleteActivity"] == 1){ ?>
|
||||
<?php echo $translationsIndex['index_sidebar_addActivity_success_activityDeleted']; ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<!--<div class="btn-group mb-3 d-flex" role="group" aria-label="Activities radio toggle button group">
|
||||
<input type="radio" class="btn-check" name="btnradio" id="btnRadioUserActivities" autocomplete="off" checked>
|
||||
<label class="btn btn-outline-primary w-100" for="btnRadioUserActivities"><?php echo $translationsIndex['activity_radio_userActivities']; ?></label>
|
||||
|
||||
<input type="radio" class="btn-check" name="btnradio" id="btnRadioFollowersActivities" autocomplete="off">
|
||||
<label class="btn btn-outline-primary w-100" for="btnRadioFollowersActivities"><?php echo $translationsIndex['activity_radio_followersActivities']; ?></label>
|
||||
</div>-->
|
||||
|
||||
<div id="userActivitiesDiv" style="display: block;">
|
||||
<!-- user activities list -->
|
||||
<?php foreach($activities as $activity){ ?>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="d-flex align-items-center">
|
||||
<img src=<?php if(is_null($_SESSION["photo_path"])){
|
||||
if($_SESSION["gender"] == 1){
|
||||
echo ("../img/avatar/male1.png");
|
||||
}else{
|
||||
echo ("../img/avatar/female1.png");
|
||||
}
|
||||
}else{
|
||||
echo ($_SESSION["photo_path"]);
|
||||
}?> alt="userPicture" class="rounded-circle" width="55" height="55">
|
||||
<div class="ms-3 me-3">
|
||||
<div class="fw-bold">
|
||||
<a href="activities/activity.php?activityID=<?php echo ($activity["id"]); ?>" class="link-underline-opacity-25 link-underline-opacity-100-hover"><?php echo ($activity["name"]); ?></a>
|
||||
</div>
|
||||
<h7><?php if($activity["activity_type"] == 1){
|
||||
echo '<i class="fa-solid fa-person-running"></i>';
|
||||
}else{
|
||||
if($activity["activity_type"] == 4 || $activity["activity_type"] == 5 || $activity["activity_type"] == 6 || $activity["activity_type"] == 8){
|
||||
echo '<i class="fa-solid fa-person-biking"></i>';
|
||||
}else{
|
||||
if($activity["activity_type"] == 7){
|
||||
echo '<i class="fa-solid fa-person-biking"></i> (Virtual)';
|
||||
}else{
|
||||
if($activity["activity_type"] == 9){
|
||||
echo '<i class="fa-solid fa-person-swimming"></i>';
|
||||
}else{
|
||||
if($activity["activity_type"] == 10){
|
||||
echo '<i class="fa-solid fa-dumbbell"></i>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} ?> <?php echo (new DateTime($activity["start_time"]))->format("d/m/y"); ?>@<?php echo (new DateTime($activity["start_time"]))->format("H:i"); ?><?php if(isset($activity["city"]) || isset($activity["country"])){ echo " - "; }?><?php if(isset($activity["city"]) && !empty($activity["city"])){ echo $activity["city"].", " ; }?><?php if(isset($activity["country"]) && !empty($activity["country"])){ echo $activity["country"]; } ?></h7>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row d-flex mt-3">
|
||||
<div class="col">
|
||||
<span class="fw-lighter"><?php echo $translationsIndex['index_activities_detail_distance']; ?></span>
|
||||
<br>
|
||||
<?php if($activity["activity_type"] != 9){ ?>
|
||||
<?php echo number_format(($activity["distance"] / 1000),2); ?> km
|
||||
<?php }else{ ?>
|
||||
<?php echo ($activity["distance"]); ?> m
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div class="col border-start border-opacity-50">
|
||||
<span class="fw-lighter"><?php echo $translationsIndex['index_activities_detail_time']; ?></span>
|
||||
<br>
|
||||
<?php
|
||||
#echo $activity["start_time"];
|
||||
#echo $activity["end_time"];
|
||||
$startDateTime = DateTime::createFromFormat("Y-m-d\TH:i:s", $activity["start_time"]);
|
||||
$endDateTime = DateTime::createFromFormat("Y-m-d\TH:i:s", $activity["end_time"]);
|
||||
$interval = $startDateTime->diff($endDateTime);
|
||||
|
||||
if ($interval->h < 1) {
|
||||
// If the difference is less than one hour
|
||||
echo $interval->i . "m " . $interval->s . "s";
|
||||
} else {
|
||||
// If the difference is one hour or more
|
||||
echo $interval->h . "h " . $interval->i . "m";
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="col border-start border-opacity-50">
|
||||
<?php if($activity["activity_type"] != 9 && $activity["activity_type"] != 1){ ?>
|
||||
<span class="fw-lighter"><?php echo $translationsIndex['index_activities_detail_elevation_gain']; ?></span>
|
||||
<br>
|
||||
<?php echo ($activity["elevation_gain"]); ?> m
|
||||
<?php }else{ ?>
|
||||
<?php if($activity["activity_type"] == 1 || $activity["activity_type"] == 2 || $activity["activity_type"] == 3){ ?>
|
||||
<span class="fw-lighter"><?php echo $translationsIndex['index_activities_detail_pace']; ?></span>
|
||||
<br>
|
||||
<?php echo floor(($activity["pace"]*1000)/60).":".number_format((((($activity["pace"]*1000)/60) - floor(($activity["pace"]*1000)/60)) * 60),0); ?> min/km
|
||||
<?php }else{ ?>
|
||||
<?php if($activity["activity_type"] == 9){ ?>
|
||||
<span class="fw-lighter"><?php echo $translationsIndex['index_activities_detail_pace']; ?></span>
|
||||
<br>
|
||||
<?php echo floor(($activity["pace"]*100)/60).":".number_format((((($activity["pace"]*100)/60) - floor(($activity["pace"]*100)/60)) * 60),0); ?> min/km
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php if($activity["activity_type"] != 10 && $activity["activity_type"] != 9){ ?>
|
||||
<div class="ms-3 me-3 <?php if($activity['strava_activity_id'] == null){ echo "mb-3"; } ?>" id="map_<?php echo $activity['id']; ?>" style="height: 300px"></div>
|
||||
<?php } ?>
|
||||
<?php if($activity['strava_activity_id'] != null){ ?>
|
||||
<div class="mb-3">
|
||||
<span class="fw-lighter ms-3 me-3"><?php echo $translationsIndex['index_activities_stravaText1']; ?><a href="https://www.strava.com/activities/<?php echo $activity['strava_activity_id']; ?>" target="_blank" rel="noopener noreferrer"><?php echo $translationsIndex['index_activities_stravaText2']; ?></a></span>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<br>
|
||||
<script>
|
||||
// JavaScript code to create the map for this activity
|
||||
var waypoints = <?php echo json_encode($activity['waypoints']); ?>;
|
||||
var mapId = "map_<?php echo $activity['id']; ?>";
|
||||
|
||||
var map = L.map(mapId, {
|
||||
dragging: false, // Disable panning
|
||||
touchZoom: false, // Disable touch zoom
|
||||
scrollWheelZoom: false, // Disable scroll wheel zoom
|
||||
zoomControl: false // Remove zoom control buttons
|
||||
});
|
||||
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
maxZoom: 19,
|
||||
}).addTo(map);
|
||||
|
||||
var latlngs = waypoints.map(function(waypoint) {
|
||||
return [waypoint.lat, waypoint.lon];
|
||||
});
|
||||
|
||||
L.polyline(latlngs, { color: 'blue' }).addTo(map);
|
||||
|
||||
// Calculate the bounds of the polyline and fit the map to those bounds
|
||||
var bounds = L.latLngBounds(latlngs);
|
||||
map.fitBounds(bounds);
|
||||
|
||||
// Add green dot for the first waypoint
|
||||
L.marker([waypoints[0].lat, waypoints[0].lon], { icon: L.divIcon({ className: 'bg-success dot' }) }).addTo(map);
|
||||
|
||||
// Add red dot for the last waypoint
|
||||
L.marker([waypoints[waypoints.length - 1].lat, waypoints[waypoints.length - 1].lon], { icon: L.divIcon({ className: 'bg-danger dot' }) }).addTo(map);
|
||||
</script>
|
||||
<?php } ?>
|
||||
|
||||
<?php if(!isset($_POST["activitySearch"])){ ?>
|
||||
<br>
|
||||
<nav>
|
||||
<ul class="pagination justify-content-center">
|
||||
<li class="page-item <?php if($pageNumberActivities == 1){ echo "disabled"; } ?>"><a class="page-link" href="?pageNumberActivities=1">«</a></li>
|
||||
<?php for ($i = 1; $i <= $total_pages; $i++) { ?>
|
||||
<li class="page-item <?php if($i == $pageNumberActivities){ echo "active"; } ?>"><a class="page-link" href="?pageNumberActivities=<?php echo ($i);?>"><?php echo ($i);?></a></li>
|
||||
<?php } ?>
|
||||
<li class="page-item <?php if($pageNumberActivities == $total_pages){ echo "disabled"; } ?>"><a class="page-link" href="?pageNumberActivities=<?php echo ($total_pages);?>">»</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
||||
<div class="card" id="followersActivitiesDiv" style="display: none;">
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Get references to the radio buttons and the div elements
|
||||
const userActivitiesRadio = document.getElementById('btnRadioUserActivities');
|
||||
const followersActivitiesRadio = document.getElementById('btnRadioFollowersActivities');
|
||||
const userActivitiesDiv = document.getElementById('userActivitiesDiv');
|
||||
const followersActivitiesDiv = document.getElementById('followersActivitiesDiv');
|
||||
|
||||
// Add a change event listener to the radio buttons
|
||||
userActivitiesRadio.addEventListener('change', () => {
|
||||
userActivitiesDiv.style.display = 'block';
|
||||
followersActivitiesDiv.style.display = 'none';
|
||||
});
|
||||
|
||||
followersActivitiesRadio.addEventListener('change', () => {
|
||||
userActivitiesDiv.style.display = 'none';
|
||||
followersActivitiesDiv.style.display = 'block';
|
||||
});
|
||||
</script>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Page Container -->
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<?php require_once $_SERVER['DOCUMENT_ROOT']."/inc/Template-Bottom.php" ?>
|
||||
50
frontend/lang/activities/en.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
//activity.php translations
|
||||
return [
|
||||
// title zone
|
||||
"activity_title" => "Activity",
|
||||
// error banner zone
|
||||
"activity_addEditGear_API_error_-1" => "Connection to API not possible. Failed to execute cURL request",
|
||||
"activity_addEditGear_API_error_-2" => "API return code was not 200",
|
||||
// success banner zone
|
||||
"activity_success_gearAdded" => "Gear added to activity",
|
||||
"activity_success_gearEdited" => "Activity gear edited",
|
||||
"activity_success_gearDeleted" => "Activity gear deleted",
|
||||
// activity title
|
||||
"activity_title_dropdown_seeItOnStrava" => "See it on Strava",
|
||||
"activity_title_dropdown_deleteActivity" => "Delete Activity",
|
||||
"activity_title_dropdown_deleteActivity_modal_body" => "Are you sure you want to delete activity",
|
||||
// activity details
|
||||
"activity_detail_distance" => "Distance",
|
||||
"activity_detail_time" => "Time",
|
||||
"activity_detail_elevationGain" => "Elevation gain",
|
||||
"activity_detail_elevationLoss" => "Elevation loss",
|
||||
"activity_detail_pace" => "pace",
|
||||
"activity_detail_avgSpeed" => "Avg speed",
|
||||
"activity_detail_avgPower" => "Avg power",
|
||||
// other gear
|
||||
"activity_gear_title" => "Gear",
|
||||
"activity_gear_notset" => "Gear not set for this activity",
|
||||
// add gear
|
||||
"activity_gear_addGear_title" => "Add gear to activity",
|
||||
"activity_gear_addGear_label" => "Select gear",
|
||||
"activity_gear_addGear_submit" => "Add gear",
|
||||
// edit gear
|
||||
"activity_gear_editGear_title" => "Edit activity gear",
|
||||
"activity_gear_editGear_submit" => "Edit gear",
|
||||
// delete gear zone
|
||||
"activity_gear_deleteGear_title" => "Delete activity gear",
|
||||
"activity_gear_deleteGear_body" => "Are you sure you want to delete activity gear",
|
||||
// data graph
|
||||
"activity_dataGraph_dataSelection" => "Data selection",
|
||||
"activity_dataGraph_hr" => "Heart Rate",
|
||||
"activity_dataGraph_cad" => "Cadence",
|
||||
"activity_dataGraph_power" => "Power",
|
||||
"activity_dataGraph_ele" => "Elevation",
|
||||
"activity_dataGraph_vel" => "Velocity",
|
||||
"activity_dataGraph_pace" => "Pace",
|
||||
"activity_dataGraph_title" => "Data graph",
|
||||
"activity_dataGraph_downsampleDataInfo" => "Downsample data (200 points)"
|
||||
];
|
||||
?>
|
||||
46
frontend/lang/gear/gear/en.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
//gear.php translations
|
||||
return [
|
||||
// error banner zone
|
||||
"gear_API_error_-1" => "Connection to API not possible. Failed to execute cURL request",
|
||||
"gear_API_error_-2" => "API return code was not 200",
|
||||
// success banner zone
|
||||
"gear_success_gearEdited" => "Gear edited.",
|
||||
// gear info zone
|
||||
"gear_gear_infoZone_isactive" => "Active",
|
||||
"gear_gear_infoZone_isinactive" => "Inactive",
|
||||
"gear_gear_infoZone_gearisbike" => "Bike",
|
||||
"gear_gear_infoZone_gearisshoe" => "Shoes",
|
||||
"gear_gear_infoZone_geariswetsuit" => "Wetsuit",
|
||||
// edit zone
|
||||
"gear_gear_infoZone_editbutton" => "Edit gear",
|
||||
"gear_gear_infoZone_modal_editGear_brandLabel" => "Brand",
|
||||
"gear_gear_infoZone_modal_editGear_brandPlaceholder" => "Brand (max 45 characters)",
|
||||
"gear_gear_infoZone_modal_editGear_modelLabel" => "Model",
|
||||
"gear_gear_infoZone_modal_editGear_modelPlaceholder" => "Model (max 45 characters)",
|
||||
"gear_gear_infoZone_modal_editGear_nicknameLabel" => "Nickname",
|
||||
"gear_gear_infoZone_modal_editGear_nicknamePlaceholder" => "Nickname (max 45 characters)",
|
||||
"gear_gear_infoZone_modal_editGear_gearTypeLabel" => "Gear type",
|
||||
"gear_gear_infoZone_modal_editGear_gearTypeOption1" => "Bike",
|
||||
"gear_gear_infoZone_modal_editGear_gearTypeOption2" => "Shoes",
|
||||
"gear_gear_infoZone_modal_editGear_gearTypeOption3" => "Wetsuit",
|
||||
"gear_gear_infoZone_modal_editGear_dateLabel" => "Created date",
|
||||
"gear_gear_infoZone_modal_editGear_datePlaceholder" => "Date",
|
||||
"gear_gear_infoZone_modal_editGear_gearIsActiveLabel" => "Is active",
|
||||
"gear_gear_infoZone_modal_editGear_gearIsActiveOption1" => "Yes",
|
||||
"gear_gear_infoZone_modal_editGear_gearIsActiveOption2" => "No",
|
||||
// delete zone
|
||||
"gear_gear_infoZone_modal_deleteGear_body" => "Are you sure you want to delete gear",
|
||||
"gear_gear_infoZone_deletebutton" => "Delete gear",
|
||||
// details
|
||||
"gear_gear_infoZone_distance" => "Distance",
|
||||
"gear_gear_infoZone_brand" => "Brand",
|
||||
"gear_gear_infoZone_model" => "Model",
|
||||
// gear activities
|
||||
"gear_gear_gearActivities_noactivities" => "Gear is not linked to any activity",
|
||||
"gear_gear_gearActivities_title" => "Gear activities",
|
||||
"gear_gear_gearActivities_number" => "(last 10 activities)",
|
||||
"gear_gear_gearActivities_datelabel" => "Date"
|
||||
];
|
||||
?>
|
||||
61
frontend/lang/gear/gears/en.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
//gears.php translations
|
||||
return [
|
||||
// title zone
|
||||
"gear_title" => "Gear",
|
||||
// error banner zone
|
||||
"gear_gear_API_error_-1" => "Connection to API not possible. Failed to execute cURL request",
|
||||
"gear_gear_API_error_-2" => "API return code was not 200",
|
||||
"gear_gear_error_addGear_-3" => "Nickname already exists. Please verify nickname",
|
||||
"gear_gear_error_editGear_-3" => "Nickname and type field required",
|
||||
// info banner zone
|
||||
"gear_gear_info_searchGear_NULL" => "Gear not found",
|
||||
"gear_gear_info_fromGear_invalidGear" => "Gear not found",
|
||||
// success banner zone
|
||||
"gear_gear_success_gearAdded" => "Gear added.",
|
||||
"gear_gear_success_gearEdited" => "Gear edited.",
|
||||
"gear_gear_success_gearDeleted" => "Gear deleted.",
|
||||
// add gear zone
|
||||
"gear_gear_buttonLabel_addGear" => "Add gear:",
|
||||
"gear_gear_button_addGear" => "Add gear",
|
||||
"gear_gear_modal_addGear_title" => "Add gear",
|
||||
"gear_gear_modal_addEditGear_brandLabel" => "Brand",
|
||||
"gear_gear_modal_addEditGear_brandPlaceholder" => "Brand (max 45 characters)",
|
||||
"gear_gear_modal_addEditGear_modelLabel" => "Model",
|
||||
"gear_gear_modal_addEditGear_modelPlaceholder" => "Model (max 45 characters)",
|
||||
"gear_gear_modal_addEditGear_nicknameLabel" => "Nickname",
|
||||
"gear_gear_modal_addEditGear_nicknamePlaceholder" => "Nickname (max 45 characters)",
|
||||
"gear_gear_modal_addEditUser_gearTypeLabel" => "Gear type",
|
||||
"gear_gear_modal_addEditUser_gearTypeOption1" => "Bike",
|
||||
"gear_gear_modal_addEditUser_gearTypeOption2" => "Shoes",
|
||||
"gear_gear_modal_addEditUser_gearTypeOption3" => "Wetsuit",
|
||||
"gear_gear_modal_addEditGear_dateLabel" => "Created date",
|
||||
"gear_gear_modal_addEditGear_datePlaceholder" => "Date",
|
||||
// search gear zone
|
||||
"gear_gear_buttonLabel_searchGear" => "Search gear by nickname:",
|
||||
"gear_gear_button_searchGear" => "Search",
|
||||
"gear_gear_form_searchGear_nicknamePlaceholder" => "Nickname",
|
||||
// list gears
|
||||
// error banner zone
|
||||
"gear_gear_error_listGear_-1-2" => "It was not possible to list gear",
|
||||
// info banner zone
|
||||
"gear_gear_error_listGear_-3" => "Gear does not exist",
|
||||
// list
|
||||
"gear_gear_list_title1" => "There is a total of",
|
||||
"gear_gear_list_title2" => " gear(s)",
|
||||
"gear_gear_list_title3" => " per page)",
|
||||
"gear_gear_gear_type" => "Type: ",
|
||||
"gear_gear_list_isactive" => "Active",
|
||||
"gear_gear_list_isinactive" => "Inactive",
|
||||
"gear_gear_list_button_components" => "Gear components",
|
||||
// edit gear zone
|
||||
"gear_gear_modal_editGear_title" => "Edit gear",
|
||||
"gear_gear_modal_editUser_gearIsActiveLabel" => "Is active",
|
||||
"gear_gear_modal_editUser_gearIsActiveOption1" => "Yes",
|
||||
"gear_gear_modal_editUser_gearIsActiveOption2" => "No",
|
||||
// delete gear zone
|
||||
"gear_gear_modal_deleteGear_title" => "Delete gear",
|
||||
"gear_gear_modal_deleteGear_body" => "Are you sure you want to delete gear"
|
||||
];
|
||||
?>
|
||||
17
frontend/lang/inc/Template-Top/en.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
//Template-Top.php translations
|
||||
return [
|
||||
"template_top_navbar_gear" => "Gear",
|
||||
"template_top_navbar_login" => "Login",
|
||||
"template_top_navbar_profile" => "Profile",
|
||||
"template_top_navbar_settings" => "Settings",
|
||||
"template_top_navbar_logout" => "Logout",
|
||||
// back section
|
||||
"template_top_global_back" => "Back",
|
||||
"template_top_global_requiredFields" => "Required field(s)",
|
||||
"template_top_global_close" => "Close",
|
||||
"template_top_global_button_listAll" => "List all",
|
||||
"template_top_warning_zone" => "Alpha software, some features might not work has expected"
|
||||
];
|
||||
?>
|
||||
37
frontend/lang/index/en.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
//index.php translations
|
||||
return [
|
||||
// title zone
|
||||
"index_title" => "Feed",
|
||||
"index_userZone_thisWeekDistances_title" => "This week distances",
|
||||
"index_userZone_thisWeekDistances_run" => "Run",
|
||||
"index_userZone_thisWeekDistances_bike" => "Bike",
|
||||
"index_userZone_thisWeekDistances_swim" => "Swim",
|
||||
// add activity
|
||||
"index_sidebar_addActivity" => "Add Activity",
|
||||
"index_sidebar_addActivity_modal_addGpxFile_placeholder" => "Add GPX activity",
|
||||
// error banner zone
|
||||
"index_sidebar_addActivity_API_error_-1" => "Connection to API not possible. Failed to execute cURL request",
|
||||
"index_sidebar_addActivity_API_error_-2" => "API return code was not 200",
|
||||
"index_sidebar_addActivity_GPXError_-3" => "Invalid GPX file or could not load the file",
|
||||
"index_sidebar_addActivity_GPXError_-4" => "Invalid GPX file or could not load the file",
|
||||
"index_sidebar_invalidActivity" => "Invalid activity. Activity ID not valid or you might not have access to see it",
|
||||
// info banner zone
|
||||
"index_sidebar_addActivity_info_searchActivity_NULL" => "Activities not found",
|
||||
// success banner zone
|
||||
"index_sidebar_addActivity_success_activityAdded" => "Activity added.",
|
||||
"index_sidebar_addActivity_success_activityDeleted" => "Activity deleted.",
|
||||
// radio zone
|
||||
"activity_radio_userActivities" => "My activities",
|
||||
"activity_radio_followersActivities" => "Followers activities",
|
||||
// activities zone
|
||||
"index_activities_type_title" => "Activity added.",
|
||||
"index_activities_detail_distance" => "Distance",
|
||||
"index_activities_detail_time" => "Time",
|
||||
"index_activities_detail_elevation_gain" => "Elevation gain",
|
||||
"index_activities_detail_pace" => "Pace",
|
||||
"index_activities_stravaText1" => "Strava activitity, see it ",
|
||||
"index_activities_stravaText2" => "here"
|
||||
];
|
||||
?>
|
||||
15
frontend/lang/login/en.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
//login.php translations
|
||||
return [
|
||||
"login_info_session expired" => "User session expired",
|
||||
"login_error" => "Unable to login. Check username and password",
|
||||
"login_API_error_-1" => "Connection to API not possible. Failed to execute cURL request",
|
||||
"login_API_error_-2" => "API return code was not 200",
|
||||
"login_API_error_-3" => "User state is inactive. Unable to login",
|
||||
"login_insert_username" => "Insert username",
|
||||
"login_password" => "Password",
|
||||
"login_neverExpires" => "Remember login",
|
||||
"login_login" => "Login"
|
||||
// Add more translations here
|
||||
];
|
||||
?>
|
||||
243
frontend/lang/settings/en.php
Normal file
@@ -0,0 +1,243 @@
|
||||
<?php
|
||||
|
||||
//settings.php translations
|
||||
return [
|
||||
// title zone
|
||||
"settings_title" => "Settings",
|
||||
"settings_sidebar_spaces" => "Spaces",
|
||||
"settings_sidebar_rooms" => "Rooms",
|
||||
"settings_sidebar_users" => "Users",
|
||||
"settings_sidebar_global" => "Global settings",
|
||||
"settings_sidebar_profileSettings" => "Profile settings",
|
||||
"settings_sidebar_gearSettings" => "Gear",
|
||||
// error banner zone
|
||||
"settings_API_error_-1" => "Connection to API not possible. Failed to execute cURL request",
|
||||
"settings_API_error_-2" => "API return code was not 200",
|
||||
"settings_sidebar_spaces_error_deletespace_-3" => "Cannot delete space due to existing dependencies",
|
||||
"settings_sidebar_rooms_error_deleteroom_-3" => "Cannot delete room due to existing dependencies",
|
||||
"settings_sidebar_spaces_error_addSpace_-3" => "Space name already exists. Please verify name",
|
||||
"settings_sidebar_rooms_error_addRoom_-3" => "Room name already exists. Please verify name",
|
||||
"settings_sidebar_spaces_error_editSpace_-3" => "Name is mandatory",
|
||||
"settings_sidebar_spaces_error_addEditSpace_-4" => "Photo path invalid",
|
||||
"settings_sidebar_spaces_error_addEditSpace_-5" => "Only photos with extension .jpg, .jpeg e .png are allowed",
|
||||
"settings_sidebar_spaces_error_addEditSpace_-6" => "It was not possible to upload photo",
|
||||
"settings_sidebar_spaces_error_deleteSpacePhoto_-3" => "It was not possible to delete space photo on filesystem. Database not updated",
|
||||
"settings_sidebar_rooms_error_deleteRoomPhoto_-3" => "It was not possible to delete room photo on filesystem. Database not updated",
|
||||
"settings_sidebar_profile_error_deleteProfilePhoto_-3" => "It was not possible to delete profile photo on filesystem. Database not updated",
|
||||
"settings_sidebar_users_error_addUser_-3" => "Username already exists. Please verify username",
|
||||
"settings_sidebar_users_error_addEditUser_-4" => "Photo path invalid",
|
||||
"settings_sidebar_users_error_addEditUser_-5" => "Only photos with extension .jpg, .jpeg e .png are allowed",
|
||||
"settings_sidebar_users_error_addEditUser_-6" => "It was not possible to upload photo",
|
||||
"settings_sidebar_users_error_editUser_-3" => "Username and type field required",
|
||||
"settings_sidebar_users_error_deleteUser_-3" => "User cannot delete himself",
|
||||
"settings_sidebar_users_error_deleteUser_-409" => "User has dependencies. It is not possible to delete",
|
||||
"settings_sidebar_users_error_deleteUserPhoto_-3" => "It was not possible to delete user photo on filesystem. Database not updated",
|
||||
// info banner zone
|
||||
"settings_sidebar_spaces_info_searchSpace_NULL" => "Space not found",
|
||||
"settings_sidebar_spaces_info_spaces_NULL" => "There is no spaces inserted",
|
||||
"settings_sidebar_spaces_info_listSpace_-3" => "Space does not exist",
|
||||
"settings_sidebar_spaces_info_spaceDeleted_photoNotDeleted" => "Space deleted. It was not possible to delete space photo from filesystem.",
|
||||
"settings_sidebar_rooms_info_searchRoom_NULL" => "Room not found",
|
||||
"settings_sidebar_rooms_info_rooms_NULL" => "There is no rooms inserted",
|
||||
"settings_sidebar_rooms_info_listRoom_-3" => "Room does not exist",
|
||||
"settings_sidebar_rooms_info_roomDeleted_photoNotDeleted" => "Room deleted. It was not possible to delete room photo from filesystem.",
|
||||
"settings_sidebar_users_info_userDeleted_photoNotDeleted" => "User deleted. It was not possible to delete user photo from filesystem.",
|
||||
"settings_sidebar_users_error_searchUser_NULL" => "User not found",
|
||||
// success banner zone
|
||||
"settings_sidebar_spaces_success_spaceDeleted" => "Space deleted.",
|
||||
"settings_sidebar_spaces_success_spaceAdded" => "Space added.",
|
||||
"settings_sidebar_spaces_success_spaceEdited" => "Space edited.",
|
||||
"settings_sidebar_spaces_success_spacePhotoDeleted" => "Space photo deleted.",
|
||||
"settings_sidebar_rooms_success_roomDeleted" => "Room deleted.",
|
||||
"settings_sidebar_rooms_success_roomAdded" => "Room added.",
|
||||
"settings_sidebar_rooms_success_roomEdited" => "Room edited.",
|
||||
"settings_sidebar_rooms_success_roomPhotoDeleted" => "Room photo deleted.",
|
||||
"settings_sidebar_profile_success_profilePhotoDeleted" => "Profile photo deleted.",
|
||||
"settings_sidebar_profile_success_profileEdited" => "Profile edited",
|
||||
"settings_sidebar_profile_success_stravaLinked" => "Strava linked with success",
|
||||
"settings_sidebar_users_success_userAdded" => "User added.",
|
||||
"settings_sidebar_users_success_userEdited" => "User edited.",
|
||||
"settings_sidebar_users_success_userDeleted" => "User deleted.",
|
||||
"settings_sidebar_users_success_userPhotoDeleted" => "User photo deleted.",
|
||||
// spaces zone
|
||||
"settings_sidebar_spaces_new" => "New space",
|
||||
"settings_sidebar_spaces_search" => "Search",
|
||||
"settings_sidebar_spaces_modal_addSpace_title" => "Add space",
|
||||
"settings_sidebar_spaces_modal_addEditSpace_photoLabel" => "Space photo",
|
||||
"settings_sidebar_spaces_modal_addEditSpace_nameLabel" => "Name",
|
||||
"settings_sidebar_spaces_modal_addEditSpace_namePlaceholder" => "Name (max 45 characters)",
|
||||
"settings_sidebar_spaces_modal_addEditSpace_cityLabel" => "Town/city",
|
||||
"settings_sidebar_spaces_modal_addEditSpace_cityPlaceholder" => "Town/city (max 45 characters)",
|
||||
"settings_sidebar_spaces_modal_addEditSpace_addressLabel" => "Address",
|
||||
"settings_sidebar_spaces_modal_addEditSpace_addressPlaceholder" => "Address (max 45 characters)",
|
||||
// spaces list
|
||||
"settings_sidebar_spaces_list_title1" => "There is a total of",
|
||||
"settings_sidebar_spaces_list_title2" => " space(s)",
|
||||
"settings_sidebar_spaces_list_title3" => " per page)",
|
||||
"settings_sidebar_spaces_list_numberofrooms" => "Number of rooms: ",
|
||||
// add space zone
|
||||
"settings_sidebar_button_addSpace" => "Add space",
|
||||
// edit space zone
|
||||
"settings_sidebar_button_editSpace_title" => "Edit space",
|
||||
// delete space/room photo zone
|
||||
"settings_sidebar_modal_editSpaceRoom_deleteSpaceRoomPhoto" => "Delete photo",
|
||||
// search space/room zone
|
||||
"settings_sidebar_form_searchSpaceRoomUser_namePlaceholder" => "Search",
|
||||
"settings_sidebar_form_searchSpace_namePlaceholder" => "Name",
|
||||
// delete space modal zone
|
||||
"settings_sidebar_modal_deleteSpace_title" => "Delete space",
|
||||
"settings_sidebar_modal_deleteSpace_body" => "Are you sure you want to delete space",
|
||||
// room zone
|
||||
"settings_sidebar_rooms_new" => "New room",
|
||||
// add room zone
|
||||
"settings_sidebar_button_addRoom" => "Add room",
|
||||
// edit room zone
|
||||
"settings_sidebar_button_editRoom_title" => "Edit room",
|
||||
// rooms zone
|
||||
"settings_sidebar_rooms_new" => "New room",
|
||||
"settings_sidebar_rooms_modal_addRoom_title" => "Add room",
|
||||
"settings_sidebar_rooms_modal_addEditRoom_photoLabel" => "Room photo",
|
||||
"settings_sidebar_rooms_modal_addEditRoom_nameLabel" => "Name",
|
||||
"settings_sidebar_rooms_modal_addEditRoom_namePlaceholder" => "Name (max 45 characters)",
|
||||
"settings_sidebar_rooms_modal_addEditRoom_spaceLabel" => "Space which room belongs",
|
||||
// room list
|
||||
"settings_sidebar_rooms_list_title1" => "There is a total of",
|
||||
"settings_sidebar_rooms_list_title2" => " room(s)",
|
||||
"settings_sidebar_rooms_list_title3" => " per page)",
|
||||
"settings_sidebar_rooms_list_spaceName" => "Space: ",
|
||||
// delete room modal zone
|
||||
"settings_sidebar_modal_deleteRoom_title" => "Delete room",
|
||||
"settings_sidebar_modal_deleteRoom_body" => "Are you sure you want to delete room",
|
||||
// users zone
|
||||
"settings_sidebar_users_new" => "New user",
|
||||
"settings_sidebar_users_search" => "Search",
|
||||
// add room zone
|
||||
"settings_sidebar_button_addUser" => "Add user",
|
||||
// add user modal
|
||||
"settings_sidebar_users_modal_addUser_title" => "Add user",
|
||||
"settings_sidebar_users_modal_addEditUser_photoLabel" => "User photo",
|
||||
"settings_sidebar_users_modal_addEditUser_usernameLabel" => "Username",
|
||||
"settings_sidebar_users_modal_addEditUser_usernamePlaceholder" => "Username (max 45 characters)",
|
||||
"settings_sidebar_users_modal_addEditUser_emailLabel" => "Email",
|
||||
"settings_sidebar_users_modal_addEditUser_emailPlaceholder" => "Email (max 45 characters)",
|
||||
"settings_sidebar_users_modal_addEditUser_nameLabel" => "Name",
|
||||
"settings_sidebar_users_modal_addEditUser_namePlaceholder" => "Name (max 45 characters)",
|
||||
"settings_sidebar_users_modal_addEditUser_passwordLabel" => "Password",
|
||||
"settings_sidebar_users_modal_addEditUser_passwordPlaceholder" => "Password",
|
||||
"settings_sidebar_users_modal_addEditUser_cityLabel" => "Town/city",
|
||||
"settings_sidebar_users_modal_addEditUser_cityPlaceholder" => "Town/city (max 45 characters)",
|
||||
"settings_sidebar_users_modal_addEditUser_birthdateLabel" => "Birth date",
|
||||
"settings_sidebar_users_modal_addEditUser_genderLabel" => "User gender",
|
||||
"settings_sidebar_users_modal_addEditUser_genderOption1" => "Male",
|
||||
"settings_sidebar_users_modal_addEditUser_genderOption2" => "Female",
|
||||
"settings_sidebar_users_modal_addEditUser_preferredLanguageLabel" => "User prefered language",
|
||||
"settings_sidebar_users_modal_addEditUser_preferredLanguageOption1" => "English",
|
||||
"settings_sidebar_users_modal_addEditUser_preferredLanguageOption2" => "Portuguese",
|
||||
"settings_sidebar_users_modal_addEditUser_typeLabel" => "User type",
|
||||
"settings_sidebar_users_modal_addEditUser_typeOption1" => "Regular user",
|
||||
"settings_sidebar_users_modal_addEditUser_typeOption2" => "Administrator",
|
||||
"settings_sidebar_users_modal_addEditUser_notesLabel" => "Notes",
|
||||
"settings_sidebar_users_modal_addEditUser_notesPlaceholder" => "Notes (max 250 characters)",
|
||||
"settings_sidebar_users_modal_addEditUser_isActiveLabel" => "Is active",
|
||||
"settings_sidebar_users_modal_addEditUser_isActiveOption1" => "Yes",
|
||||
"settings_sidebar_users_modal_addEditUser_isActiveOption2" => "No",
|
||||
// search space/room zone
|
||||
"settings_sidebar_form_searchUser_usernamePlaceholder" => "Username",
|
||||
// users list
|
||||
"settings_sidebar_users_list_title1" => "There is a total of",
|
||||
"settings_sidebar_users_list_title2" => " user(s)",
|
||||
"settings_sidebar_users_list_title3" => " per page)",
|
||||
"settings_sidebar_users_list_user_accesstype" => "Access type: ",
|
||||
"settings_sidebar_users_list_isactive" => "Active",
|
||||
"settings_sidebar_users_list_isinactive" => "Inactive",
|
||||
// edit user zone
|
||||
"settings_sidebar_users_modal_editUser_title" => "Edit user",
|
||||
// delete user photo zone
|
||||
"settings_sidebar_users_modal_editUser_deleteUserPhoto" => "Delete photo",
|
||||
// delete user zone
|
||||
"settings_sidebar_users_modal_deleteUser_title" => "Delete user",
|
||||
"settings_sidebar_users_modal_deleteUser_body" => "Are you sure you want to delete user",
|
||||
|
||||
// edit profile modal zone
|
||||
"settings_sidebar_profile_editProfile_title" => "Edit profile",
|
||||
"settings_sidebar_profile_photo_label" => "Profile photo",
|
||||
"settings_sidebar_profile_username_label" => "Username",
|
||||
"settings_sidebar_profile_username_placeholder" => "Username (max 45 characters)",
|
||||
"settings_sidebar_profile_name_label" => "Name",
|
||||
"settings_sidebar_profile_name_placeholder" => "Name (max 45 characters)",
|
||||
"settings_sidebar_profile_email_label" => "Email",
|
||||
"settings_sidebar_profile_email_placeholder" => "Email (max 45 characters)",
|
||||
"settings_sidebar_profile_city_label" => "Town/city",
|
||||
"settings_sidebar_profile_city_placeholder" => "Town/city (max 45 characters)",
|
||||
"settings_sidebar_profile_birthdate_label" => "Birth date",
|
||||
"settings_sidebar_profile_gender_label" => "Gender",
|
||||
"settings_sidebar_profile_gender_option1" => "Male",
|
||||
"settings_sidebar_profile_gender_option2" => "Female",
|
||||
"settings_sidebar_profile_preferredLanguage_label" => "Prefered language",
|
||||
"settings_sidebar_profile_preferredLanguage_option1" => "English",
|
||||
"settings_sidebar_profile_preferredLanguage_option2" => "Portuguese",
|
||||
// profile zone
|
||||
"settings_sidebar_profile_deleteProfilePhoto" => "Delete profile photo",
|
||||
"settings_sidebar_profile_modal_title_deleteProfilePhoto" => "Delete profile photo",
|
||||
"settings_sidebar_profile_modal_body_deleteProfilePhoto" => "Are you sure you want to delete the profile photo?",
|
||||
"settings_sidebar_profile_button_editprofile" => "Edit profile",
|
||||
"settings_sidebar_profile_gender_male" => "Male",
|
||||
"settings_sidebar_profile_gender_female" => "Female",
|
||||
"settings_sidebar_profile_access_type_regular_user" => "Regular user",
|
||||
"settings_sidebar_profile_access_type_admin" => "Admin",
|
||||
"settings_sidebar_profile_username_subtitle" => "Username: ",
|
||||
"settings_sidebar_profile_email_subtitle" => "Email: ",
|
||||
"settings_sidebar_profile_gender_subtitle" => "Gender: ",
|
||||
"settings_sidebar_profile_birthdate_subtitle" => "Birthdate: ",
|
||||
"settings_sidebar_profile_city_subtitle" => "City: ",
|
||||
"settings_sidebar_profile_access_type_subtitle" => "Access type: ",
|
||||
"settings_sidebar_profile_preferredlanguage_subtitle" => "Preferred language: ",
|
||||
// gear zone
|
||||
// error banner zone
|
||||
"settings_sidebar_gear_API_error_-1" => "Connection to API not possible. Failed to execute cURL request",
|
||||
"settings_sidebar_gear_API_error_-2" => "API return code was not 200",
|
||||
"settings_sidebar_gear_error_addGear_-3" => "Nickname already exists. Please verify nickname",
|
||||
"settings_sidebar_gear_error_editGear_-3" => "Nickname and type field required",
|
||||
// info banner zone
|
||||
"settings_sidebar_gear_info_searchGear_NULL" => "Gear not found",
|
||||
"settings_sidebar_gear_info_fromGear_invalidGear" => "Gear not found",
|
||||
// success banner zone
|
||||
"settings_sidebar_gear_success_gearAdded" => "Gear added.",
|
||||
"settings_sidebar_gear_success_gearEdited" => "Gear edited.",
|
||||
"settings_sidebar_gear_success_gearDeleted" => "Gear deleted.",
|
||||
// add and edit gear zone modal
|
||||
"settings_sidebar_gear_buttonLabel_addGear" => "Add gear:",
|
||||
"settings_sidebar_gear_button_addGear" => "Add gear",
|
||||
"settings_sidebar_gear_modal_addGear_title" => "Add gear",
|
||||
"settings_sidebar_gear_modal_addEditGear_brandLabel" => "Brand",
|
||||
"settings_sidebar_gear_modal_addEditGear_brandPlaceholder" => "Brand (max 45 characters)",
|
||||
"settings_sidebar_gear_modal_addEditGear_modelLabel" => "Model",
|
||||
"settings_sidebar_gear_modal_addEditGear_modelPlaceholder" => "Model (max 45 characters)",
|
||||
"settings_sidebar_gear_modal_addEditGear_nicknameLabel" => "Nickname",
|
||||
"settings_sidebar_gear_modal_addEditGear_nicknamePlaceholder" => "Nickname (max 45 characters)",
|
||||
"settings_sidebar_gear_modal_addEditGear_gearTypeLabel" => "Gear type",
|
||||
"settings_sidebar_gear_modal_addEditGear_gearTypeOption1" => "Bike",
|
||||
"settings_sidebar_gear_modal_addEditGear_gearTypeOption2" => "Shoes",
|
||||
"settings_sidebar_gear_modal_addEditGear_gearTypeOption3" => "Wetsuit",
|
||||
"settings_sidebar_gear_modal_addEditGear_dateLabel" => "Created date",
|
||||
"settings_sidebar_gear_modal_addEditGear_datePlaceholder" => "Date",
|
||||
// search gear zone
|
||||
"settings_sidebar_gear_button_searchGear" => "Search",
|
||||
"settings_sidebar_gear_form_searchGear_nicknamePlaceholder" => "Nickname",
|
||||
// list
|
||||
"settings_sidebar_gear_list_title1" => "There is a total of",
|
||||
"settings_sidebar_gear_list_title2" => " gear(s)",
|
||||
"settings_sidebar_gear_list_title3" => " per page)",
|
||||
"settings_sidebar_settings_sidebar_gear_type" => "Type: ",
|
||||
"settings_sidebar_gear_list_isactive" => "Active",
|
||||
"settings_sidebar_gear_list_isinactive" => "Inactive",
|
||||
// edit gear zone
|
||||
"settings_sidebar_gear_modal_editGear_title" => "Edit gear",
|
||||
"settings_sidebar_gear_modal_editGear_gearIsActiveLabel" => "Is active",
|
||||
"settings_sidebar_gear_modal_editGear_gearIsActiveOption1" => "Yes",
|
||||
"settings_sidebar_gear_modal_editGear_gearIsActiveOption2" => "No",
|
||||
// delete gear zone
|
||||
"settings_sidebar_gear_modal_deleteGear_title" => "Delete gear",
|
||||
"settings_sidebar_gear_modal_deleteGear_body" => "Are you sure you want to delete gear"
|
||||
];
|
||||
?>
|
||||
114
frontend/login.php
Executable file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
if(!isset($_SESSION)){
|
||||
session_start();
|
||||
}
|
||||
|
||||
require_once $_SERVER['DOCUMENT_ROOT']."/inc/sqlFunctions.php";
|
||||
|
||||
$page="login";
|
||||
|
||||
if(isLogged()){
|
||||
header("Location: ../index.php");
|
||||
}
|
||||
|
||||
// Load the language file based on the user's preferred language
|
||||
/*switch ($_SESSION["preferred_language"]) {
|
||||
case 'en':
|
||||
$translationsLogin = include $_SERVER['DOCUMENT_ROOT'].'/lang/login/en.php';
|
||||
break;
|
||||
case 'pt':
|
||||
$translationsLogin = include $_SERVER['DOCUMENT_ROOT'].'/lang/login/pt.php';
|
||||
break;*/
|
||||
// ...
|
||||
//default:
|
||||
$translationsLogin = include $_SERVER['DOCUMENT_ROOT'].'/lang/login/en.php';
|
||||
//}
|
||||
|
||||
$error = 0;
|
||||
|
||||
if(isset($_POST["loginUsername"]) && isset($_POST["loginPassword"])) {
|
||||
clearUserRelatedInfoSession();
|
||||
$hashPassword = hash("sha256",$_POST["loginPassword"]);
|
||||
$neverExpires = false;
|
||||
if (isset($_POST["loginNeverExpires"]) && $_POST["loginNeverExpires"] === "on") {
|
||||
$neverExpires = true;
|
||||
}
|
||||
$result = loginUser($_POST["loginUsername"], $hashPassword, $neverExpires);
|
||||
$response = json_decode($result, true);
|
||||
if (isset($response['access_token'])) {
|
||||
$error = setUserRelatedInfoSession($response['access_token']);
|
||||
if ($error == 0){
|
||||
header("Location: ../index.php");
|
||||
die();
|
||||
}
|
||||
} else {
|
||||
$error = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#$random_number = mt_rand(1, 2);
|
||||
?>
|
||||
|
||||
<?php require_once $_SERVER['DOCUMENT_ROOT']."/inc/Template-Top.php" ?>
|
||||
|
||||
<main class="form-signin w-100 m-auto text-center p-5" style="max-width: 500px">
|
||||
<!-- Info banners -->
|
||||
<?php if($_GET["sessionExpired"] == 1){ ?>
|
||||
<div class="alert alert-warning alert-dismissible d-flex align-items-center" role="alert">
|
||||
<i class="fa-solid fa-triangle-exclamation me-1"></i>
|
||||
<div>
|
||||
<?php if($_GET["sessionExpired"] == 1){ ?>
|
||||
<?php echo $translationsLogin['login_info_session expired']; ?>.
|
||||
<?php } ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
<?php if($error == 1 || $error == -1 || $error == -3 || $error == -3){ ?>
|
||||
<div class="alert alert-danger alert-dismissible d-flex align-items-center" role="alert">
|
||||
<i class="fa-solid fa-circle-exclamation me-1"></i>
|
||||
<div>
|
||||
<?php if($error == 1){ ?>
|
||||
<?php echo $translationsLogin['login_error']; ?> (1).
|
||||
<?php }else{ ?>
|
||||
<?php if($error == -1){ ?>
|
||||
<?php echo $translationsLogin['login_API_error_-1']; ?> (-1).
|
||||
<?php }else{ ?>
|
||||
<?php if($error == -2){ ?>
|
||||
<?php echo $translationsLogin['login_API_error_-2']; ?> (-2).
|
||||
<?php }else{ ?>
|
||||
<?php if($error == -3){ ?>
|
||||
<?php echo $translationsLogin['login_API_error_-3']; ?> (-3).
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
<form action="../login.php" method="post">
|
||||
<!--<img class="mb-4 rounded-circle" src="../img/avatar/<?php if($random_number == 1){ echo ("female1"); }else{ echo ("male1"); } ?>.png" alt="avatar" width="150" height="150">-->
|
||||
<img class="mb-4" src="../img/logo/logo.png" alt="app logo" width="200" height="200">
|
||||
<br>
|
||||
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control" id="floatingInput" placeholder="<?php echo $translationsLogin['login_insert_username']; ?>" name="loginUsername" required>
|
||||
<label for="loginUsername"><?php echo $translationsLogin['login_insert_username']; ?></label>
|
||||
</div>
|
||||
<br>
|
||||
<div class="form-floating">
|
||||
<input type="password" class="form-control" placeholder="<?php echo $translationsLogin['login_password']; ?>" name="loginPassword" required>
|
||||
<label for="loginPassword"><?php echo $translationsLogin['login_password']; ?></label>
|
||||
</div>
|
||||
<br>
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" name="loginNeverExpires">
|
||||
<label class="form-check-label" for="loginNeverExpires"><?php echo $translationsLogin['login_neverExpires']; ?></label>
|
||||
</div>
|
||||
<br>
|
||||
<button class="w-100 btn btn-lg btn-primary" type="submit"><?php echo $translationsLogin['login_login']; ?></button>
|
||||
</form>
|
||||
</main>
|
||||
|
||||
<?php require_once $_SERVER['DOCUMENT_ROOT']."/inc/Template-Bottom.php" ?>
|
||||
24
frontend/logout.php
Executable file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
require_once $_SERVER['DOCUMENT_ROOT']."/inc/sqlFunctions.php";
|
||||
if(!isset($_SESSION)){
|
||||
session_start();
|
||||
}
|
||||
|
||||
$response = callAPIRoute("/logout/{$_SESSION["id"]}", 1, 1, NULL);
|
||||
if ($response[0] === false) {
|
||||
#return -1;
|
||||
} else {
|
||||
if ($response[1] === 200) {
|
||||
#return json_decode($response[0], true);
|
||||
} else {
|
||||
#return -2;
|
||||
}
|
||||
}
|
||||
|
||||
clearUserRelatedInfoSession();
|
||||
if(isset($_GET["sessionExpired"])){
|
||||
header("location: ../login.php?sessionExpired=1");
|
||||
}else{
|
||||
header("location: ../login.php");
|
||||
}
|
||||
?>
|
||||