diff --git a/CHANGELOG.md b/CHANGELOG.md index fe566d3..caa1970 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ et le versionnage suit [SemVer](https://semver.org/lang/fr/). ## [Non publié] ### Ajouté +- Page publique de téléchargement des applications mobiles Android / iOS (`/telecharger`). - Système de tickets connecté à Gitea : création, suivi de l'avancement (état, jalon, labels), fil de discussion et réponses depuis l'interface web. - Pipeline d'intégration continue Gitea Actions (tests, Pint, audit de sécurité). - Pipeline de déploiement continu (build image → registre Gitea → webhook Portainer). diff --git a/WEB/.env.example b/WEB/.env.example index 7f78dee..cca7c42 100644 --- a/WEB/.env.example +++ b/WEB/.env.example @@ -68,4 +68,10 @@ GITEA_URL=https://gitea.sam-coffre.duckdns.org GITEA_TOKEN= GITEA_REPO=sam/cesizen +# --- Applications mobiles (page /telecharger) --- +MOBILE_ANDROID_URL= +MOBILE_IOS_URL= +MOBILE_ANDROID_VERSION=1.0.0 +MOBILE_IOS_VERSION=1.0.0 + VITE_APP_NAME="${APP_NAME}" diff --git a/WEB/.env.production.example b/WEB/.env.production.example index 3a09051..509bb3d 100644 --- a/WEB/.env.production.example +++ b/WEB/.env.production.example @@ -59,4 +59,11 @@ GITEA_URL=https://gitea.sam-coffre.duckdns.org GITEA_TOKEN= # token Gitea avec le scope write:issue GITEA_REPO=sam/cesizen +# ── Applications mobiles (page /telecharger) ───────────────── +# Liens de store (prioritaires) ou dépôt des binaires dans public/downloads/. +MOBILE_ANDROID_URL= +MOBILE_IOS_URL= +MOBILE_ANDROID_VERSION=1.0.0 +MOBILE_IOS_VERSION=1.0.0 + VITE_APP_NAME="${APP_NAME}" diff --git a/WEB/.gitignore b/WEB/.gitignore index 09ee516..63f6069 100644 --- a/WEB/.gitignore +++ b/WEB/.gitignore @@ -18,6 +18,8 @@ /public/storage /storage/*.key /storage/pail +/public/downloads/*.apk +/public/downloads/*.ipa /vendor Homestead.json Homestead.yaml diff --git a/WEB/app/Http/Controllers/Web/DownloadController.php b/WEB/app/Http/Controllers/Web/DownloadController.php new file mode 100644 index 0000000..8fb4d4b --- /dev/null +++ b/WEB/app/Http/Controllers/Web/DownloadController.php @@ -0,0 +1,45 @@ + $this->resoudre('android'), + 'ios' => $this->resoudre('ios'), + ]); + } + + /** + * Détermine, pour une plateforme, le lien de téléchargement et sa disponibilité. + * + * @return array{version: string, url: string|null, disponible: bool} + */ + private function resoudre(string $plateforme): array + { + $config = config("mobile.{$plateforme}"); + if (! is_array($config)) { + $config = []; + } + + $version = is_string($config['version'] ?? null) ? $config['version'] : '1.0.0'; + $url = (is_string($config['url'] ?? null) && $config['url'] !== '') ? $config['url'] : null; + $file = is_string($config['file'] ?? null) ? $config['file'] : null; + + // À défaut d'URL explicite, on propose le fichier précompilé s'il existe. + if ($url === null && $file !== null && file_exists(public_path($file))) { + $url = asset($file); + } + + return [ + 'version' => $version, + 'url' => $url, + 'disponible' => $url !== null, + ]; + } +} diff --git a/WEB/config/mobile.php b/WEB/config/mobile.php new file mode 100644 index 0000000..4f6a5fa --- /dev/null +++ b/WEB/config/mobile.php @@ -0,0 +1,29 @@ + [ + 'version' => env('MOBILE_ANDROID_VERSION', '1.0.0'), + 'url' => env('MOBILE_ANDROID_URL'), + 'file' => 'downloads/cesizen.apk', + ], + + 'ios' => [ + 'version' => env('MOBILE_IOS_VERSION', '1.0.0'), + 'url' => env('MOBILE_IOS_URL'), + 'file' => 'downloads/cesizen.ipa', + ], + +]; diff --git a/WEB/public/downloads/README.md b/WEB/public/downloads/README.md new file mode 100644 index 0000000..c235727 --- /dev/null +++ b/WEB/public/downloads/README.md @@ -0,0 +1,25 @@ +# Applications mobiles précompilées + +Déposez ici les binaires servis par la page **/telecharger** : + +- `cesizen.apk` — application Android +- `cesizen.ipa` — application Apple (iOS) + +La page détecte automatiquement la présence de ces fichiers. + +## Alternative : liens de store + +Plutôt que des fichiers locaux, vous pouvez renseigner des liens (Play Store, +App Store, TestFlight…) dans le fichier `.env` du serveur : + +``` +MOBILE_ANDROID_URL=https://play.google.com/store/apps/details?id=... +MOBILE_IOS_URL=https://apps.apple.com/app/id... +MOBILE_ANDROID_VERSION=1.0.0 +MOBILE_IOS_VERSION=1.0.0 +``` + +Si une URL est renseignée, elle est prioritaire sur le fichier local. +Si ni URL ni fichier ne sont disponibles, le bouton affiche « Bientôt disponible ». + +> Les binaires (`*.apk`, `*.ipa`) ne sont pas versionnés dans git (voir `.gitignore`). diff --git a/WEB/resources/views/layouts/sidebar.blade.php b/WEB/resources/views/layouts/sidebar.blade.php index e3aba1b..baf7395 100644 --- a/WEB/resources/views/layouts/sidebar.blade.php +++ b/WEB/resources/views/layouts/sidebar.blade.php @@ -62,6 +62,16 @@ @endauth + + routeIs('telecharger') ? 'aria-current="page"' : '' !!}> + + Application mobile + +

Services de l'État

diff --git a/WEB/resources/views/telecharger.blade.php b/WEB/resources/views/telecharger.blade.php new file mode 100644 index 0000000..d13bbe9 --- /dev/null +++ b/WEB/resources/views/telecharger.blade.php @@ -0,0 +1,77 @@ +@extends('layouts.app') + +@section('title', "Télécharger l'application") + +@section('content') +
+ + +
+

📱 Télécharger l'application CESIZen

+

+ Emportez CESIZen partout avec vous. Choisissez votre plateforme et installez + l'application mobile pour suivre votre bien-être au quotidien. +

+
+ +
+ + {{-- Carte Android --}} +
+
+ 🤖 +
+

Android

+

Version {{ $android['version'] }}

+ + @if ($android['disponible']) +
+ ⬇️ Télécharger (.apk) + +

+ Sur Android, autorisez l'installation depuis « sources inconnues » si nécessaire. +

+ @else + + @endif +
+ + {{-- Carte iOS --}} +
+
+ 🍏 +
+

Apple (iOS)

+

Version {{ $ios['version'] }}

+ + @if ($ios['disponible']) + + ⬇️ Télécharger + +

+ L'installation d'un fichier .ipa nécessite TestFlight ou un profil adapté. +

+ @else + + @endif +
+ +
+ + +
+@endsection diff --git a/WEB/routes/web.php b/WEB/routes/web.php index 943a013..004aefb 100644 --- a/WEB/routes/web.php +++ b/WEB/routes/web.php @@ -3,6 +3,7 @@ use App\Http\Controllers\DashboardController; use App\Http\Controllers\Web\AuthController; use App\Http\Controllers\Web\DiagnosticController; +use App\Http\Controllers\Web\DownloadController; use App\Http\Controllers\Web\EmotionController; use App\Http\Controllers\Web\InformationController; use App\Http\Controllers\Web\ProfileController; @@ -17,6 +18,9 @@ Route::get('/relaxation', [RelaxationController::class, 'index'])->name('relaxat Route::get('/informations', [InformationController::class, 'index'])->name('informations.index'); Route::get('/informations/{id}', [InformationController::class, 'show'])->name('informations.show'); +// Téléchargement des applications mobiles (Android / iOS) +Route::get('/telecharger', [DownloadController::class, 'index'])->name('telecharger'); + // Authentification Route::get('/login', [AuthController::class, 'showLogin'])->name('login'); Route::post('/login', [AuthController::class, 'login']); diff --git a/WEB/tests/Feature/DownloadTest.php b/WEB/tests/Feature/DownloadTest.php new file mode 100644 index 0000000..9de0aa1 --- /dev/null +++ b/WEB/tests/Feature/DownloadTest.php @@ -0,0 +1,41 @@ +get('/telecharger') + ->assertOk() + ->assertSee('Android') + ->assertSee('Apple'); + } + + #[Test] + public function un_lien_de_store_configure_est_propose() + { + config(['mobile.android.url' => 'https://play.google.com/store/apps/details?id=fr.cesizen']); + + $this->get('/telecharger') + ->assertOk() + ->assertSee('play.google.com'); + } + + #[Test] + public function sans_lien_ni_fichier_le_bouton_est_desactive() + { + config(['mobile.ios.url' => null, 'mobile.ios.file' => 'downloads/inexistant.ipa']); + + $this->get('/telecharger') + ->assertOk() + ->assertSee('Bientôt disponible'); + } +}