Author SHA1 Message Date
tezcat c7ce2a1ffb Update README.md 2026-05-21 19:06:22 +02:00
12 changed files with 24 additions and 122 deletions
-1
View File
@@ -1 +0,0 @@
www/config.php
+14 -17
View File
@@ -7,7 +7,6 @@ OpenPlanetsMaps is a project that gathers and structures astronomical data (imag
This project was carried out as part of an exam presided over by **F. LEFEVRE**.
It is hosted and accessible online at the following address: [opm.nhkyllian.fr](https://opm.nhkyllian.fr)
## Database Structure
The core of the project relies on a MySQL/MariaDB database named `OpenPlanetsMaps`. It contains dedicated tables for each major celestial body, allowing data to be isolated and structured (`id`, `date`, `title`, `explanation`, `url`, `media_type`, etc.):
@@ -25,21 +24,19 @@ The core of the project relies on a MySQL/MariaDB database named `OpenPlanetsMap
The system also includes a `CONTACT` table intended to store messages and requests from a potential contact form (email, subject, request, attached file).
## Installation and Configuration
To set up the database locally (for example, with XAMPP, WAMP, or directly via MariaDB/MySQL):
1. Create a new database named `OpenPlanetsMaps` (recommended encoding: `utf8mb4_general_ci`).
2. Import the structure file to initialize the tables:
```bash
mysql -u user -p OpenPlanetsMaps < SRC/DATA/Structure.sql
```
3. Then import the data file to populate the database (currently contains Earth data):
```bash
mysql -u user -p OpenPlanetsMaps < SRC/DATA/DATA.sql
```
## Technologies
- Database: MySQL / MariaDB (generated via phpMyAdmin)
- Frontend: HTML, CSS, JavaScript
- Packaging: Electron Packager
- CI/CD: GitHub Actions
- Data format: JSON
## Releases (Mobile Apps)
Native mobile applications for this project are now available. You can download them directly from the **Releases** tab of this GitHub repository:
- **Android**: Download the `.apk` file to install the app on your Android device.
- **iOS**: Download the `.ipa` file to install the app on your iOS device.
## Data Source & License
The astronomical data (images, videos, and descriptions) provided in this project is sourced from the public NASA API.
As per NASA's media guidelines, these materials are in the **public domain** and are completely free to use without any royalties.
The code and structure of this project are open-source and entirely free to use.
- Database: MySQL / MariaDB (generated via phpMyAdmin).
View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

+5 -14
View File
@@ -1,12 +1,9 @@
<?php
/* --- SESSION & AUTHENTICATION --- */
session_start();
$config = require_once './config.php';
$error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'login') {
if ($_POST['username'] === $config['admin_user'] && $_POST['password'] === $config['admin_pass']) {
if ($_POST['username'] === 'admin' && $_POST['password'] === 'admin') {
$_SESSION['admin_logged_in'] = true;
header('Location: admin.php');
exit;
@@ -21,14 +18,12 @@ if (isset($_GET['logout'])) {
exit;
}
/* --- DATABASE CONFIGURATION --- */
$host = $config['host'];
$dbname = $config['dbname'];
$db_user = $config['username'];
$db_pass = $config['password'];
$host = '172.22.0.3';
$dbname = 'OpenPlanetsMaps';
$db_user = 'root';
$db_pass = 'admin123';
$message = '';
/* --- FORM PROCESSING & DB INSERTION --- */
if (isset($_SESSION['admin_logged_in']) && $_SESSION['admin_logged_in'] === true && $_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'add') {
try {
$options = [PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8", PDO::ATTR_EMULATE_PREPARES => false];
@@ -62,7 +57,6 @@ if (isset($_SESSION['admin_logged_in']) && $_SESSION['admin_logged_in'] === true
<!DOCTYPE html>
<html lang="en">
<head>
<!-- --- HEAD & STYLES --- -->
<meta charset="UTF-8">
<title>Admin Panel - OpenPlanetsMaps</title>
<link rel="stylesheet" href="style.css">
@@ -81,10 +75,8 @@ if (isset($_SESSION['admin_logged_in']) && $_SESSION['admin_logged_in'] === true
</style>
</head>
<body>
<!-- --- BODY & ADMIN PANEL --- -->
<div class="admin-box">
<?php if (!isset($_SESSION['admin_logged_in']) || $_SESSION['admin_logged_in'] !== true): ?>
<!-- --- LOGIN FORM --- -->
<h1>Admin Login</h1>
<?php if ($error): ?><p style="color: #f87171; text-align: center; margin-bottom: 1rem;"><?= $error ?></p><?php endif; ?>
<form method="POST">
@@ -95,7 +87,6 @@ if (isset($_SESSION['admin_logged_in']) && $_SESSION['admin_logged_in'] === true
</form>
<div class="links"><a href="index.html"> Back to site</a></div>
<?php else: ?>
<!-- --- ADD DATA FORM --- -->
<h1>Add a row</h1>
<?= $message ?>
<form method="POST">
+4 -11
View File
@@ -1,20 +1,16 @@
<?php
header('Content-Type: application/json');
/* --- CONFIGURATION & SETUP --- */
$config = require_once 'config.php';
$host = $config['host'];
$dbname = $config['dbname'];
$username = $config['username'];
$password = $config['password'];
$host = '172.22.0.3';
$dbname = 'OpenPlanetsMaps';
$username = 'root';
$password = 'admin123';
try {
/* --- DATABASE CONNECTION --- */
$options = [PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8", PDO::ATTR_EMULATE_PREPARES => false];
$pdo = new PDO("mysql:host=$host;port=3306;dbname=$dbname;charset=utf8;protocol=tcp", $username, $password, $options);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
/* --- REQUEST HANDLING --- */
$planetId = isset($_GET['planet']) ? $_GET['planet'] : '';
$allowedTables = [
@@ -31,7 +27,6 @@ try {
];
if ($planetId === 'quiz') {
/* --- QUIZ DATA GENERATION --- */
$queries = [];
$seed = date('Ymd');
foreach ($allowedTables as $key => $table) {
@@ -70,7 +65,6 @@ try {
exit;
}
/* --- PLANET DATA FETCHING --- */
if (!array_key_exists($planetId, $allowedTables)) {
echo json_encode([]);
exit;
@@ -83,7 +77,6 @@ try {
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($data);
} catch (PDOException $e) {
/* --- ERROR HANDLING --- */
http_response_code(500);
echo json_encode(['error' => 'Database error: ' . $e->getMessage()]);
}
-6
View File
@@ -1,10 +1,8 @@
<?php
/* --- SESSION & INITIALIZATION --- */
session_start();
$message_status = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
/* --- FORM PROCESSING --- */
$email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
$subject = htmlspecialchars($_POST['objet']);
$message = htmlspecialchars($_POST['demande']);
@@ -13,7 +11,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$file_path = null;
if (isset($_FILES['televersement']) && $_FILES['televersement']['error'] == UPLOAD_ERR_OK) {
/* --- FILE UPLOAD --- */
$file_tmp_name = $_FILES['televersement']['tmp_name'];
$file_name = $_FILES['televersement']['name'];
$file_size = $_FILES['televersement']['size'];
@@ -47,7 +44,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
}
if (!$has_error) {
/* --- DATABASE INSERTION --- */
try {
$host = '172.22.0.3';
$dbname = 'OpenPlanetsMaps';
@@ -71,13 +67,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
<!DOCTYPE html>
<html lang="fr">
<head>
<!-- --- HEAD --- -->
<meta charset="UTF-8">
<title>Contact - OpenPlanetsMaps</title>
<link rel="stylesheet" href="style.css">
</head>
<body class="page-form">
<!-- --- BODY & FORM --- -->
<div class="admin-box">
<h1>Contact</h1>
<?= $message_status ?>
-18
View File
@@ -11,7 +11,6 @@
<body class="theme-home">
<div class="bg-animated"></div>
<!-- HEADER -->
<header>
<div class="menu-icon" onclick="toggleSidebar()"></div>
<h1>Open Planets Maps</h1>
@@ -21,7 +20,6 @@
</div>
</header>
<!-- SIDEBAR -->
<nav id="sidebar" class="sidebar">
<ul>
<li onclick="showLayer('home')">Home</li>
@@ -42,9 +40,7 @@
</ul>
</nav>
<!-- MAIN CONTENT -->
<main id="content-area">
<!-- HOME SECTION -->
<section id="layer-home" class="layer active">
<div class="main-img">
<iframe title="Solar System animation" frameborder="0" allow="autoplay; fullscreen; xr-spatial-tracking" src="https://sketchfab.com/models/b7c69a6b655b47c99f871d5ec5aee854/embed?autostart=1&ui_infos=0&ui_watermark=0&ui_controls=0"></iframe>
@@ -65,7 +61,6 @@
<div class="desc-box">Ready for launch? Open the side menu (☰) and select a destination to begin your journey.</div>
</section>
<!-- MERCURY SECTION -->
<section id="layer-mercury" class="layer">
<div class="search-bar"><input type="text" placeholder="Multi-criteria search..."></div>
<div class="main-img">
@@ -91,7 +86,6 @@
</div>
</section>
<!-- VENUS SECTION -->
<section id="layer-venus" class="layer">
<div class="search-bar"><input type="text" placeholder="Multi-criteria search..."></div>
<div class="main-img">
@@ -117,7 +111,6 @@
</div>
</section>
<!-- EARTH SECTION -->
<section id="layer-earth" class="layer">
<div class="search-bar"><input type="text" placeholder="Multi-criteria search..."></div>
<div class="main-img">
@@ -143,7 +136,6 @@
</div>
</section>
<!-- MARS SECTION -->
<section id="layer-mars" class="layer">
<div class="search-bar"><input type="text" placeholder="Multi-criteria search..."></div>
<div class="main-img">
@@ -169,7 +161,6 @@
</div>
</section>
<!-- JUPITER SECTION -->
<section id="layer-jupiter" class="layer">
<div class="search-bar"><input type="text" placeholder="Multi-criteria search..."></div>
<div class="main-img">
@@ -195,7 +186,6 @@
</div>
</section>
<!-- SATURN SECTION -->
<section id="layer-saturn" class="layer">
<div class="search-bar"><input type="text" placeholder="Multi-criteria search..."></div>
<div class="main-img">
@@ -221,7 +211,6 @@
</div>
</section>
<!-- URANUS SECTION -->
<section id="layer-uranus" class="layer">
<div class="search-bar"><input type="text" placeholder="Multi-criteria search..."></div>
<div class="main-img">
@@ -247,7 +236,6 @@
</div>
</section>
<!-- NEPTUNE SECTION -->
<section id="layer-neptune" class="layer">
<div class="search-bar"><input type="text" placeholder="Multi-criteria search..."></div>
<div class="main-img">
@@ -273,7 +261,6 @@
</div>
</section>
<!-- SUN SECTION -->
<section id="layer-sun" class="layer">
<div class="search-bar"><input type="text" placeholder="Multi-criteria search..."></div>
<div class="main-img">
@@ -302,7 +289,6 @@
</div>
</section>
<!-- MOON SECTION -->
<section id="layer-moon" class="layer">
<div class="search-bar"><input type="text" placeholder="Multi-criteria search..."></div>
<div class="main-img">
@@ -331,7 +317,6 @@
</div>
</section>
<!-- QUIZ SECTION -->
<section id="layer-Quiz" class="layer">
<div class="desc-box">Test your knowledge of the solar system! Answer the questions below to see if you are a true space expert.</div>
@@ -354,12 +339,10 @@
</section>
</main>
<!-- FOOTER -->
<footer class="site-footer" onclick="openCredits()" title="Credits & About">
&copy; 2026 OpenPlanetsMaps. Royalty-free. <span class="footer-credits-hint">— Credits ↗</span>
</footer>
<!-- CREDITS MODAL -->
<div id="credits-overlay"></div>
<div id="credits-panel">
<button class="credits-close" onclick="closeCredits()"></button>
@@ -407,7 +390,6 @@
</div>
</div>
<!-- SCRIPTS -->
<script src="main.js"></script>
</body>
</html>
-6
View File
@@ -1,4 +1,3 @@
/* --- UI & NAVIGATION --- */
function toggleSidebar() {
document.getElementById('sidebar').classList.toggle('open');
}
@@ -25,7 +24,6 @@ function showLayer(layerId) {
const planetData = {};
const planetCols = {};
/* --- SEARCH & FILTERING --- */
function wireSearch(planetId) {
const layer = document.getElementById('layer-' + planetId);
if (!layer) return;
@@ -100,7 +98,6 @@ function filterTable(planetId, query) {
});
}
/* --- API & DATA FETCHING --- */
async function fetchData(planetId) {
const tbody = document.getElementById('tbody-' + planetId);
if (!tbody) return;
@@ -215,7 +212,6 @@ let quizQuestions = [];
let currentQuizIndex = 0;
let quizScore = 0;
/* --- QUIZ SYSTEM --- */
async function initQuiz() {
currentQuizIndex = 0;
quizScore = 0;
@@ -343,7 +339,6 @@ function checkAnswer(selected, correct, btn) {
}, 1800);
}
/* --- CREDITS MODAL --- */
function openCredits() {
document.getElementById('credits-panel').classList.add('open');
document.getElementById('credits-overlay').classList.add('open');
@@ -356,7 +351,6 @@ function closeCredits() {
document.body.style.overflow = '';
}
/* --- INITIALIZATION & MOBILE FALLBACK --- */
document.addEventListener('DOMContentLoaded', () => {
const overlay = document.getElementById('credits-overlay');
if (overlay) overlay.addEventListener('click', closeCredits);
-17
View File
@@ -1,4 +1,3 @@
/* --- FONTS & VARIABLES --- */
@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;600;700&family=Orbitron:wght@400;600;700;900&family=Space+Mono:wght@400;700&display=swap');
:root {
@@ -22,7 +21,6 @@ body.theme-sun { --theme-color:#ffcc44; --theme-glow:rgba(255,180,40,.55);
body.theme-moon { --theme-color:#c8cfe8; --theme-glow:rgba(200,207,232,.35); --theme-subtle:rgba(200,207,232,.06); --bg-deep:#060608; --bg-mid:#0e0f14; --border:rgba(200,207,232,.12); --text-primary:#dde2f0; --text-secondary:#7e8ba8; --text-muted:#3c4258; }
body.theme-Quiz { --theme-color:#7eb8f7; --theme-glow:rgba(126,184,247,.35); --theme-subtle:rgba(126,184,247,.07); --bg-deep:#020510; --bg-mid:#060e24; --border:rgba(126,184,247,.13); --text-primary:#ddeeff; --text-secondary:#6a90b8; --text-muted:#2e4a6a; }
/* --- GLOBAL STYLES --- */
*,*::before,*::after { margin:0; padding:0; box-sizing:border-box; }
html, body { max-width:100vw; overflow-x:hidden; }
@@ -33,7 +31,6 @@ body {
transition:background-color .8s ease, color .3s ease;
}
/* --- ANIMATED BACKGROUND --- */
.bg-animated {
position:fixed; inset:0; z-index:-2;
background:radial-gradient(ellipse at 20% 10%, var(--bg-mid) 0%, var(--bg-deep) 60%);
@@ -96,7 +93,6 @@ body.theme-moon::before {
100% { opacity:.65; }
}
/* --- HEADER --- */
header {
display:flex; justify-content:space-between; align-items:center;
padding:0 2rem; height:64px;
@@ -135,7 +131,6 @@ header h1:hover { animation:glitch .4s steps(1) forwards; }
box-shadow:0 0 12px var(--theme-glow);
}
/* --- SIDEBAR --- */
.sidebar {
position:fixed; top:0; left:-300px; width:280px; height:100vh;
background:rgba(2,6,14,.96); backdrop-filter:blur(24px);
@@ -175,7 +170,6 @@ header h1:hover { animation:glitch .4s steps(1) forwards; }
.sidebar li.menu-category::after { display:none; }
.sidebar li.menu-category:hover { background:none; padding-left:1.75rem; text-shadow:none; color:var(--text-muted); }
/* --- LAYOUT & MAIN CONTENT --- */
#content-area {
flex:1; padding:2.5rem; display:flex;
max-width:1400px; margin:0 auto; width:100%;
@@ -186,7 +180,6 @@ header h1:hover { animation:glitch .4s steps(1) forwards; }
}
.layer.active { display:flex; }
/* --- COMPONENTS (Images, Boxes, Tickers) --- */
.main-img {
margin-bottom:2.5rem; position:relative;
border-radius:12px; overflow:hidden; border:1px solid var(--border);
@@ -266,7 +259,6 @@ header h1:hover { animation:glitch .4s steps(1) forwards; }
}
.ticker:hover { animation-play-state:paused; }
/* --- SEARCH BAR --- */
.search-bar { margin-bottom:2rem; position:relative; display:flex; justify-content:center; }
.search-bar::before {
content:'⌕'; position:absolute; left:calc(50% - 210px); top:50%;
@@ -287,7 +279,6 @@ header h1:hover { animation:glitch .4s steps(1) forwards; }
box-shadow:0 0 20px var(--theme-glow);
}
/* --- DATA TABLES --- */
.table-container { margin-bottom:3rem; }
.data-table { width:100%; max-width:1300px; margin:0 auto; border-collapse:collapse; font-size:.88rem; }
.data-table thead tr { background:rgba(255,255,255,.03); }
@@ -345,7 +336,6 @@ header h1:hover { animation:glitch .4s steps(1) forwards; }
.show-more-btn:hover::before { transform:scaleX(1); }
.show-more-btn:hover { box-shadow:0 0 24px var(--theme-glow); transform:translateY(1px); }
/* --- FOOTER --- */
.site-footer {
text-align:center; padding:1.25rem 2rem;
background:rgba(2,4,8,.7); backdrop-filter:blur(10px);
@@ -360,7 +350,6 @@ header h1:hover { animation:glitch .4s steps(1) forwards; }
.footer-credits-hint { opacity:.5; font-style:italic; transition:opacity .2s; }
.site-footer:hover .footer-credits-hint { opacity:1; color:var(--theme-color); }
/* --- QUIZ SYSTEM --- */
.daily-challenge-box {
margin:0 auto 2rem; max-width:680px; padding:1rem 1.5rem;
background:var(--theme-subtle); border:1px solid var(--border);
@@ -458,7 +447,6 @@ header h1:hover { animation:glitch .4s steps(1) forwards; }
white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
/* --- CREDITS MODAL --- */
#credits-overlay {
position:fixed; inset:0; z-index:2000;
background:rgba(0,0,0,.7); backdrop-filter:blur(6px);
@@ -522,13 +510,11 @@ header h1:hover { animation:glitch .4s steps(1) forwards; }
.credits-footer { padding:1rem 2rem; border-top:1px solid var(--border); font-family:'Space Mono',monospace; font-size:.62rem; letter-spacing:.15em; color:var(--text-muted); flex-shrink:0; }
/* --- SCROLLBAR & SELECTION --- */
::-webkit-scrollbar { width:6px; }
::-webkit-scrollbar-track { background:var(--bg-deep); }
::-webkit-scrollbar-thumb { background:var(--theme-color); border-radius:3px; }
::selection { background:var(--theme-glow); color:#fff; }
/* --- KEYFRAMES --- */
@keyframes layerReveal {
from { opacity:0; transform:translateY(16px); filter:blur(4px); }
to { opacity:1; transform:translateY(0); filter:blur(0); }
@@ -558,8 +544,6 @@ header h1:hover { animation:glitch .4s steps(1) forwards; }
50% { transform:translateX(5px); }
75% { transform:translateX(-3px); }
}
/* --- MEDIA QUERIES --- */
@media (max-width:768px) {
#layer-Quiz .desc-box, #layer-Quiz .daily-challenge-box { display:none; }
}
@@ -578,7 +562,6 @@ header h1:hover { animation:glitch .4s steps(1) forwards; }
#quiz-img-preview img, #quiz-img-preview video { max-height:160px; width:auto; max-width:100%; margin:0 auto; }
}
/* --- ADMIN & FORM PAGES --- */
body.page-form { background-color: #0f172a; color: #e0e0e0; display: flex; flex-direction: row; justify-content: center; align-items: center; padding: 2rem; min-height: 100vh; overflow-x: auto; }
.admin-box { background-color: #1e293b; padding: 2rem; border-radius: 8px; box-shadow: 0 4px 15px rgba(0,0,0,0.5); width: 100%; max-width: 500px; border: 1px solid #334155; }
.admin-box h1 { color: #00bfff; text-align: center; margin-bottom: 1.5rem; }
-31
View File
@@ -1,31 +0,0 @@
# Environnement de Déploiement : AlwaysData
Ce document explique la façon dont j'ai déployé et configuré le projet OpenPlanetsMaps sur mon espace d'hébergement AlwaysData.
## 1. Hébergement et Transfert de fichiers (FTP)
Le site est configuré en tant que site **PHP (version 8.x)** sur AlwaysData.
Pour la mise en ligne, j'ai utilisé le client FTP **FileZilla**. J'ai transféré l'intégralité du contenu de mon dossier local `www/` vers le répertoire racine web de mon serveur AlwaysData à l'aide des accès FTP fournis par l'hébergeur.
## 2. Base de données
L'API et le site s'appuient sur une base de données MySQL/MariaDB hébergée sur AlwaysData.
- J'ai créé la base de données directement depuis le panel AlwaysData.
- J'ai ensuite utilisé l'outil **phpMyAdmin** fourni par l'hébergeur pour importer le script de structure `doc/Structure.sql`, ce qui a généré toutes les tables nécessaires (`EARTH`, `MARS`, ..., `CONTACT`).
- J'ai également importé le fichier `data.sql` via phpMyAdmin afin de peupler la base avec les données astronomiques de chaque planètes.
## 3. Configuration et Variables d'environnement
Pour des raisons de sécurité, les identifiants de la base de données ne sont pas codés en dur dans mes scripts publics. J'ai créé un fichier de configuration `config.php` directement sur le serveur distant, à la racine du site (`www/config.php`).
Ce fichier (non versionné sur GitHub) contient mes variables de production :
le fichier vous sera montré lors de la présentation.
## 4. Vérification finale
Une fois le déploiement terminé, j'ai effectué une série de tests sur ma version finale en production pour m'assurer que tout fonctionnait correctement :
- Accès à l'URL de mon site (ex: `https://openplanetsmaps.alwaysdata.net`).
- Vérification du bon affichage des données des planètes provenant de l'API.
- Test du formulaire de contact (l'insertion en base de données et le téléversement de fichiers sont opérationnels).
- Connexion à la page `/admin.php` avec mes identifiants pour tester l'ajout d'une entrée.
- Test du versionnage téléphone du site pour garantir une bonne adaptabilité sur mobile.
- Vérification minutieuse de l'ensemble du backlog fourni pour m'assurer de la totale conformité du livrable vis-à-vis des attentes de l'examen.
La version finale actuellement en ligne est parfaitement fonctionnelle.