feat: remplacer les étoiles par les réactions dans le hero article
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
## Adobe
|
||||||
|
- [Adobe Reader for Windows - FULL DONWLOAD](http://www.adobe.com/support/downloads/product.jsp?product=10&platform=Windows)
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"uuid": "a63eefea-a7b0-4af3-8500-d9dfa58be8bb",
|
||||||
|
"slug": "logiciels-2",
|
||||||
|
"title": "Logiciels",
|
||||||
|
"author": "cedric.abonnel@gmail.com",
|
||||||
|
"published": true,
|
||||||
|
"published_at": "2020-04-17 18:05:20",
|
||||||
|
"created_at": "2020-04-17 18:05:20",
|
||||||
|
"updated_at": "2020-04-17 18:05:20",
|
||||||
|
"revisions": [],
|
||||||
|
"cover": "",
|
||||||
|
"files_meta": [],
|
||||||
|
"external_links": [],
|
||||||
|
"seo_title": "",
|
||||||
|
"seo_description": "",
|
||||||
|
"og_image": "",
|
||||||
|
"category": "Informatique"
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
Voici les **pré-requis système** (processeur, mémoire, etc.) pour installer **Gitea** sur une distribution **Debian**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **1. Exigences minimales**
|
||||||
|
|
||||||
|
Ces valeurs sont suffisantes pour un petit déploiement personnel ou une petite équipe.
|
||||||
|
|
||||||
|
| Ressource | Minimum recommandé | Détails |
|
||||||
|
| ------------------- | -------------------------------------------- | --------------------------------------------------------------------------------------------- |
|
||||||
|
| **CPU** | 2+ vCPU / cœur | Gitea est léger, même un petit processeur type Atom ou 1 vCPU cloud suffit. |
|
||||||
|
| **RAM** | 1 Go ou + | Le binaire Go est efficace. 1 Go est sûr pour un usage personnel. 2 Go ou plus (pour plusieurs utilisateurs) |
|
||||||
|
| **Stockage** | ≥ 1 Go libre | Le binaire Gitea fait ~100 Mo, plus les dépôts Git (prévoir plus selon le nombre de projets). |
|
||||||
|
| **OS** | Debian 12 (Bookworm) ou Debian 13 | Gitea fournit des binaires compatibles. |
|
||||||
|
| **Base de données** | SQLite, MariaDB/MySQL, PostgreSQL | SQLite pour test/local, PostgreSQL ou MariaDB en prod. |
|
||||||
|
| **Reverse proxy** | nginx, Caddy, Apache ... avec HTTPS |
|
||||||
|
| **Utilisateur système** | `git` (non root) pour exécuter le service |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **2. Vérification rapide des ressources**
|
||||||
|
|
||||||
|
Tu peux vérifier ta machine avec :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
lscpu | grep "Model name"
|
||||||
|
free -h
|
||||||
|
df -h /
|
||||||
|
```
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"uuid": "c9796eff-43b9-4e51-b613-8eec21a8c352",
|
||||||
|
"slug": "gitea-prerequis",
|
||||||
|
"title": "gitea, prérequis",
|
||||||
|
"author": "cedric@abonnel.fr",
|
||||||
|
"published": true,
|
||||||
|
"published_at": "2025-11-07 10:57:33",
|
||||||
|
"created_at": "2025-11-07 10:57:33",
|
||||||
|
"updated_at": "2025-11-07 10:57:33",
|
||||||
|
"revisions": [],
|
||||||
|
"cover": "cover.jpg",
|
||||||
|
"category": "informatique"
|
||||||
|
}
|
||||||
@@ -0,0 +1,221 @@
|
|||||||
|
Voici un guide pas à pas pour installer Gitea sur Debian 13 avec PostgreSQL comme base de données, et configurer un reverse-proxy (par ex. Traefik ou Nginx) pour servir Gitea.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Pré-requis
|
||||||
|
|
||||||
|
* Un serveur Debian 13 à jour.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt update && sudo apt upgrade -y
|
||||||
|
```
|
||||||
|
* Installer Git, et éventuellement d’autres dépendances.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt install -y git ca-certificates
|
||||||
|
```
|
||||||
|
* Un nom de domaine `git.abonnel.fr` pointant vers votre serveur (DNS A ou AAAA).
|
||||||
|
* Assurez-vous que le port 80 et/ou 443 sont ouverts sur le serveur (pour le proxy).
|
||||||
|
* Installer PostgreSQL.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Installer PostgreSQL et créer base & utilisateur
|
||||||
|
|
||||||
|
1. Installer PostgreSQL (Debian 13 inclut postgresql dans ses dépôts).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt install -y postgresql postgresql-contrib
|
||||||
|
```
|
||||||
|
2. Passer à l’utilisateur postgres et créer la base + utilisateur pour Gitea :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo -i -u postgres
|
||||||
|
psql
|
||||||
|
CREATE DATABASE gitea WITH ENCODING 'UTF8' TEMPLATE template0;
|
||||||
|
CREATE USER gitea WITH PASSWORD 'votre_mot_de_passe_sécurisé';
|
||||||
|
GRANT ALL PRIVILEGES ON DATABASE gitea TO gitea;
|
||||||
|
\q
|
||||||
|
exit
|
||||||
|
```
|
||||||
|
|
||||||
|
Ces commandes sont conformes à la documentation Gitea pour PostgreSQL. ([Gitea Documentation][1])
|
||||||
|
3. Vérifier que PostgreSQL fonctionne :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl status postgresql
|
||||||
|
```
|
||||||
|
4. (Optionnel) Modifier le fichier `pg_hba.conf` si vous voulez autoriser certaines connexions supplémentaires (ex: accès réseau).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Installer Gitea
|
||||||
|
|
||||||
|
1. Créer un utilisateur système qui va exécuter Gitea :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo adduser --system --shell /bin/bash --gecos 'Git Version Control' --group --disabled-password --home /home/git git
|
||||||
|
```
|
||||||
|
|
||||||
|
([Gitea Documentation][2])
|
||||||
|
2. Créer les dossiers de travail :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo mkdir -p /var/lib/gitea/{custom,data,log}
|
||||||
|
sudo chown -R git:git /var/lib/gitea/
|
||||||
|
sudo chmod -R 750 /var/lib/gitea/
|
||||||
|
sudo mkdir /etc/gitea
|
||||||
|
sudo chown root:git /etc/gitea
|
||||||
|
sudo chmod 770 /etc/gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
([Gitea Documentation][3])
|
||||||
|
3. Télécharger le binaire Gitea :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wget -O gitea https://dl.gitea.com/gitea/1.24.7/gitea-1.24.7-linux-amd64
|
||||||
|
chmod +x gitea
|
||||||
|
sudo mv gitea /usr/local/bin/gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
(Vérifiez la version la plus récente sur le site officiel) ([Gitea Documentation][2])
|
||||||
|
4. Créer un fichier de service systemd pour Gitea. Exemple minimal (`/etc/systemd/system/gitea.service`) :
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[Unit]
|
||||||
|
Description=Gitea (Git with a cup of tea)
|
||||||
|
After=network.target postgresql.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=git
|
||||||
|
Group=git
|
||||||
|
WorkingDirectory=/var/lib/gitea/
|
||||||
|
ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
|
||||||
|
Restart=always
|
||||||
|
Environment=USER=git HOME=/var/lib/gitea GITEA_WORK_DIR=/var/lib/gitea
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
Ensuite :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable --now gitea
|
||||||
|
sudo systemctl status gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
([Gitea Documentation][4])
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Configuration via l’interface web
|
||||||
|
|
||||||
|
* Ouvrez [http://votre-serveur:3000](http://votre-serveur:3000) (ou le port que Gitea utilise) dans un navigateur.
|
||||||
|
* Dans l’assistant d’installation, choisissez *PostgreSQL* comme type de base de données. Entrez :
|
||||||
|
|
||||||
|
* Host : `localhost:5432` (ou l’IP/port selon)
|
||||||
|
* Database : `gitea`
|
||||||
|
* Username : `gitea`
|
||||||
|
* Password : celui que vous avez défini
|
||||||
|
* Dans le champ "Base URL", indiquez `https://git.abonnel.fr/` (ou http selon votre setup).
|
||||||
|
* Complétez le reste (admin account, etc.).
|
||||||
|
([James R. S. Kemp Git][5])
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Configurer reverse-proxy pour `git.abonnel.fr`
|
||||||
|
|
||||||
|
Si vous utilisez Nginx ou Traefik (ou un autre proxy) vous devez rediriger le domaine vers Gitea.
|
||||||
|
|
||||||
|
### Exemple avec Nginx :
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name git.abonnel.fr;
|
||||||
|
|
||||||
|
# redirection vers HTTPS (si certbot/Let’s Encrypt)
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name git.abonnel.fr;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/git.abonnel.fr/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/git.abonnel.fr/privkey.pem;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:3000;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Cet exemple est inspiré des tutos d’installation Gitea + Nginx. ([James R. S. Kemp Git][5])
|
||||||
|
Si vous utilisez un autre proxy (ex: Traefik ou « zoraxyproxy »), adaptez la configuration pour qu’il fasse passer `git.abonnel.fr` vers `localhost:3000` et gère SSL.
|
||||||
|
|
||||||
|
### Activer HTTPS
|
||||||
|
|
||||||
|
* Installez `certbot` ou utilisez votre gestionnaire de certificats.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt install -y certbot python3-certbot-nginx
|
||||||
|
sudo certbot --nginx -d git.abonnel.fr
|
||||||
|
```
|
||||||
|
* Vérifiez que le certificat est actif et que `https://git.abonnel.fr` fonctionne.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Configuration finale dans app.ini
|
||||||
|
|
||||||
|
Après installation, vous pouvez ajuster `/etc/gitea/app.ini` (ou via l’interface). Exemples de réglages utiles :
|
||||||
|
|
||||||
|
* Dans `[server]` :
|
||||||
|
|
||||||
|
```
|
||||||
|
ROOT_URL = https://git.abonnel.fr/
|
||||||
|
HTTP_PORT = 3000
|
||||||
|
SSH_PORT = 22 # ou le port SSH que vous utilisez pour Git
|
||||||
|
START_SSH_SERVER = false # si vous n’utilisez pas le serveur SSH interne
|
||||||
|
DOMAIN = git.abonnel.fr
|
||||||
|
```
|
||||||
|
* Dans `[database]` :
|
||||||
|
|
||||||
|
```
|
||||||
|
DB_TYPE = postgres
|
||||||
|
HOST = 127.0.0.1:5432
|
||||||
|
NAME = gitea
|
||||||
|
USER = gitea
|
||||||
|
PASSWD = votre_mot_de_passe
|
||||||
|
SSL_MODE = disable # ou require selon votre config
|
||||||
|
```
|
||||||
|
* Redémarrez Gitea après modification :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl restart gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Sécuriser & entretien
|
||||||
|
|
||||||
|
* Assurez-vous que seuls les ports nécessaires sont exposés (ex: 80/443 via proxy, 3000 en local si non exposé).
|
||||||
|
* Faites des sauvegardes régulières : base PostgreSQL + dossier `/var/lib/gitea/data` (ou vos dépôts).
|
||||||
|
* Vérifiez les logs de Gitea (souvent dans `/var/lib/gitea/log/`).
|
||||||
|
* Gardez Gitea et PostgreSQL à jour.
|
||||||
|
* Si vous utilisez SSH pour les repos Git, configurez correctement les clés SSH utilisateur et vérifiez que l’utilisateur `git` a bien les permissions.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
[1]: https://docs.gitea.com/enterprise/installation/linux?utm_source=chatgpt.com "Install on Linux | Gitea Enterprise Documentations"
|
||||||
|
[2]: https://docs.gitea.com/installation/install-from-binary?utm_source=chatgpt.com "Installation from binary | Gitea Documentation"
|
||||||
|
[3]: https://docs.gitea.com/1.18/installation/install-from-binary?utm_source=chatgpt.com "Installation from binary | Gitea Documentation"
|
||||||
|
[4]: https://docs.gitea.com/1.20/category/installation?utm_source=chatgpt.com "Installation | Gitea Documentation"
|
||||||
|
[5]: https://git.jamesrskemp.com/hosting/gitea.html?utm_source=chatgpt.com "Gitea - Git Commands by James Skemp"
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"uuid": "f008f509-2cad-437f-9850-7b39ec37262a",
|
||||||
|
"slug": "gitea-l-installation",
|
||||||
|
"title": "gitea, l'installation",
|
||||||
|
"author": "cedric@abonnel.fr",
|
||||||
|
"published": true,
|
||||||
|
"published_at": "2025-11-07 11:01:57",
|
||||||
|
"created_at": "2025-11-07 11:01:57",
|
||||||
|
"updated_at": "2025-11-07 11:01:57",
|
||||||
|
"revisions": [],
|
||||||
|
"cover": "cover.jpg",
|
||||||
|
"category": "informatique"
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"uuid": "fdff8ad3-d369-4bd7-bbb9-e14d433868d7",
|
||||||
|
"slug": "license",
|
||||||
|
"title": "Licences",
|
||||||
|
"author": "cedric@abonnel.fr",
|
||||||
|
"published": true,
|
||||||
|
"published_at": "2021-01-16 04:02:40",
|
||||||
|
"created_at": "2021-01-16 04:02:40",
|
||||||
|
"updated_at": "2021-01-16 04:02:40",
|
||||||
|
"revisions": [],
|
||||||
|
"cover": "",
|
||||||
|
"files_meta": [],
|
||||||
|
"external_links": [],
|
||||||
|
"seo_title": "",
|
||||||
|
"seo_description": "",
|
||||||
|
"og_image": "",
|
||||||
|
"category": ""
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# Licences
|
||||||
|
|
||||||
|
Composants logiciels utilisés par ce site et leurs licences.
|
||||||
|
|
||||||
|
## Ce site
|
||||||
|
|
||||||
|
| Composant | Licence | Usage |
|
||||||
|
|-----------|---------|-------|
|
||||||
|
| **Folio** — moteur de blog PHP | MIT | Moteur de ce blog — par Cédric Abonnel ([voir la licence](/LICENSE)) |
|
||||||
|
| **Contenu éditorial** | CC BY 4.0 | Articles et textes du blog — [Creative Commons Attribution 4.0](https://creativecommons.org/licenses/by/4.0/) |
|
||||||
|
|
||||||
|
## Bibliothèques (production)
|
||||||
|
|
||||||
|
| Composant | Version | Licence | Usage |
|
||||||
|
|-----------|---------|---------|-------|
|
||||||
|
| **Bootstrap** | 5.3.3 | MIT | Framework CSS/JS — auto-hébergé ([voir la licence](/assets/css/LICENSE-Bootstrap.txt)) |
|
||||||
|
| **PHPMailer** | 6.12.0 | LGPL-2.1 | Envoi d'e-mails SMTP |
|
||||||
|
| **phpdotenv** | 5.6.2 | BSD-3-Clause | Variables d'environnement |
|
||||||
|
| **openid-connect-php** | 1.0.2 | Apache-2.0 | Authentification SSO (OIDC) |
|
||||||
|
| **Police Inter** | v20 | OFL-1.1 | Typographie — auto-hébergée ([voir la licence](/assets/fonts/LICENSE-Inter.txt)) |
|
||||||
|
|
||||||
|
## Outils de développement
|
||||||
|
|
||||||
|
| Composant | Version | Licence | Usage |
|
||||||
|
|-----------|---------|---------|-------|
|
||||||
|
| **PHPStan** | 1.12.32 | MIT | Analyse statique PHP |
|
||||||
|
| **PHP-CS-Fixer** | 3.89.1 | MIT | Formatage du code |
|
||||||
|
| **Claude Code CLI** | — | Commercial | Outil de développement (Anthropic) — [Conditions d'utilisation](https://www.anthropic.com/legal/aup) |
|
||||||
|
|
||||||
|
## Infrastructure
|
||||||
|
|
||||||
|
| Composant | Licence | Usage |
|
||||||
|
|-----------|---------|-------|
|
||||||
|
| **PHP 8.3** | PHP License v3.01 | Langage côté serveur |
|
||||||
|
| **PostgreSQL** | PostgreSQL License | Base de données relationnelle |
|
||||||
|
| **Apache HTTP Server** | Apache-2.0 | Serveur web |
|
||||||
|
|
||||||
|
|
||||||
+24
-31
@@ -314,17 +314,32 @@ a:hover {
|
|||||||
.hero-btn--danger:hover { background: rgba(180,30,30,.65); }
|
.hero-btn--danger:hover { background: rgba(180,30,30,.65); }
|
||||||
|
|
||||||
/* Score de notation dans le hero */
|
/* Score de notation dans le hero */
|
||||||
.hero-rating-score {
|
.hero-reactions {
|
||||||
font-size: 0.8rem;
|
display: flex;
|
||||||
font-weight: 600;
|
gap: .4rem;
|
||||||
color: rgba(255,255,255,.88);
|
flex-wrap: wrap;
|
||||||
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Étoiles sur fond sombre */
|
.hero-reaction-btn {
|
||||||
.star-rating--hero label { color: rgba(255,255,255,.4); font-size: 1.1rem; }
|
display: inline-flex;
|
||||||
.star-rating--hero input:checked ~ label,
|
align-items: center;
|
||||||
.star-rating--hero label:hover,
|
gap: .3rem;
|
||||||
.star-rating--hero label:hover ~ label { color: #f5c842; }
|
background: rgba(255,255,255,.15);
|
||||||
|
border: 1px solid rgba(255,255,255,.35);
|
||||||
|
border-radius: 100px;
|
||||||
|
padding: .25rem .7rem;
|
||||||
|
color: #fff;
|
||||||
|
font-size: .875rem;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background .15s, border-color .15s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-reaction-btn:hover,
|
||||||
|
.hero-reaction-btn--active {
|
||||||
|
background: rgba(255,255,255,.32);
|
||||||
|
border-color: rgba(255,255,255,.7);
|
||||||
|
}
|
||||||
|
|
||||||
.card-cover {
|
.card-cover {
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -1172,28 +1187,6 @@ footer.mt-5 { margin-top: 0 !important; }
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ─── Widget étoiles ──────────────────────── */
|
/* ─── Widget étoiles ──────────────────────── */
|
||||||
.star-rating {
|
|
||||||
display: inline-flex;
|
|
||||||
flex-direction: row-reverse;
|
|
||||||
gap: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.star-rating input {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.star-rating label {
|
|
||||||
font-size: 1.4rem;
|
|
||||||
color: #ccc;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: color 0.1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.star-rating input:checked ~ label,
|
|
||||||
.star-rating label:hover,
|
|
||||||
.star-rating label:hover ~ label {
|
|
||||||
color: #f5a623;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ─── Barre de recherche (navbar) ────────── */
|
/* ─── Barre de recherche (navbar) ────────── */
|
||||||
.search-form {
|
.search-form {
|
||||||
|
|||||||
@@ -26,14 +26,18 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
if (!json.ok) { form.submit(); return; }
|
if (!json.ok) { form.submit(); return; }
|
||||||
|
|
||||||
var nowActive = json.active;
|
var nowActive = json.active;
|
||||||
|
if (btn.classList.contains('hero-reaction-btn')) {
|
||||||
|
btn.classList.toggle('hero-reaction-btn--active', nowActive);
|
||||||
|
} else {
|
||||||
btn.classList.toggle('btn-primary', nowActive);
|
btn.classList.toggle('btn-primary', nowActive);
|
||||||
btn.classList.toggle('btn-outline-secondary', !nowActive);
|
btn.classList.toggle('btn-outline-secondary', !nowActive);
|
||||||
if (badge) {
|
if (badge) {
|
||||||
badge.classList.toggle('bg-light', nowActive);
|
badge.classList.toggle('bg-light', nowActive);
|
||||||
badge.classList.toggle('text-primary', nowActive);
|
badge.classList.toggle('text-primary', nowActive);
|
||||||
badge.classList.toggle('bg-secondary', !nowActive);
|
badge.classList.toggle('bg-secondary', !nowActive);
|
||||||
badge.textContent = json.count;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (badge) { badge.textContent = json.count; }
|
||||||
})
|
})
|
||||||
.catch(function () { form.submit(); });
|
.catch(function () { form.submit(); });
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,32 +18,6 @@ $_csrfToken = bin2hex(random_bytes(16));
|
|||||||
$_SESSION['comment_csrf'] = $_csrfToken;
|
$_SESSION['comment_csrf'] = $_csrfToken;
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<!-- ── Réactions ──────────────────────────────────────────────────── -->
|
|
||||||
<div class="card mb-4" id="reactions">
|
|
||||||
<div class="card-body">
|
|
||||||
<h6 class="card-title mb-3 text-muted text-uppercase" style="font-size:.75rem;letter-spacing:.06em">Réactions</h6>
|
|
||||||
<div class="d-flex gap-2 flex-wrap" id="reaction-buttons">
|
|
||||||
<?php foreach ($_reactionDefs as $type => [$icon, $label]): ?>
|
|
||||||
<?php $active = in_array($type, $visitorReactions, true); ?>
|
|
||||||
<form method="post" action="/react" class="reaction-form d-inline">
|
|
||||||
<input type="hidden" name="uuid" value="<?= htmlspecialchars($article['uuid']) ?>">
|
|
||||||
<input type="hidden" name="type" value="<?= htmlspecialchars($type) ?>">
|
|
||||||
<input type="hidden" name="_back" value="/post/<?= rawurlencode($article['slug'] ?? '') ?>#reactions">
|
|
||||||
<button type="submit"
|
|
||||||
class="btn btn-sm <?= $active ? 'btn-primary' : 'btn-outline-secondary' ?> reaction-btn"
|
|
||||||
data-type="<?= htmlspecialchars($type) ?>"
|
|
||||||
data-uuid="<?= htmlspecialchars($article['uuid']) ?>">
|
|
||||||
<span class="reaction-icon"><?= $icon ?></span>
|
|
||||||
<span class="reaction-label"><?= htmlspecialchars($label) ?></span>
|
|
||||||
<span class="badge <?= $active ? 'bg-light text-primary' : 'bg-secondary' ?> ms-1 reaction-count"
|
|
||||||
data-type="<?= htmlspecialchars($type) ?>"><?= (int)($reactionStats[$type] ?? 0) ?></span>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php if (!empty($alsoReadArticles ?? [])): ?>
|
<?php if (!empty($alsoReadArticles ?? [])): ?>
|
||||||
<!-- ── À lire aussi ──────────────────────────────────────────────── -->
|
<!-- ── À lire aussi ──────────────────────────────────────────────── -->
|
||||||
<div class="also-read mb-4" id="also-read">
|
<div class="also-read mb-4" id="also-read">
|
||||||
|
|||||||
+23
-28
@@ -127,30 +127,31 @@ $hasSources = (!empty($externalLinks) || !empty($files))
|
|||||||
<?php if ($hasSources): ?>
|
<?php if ($hasSources): ?>
|
||||||
<a href="/sources/<?= rawurlencode($article['uuid']) ?>" class="hero-btn">ℹ Sources</a>
|
<a href="/sources/<?= rawurlencode($article['uuid']) ?>" class="hero-btn">ℹ Sources</a>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<?php if (function_exists('isLoggedIn') && isLoggedIn()): ?>
|
<?php
|
||||||
<form method="post" action="/?action=rate" class="d-flex align-items-center gap-2">
|
$_heroReactionDefs = [
|
||||||
|
'useful' => ['👍', 'Utile'],
|
||||||
|
'important' => ['🔥', 'Important'],
|
||||||
|
'interesting' => ['🤔', 'À creuser'],
|
||||||
|
];
|
||||||
|
?>
|
||||||
|
<div class="hero-reactions" id="reactions">
|
||||||
|
<?php foreach ($_heroReactionDefs as $type => [$icon, $label]): ?>
|
||||||
|
<?php $active = in_array($type, $visitorReactions ?? [], true); ?>
|
||||||
|
<form method="post" action="/react" class="reaction-form d-inline">
|
||||||
<input type="hidden" name="uuid" value="<?= htmlspecialchars($article['uuid']) ?>">
|
<input type="hidden" name="uuid" value="<?= htmlspecialchars($article['uuid']) ?>">
|
||||||
<?php if ($ratingStats['count'] > 0): ?>
|
<input type="hidden" name="type" value="<?= htmlspecialchars($type) ?>">
|
||||||
<span class="hero-rating-score">
|
<input type="hidden" name="_back" value="/post/<?= rawurlencode($article['slug'] ?? '') ?>#reactions">
|
||||||
<?= number_format((float)($ratingStats['avg'] ?? 0), 1) ?> <span style="opacity:.6">/ 5</span>
|
<button type="submit"
|
||||||
</span>
|
class="hero-reaction-btn<?= $active ? ' hero-reaction-btn--active' : '' ?> reaction-btn"
|
||||||
<?php endif; ?>
|
data-type="<?= htmlspecialchars($type) ?>"
|
||||||
<div class="star-rating star-rating--hero">
|
data-uuid="<?= htmlspecialchars($article['uuid']) ?>"
|
||||||
<?php for ($s = 5; $s >= 1; $s--): ?>
|
title="<?= htmlspecialchars($label) ?>">
|
||||||
<input type="radio" id="star<?= $s ?>-<?= $article['uuid'] ?>"
|
<span><?= $icon ?></span>
|
||||||
name="rating" value="<?= $s ?>"
|
<span class="reaction-count" data-type="<?= htmlspecialchars($type) ?>"><?= (int)($reactionStats[$type] ?? 0) ?></span>
|
||||||
<?= (int)($userRating ?? 0) === $s ? 'checked' : '' ?>
|
</button>
|
||||||
onchange="this.form.submit()">
|
|
||||||
<label for="star<?= $s ?>-<?= $article['uuid'] ?>" title="<?= $s ?>★">★</label>
|
|
||||||
<?php endfor; ?>
|
|
||||||
</div>
|
|
||||||
</form>
|
</form>
|
||||||
<?php elseif ($ratingStats['count'] > 0): ?>
|
<?php endforeach; ?>
|
||||||
<span class="hero-rating-score">
|
</div>
|
||||||
★ <?= number_format((float)($ratingStats['avg'] ?? 0), 1) ?>
|
|
||||||
<span style="opacity:.6">(<?= $ratingStats['count'] ?>)</span>
|
|
||||||
</span>
|
|
||||||
<?php endif; ?>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -163,12 +164,6 @@ $hasSources = (!empty($externalLinks) || !empty($files))
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if (!isLoggedIn() && $ratingStats['count'] > 0): ?>
|
|
||||||
<p class="text-muted small mt-3">
|
|
||||||
Note : <?= number_format((float)($ratingStats['avg'] ?? 0), 1) ?>/5
|
|
||||||
— <a href="/login">Connectez-vous</a> pour noter.
|
|
||||||
</p>
|
|
||||||
<?php endif; ?>
|
|
||||||
|
|
||||||
<?php include __DIR__ . '/comments_section.php'; ?>
|
<?php include __DIR__ . '/comments_section.php'; ?>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user