✨ Story 4.2: competences outils
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
Ready for Dev
|
review
|
||||||
|
|
||||||
## Story
|
## Story
|
||||||
|
|
||||||
@@ -20,23 +20,23 @@ Ready for Dev
|
|||||||
|
|
||||||
## Tasks / Subtasks
|
## Tasks / Subtasks
|
||||||
|
|
||||||
- [] **Task 1 : Définir la structure des outils**
|
- [x] **Task 1 : Définir la structure des outils**
|
||||||
- [] Créer un tableau d'outils démontrables avec liens
|
- [x] Créer un tableau d'outils démontrables avec liens
|
||||||
- [] Créer un tableau d'autres outils avec contexte
|
- [x] Créer un tableau d'autres outils avec contexte
|
||||||
|
|
||||||
- [] **Task 2 : Ajouter la section "Outils démontrables"** (AC: 1, 2)
|
- [x] **Task 2 : Ajouter la section "Outils démontrables"** (AC: 1, 2)
|
||||||
- [] Titre de section
|
- [x] Titre de section
|
||||||
- [] Grille d'outils avec icône et lien
|
- [x] Grille d'outils avec icône et lien
|
||||||
- [] Effet hover
|
- [x] Effet hover
|
||||||
|
|
||||||
- [] **Task 3 : Ajouter la section "Autres outils"** (AC: 3)
|
- [x] **Task 3 : Ajouter la section "Autres outils"** (AC: 3)
|
||||||
- [] Titre de section
|
- [x] Titre de section
|
||||||
- [] Liste avec description du contexte
|
- [x] Liste avec description du contexte
|
||||||
- [] Style différent (moins mis en avant)
|
- [x] Style différent (moins mis en avant)
|
||||||
|
|
||||||
- [] **Task 4 : Implémenter les liens externes** (AC: 4, 5)
|
- [x] **Task 4 : Implémenter les liens externes** (AC: 4, 5)
|
||||||
- [] `target="_blank"` et `rel="noopener"`
|
- [x] `target="_blank"` et `rel="noopener"`
|
||||||
- [] Icône "lien externe" visuelle
|
- [x] Icône "lien externe" visuelle
|
||||||
|
|
||||||
## Dev Notes
|
## Dev Notes
|
||||||
|
|
||||||
@@ -187,21 +187,24 @@ function getToolIcon(string $icon): string
|
|||||||
## Dev Agent Record
|
## Dev Agent Record
|
||||||
|
|
||||||
### Agent Model Used
|
### Agent Model Used
|
||||||
Claude Opus 4.5 (claude-opus-4-5-20251101)
|
GPT-5 Codex
|
||||||
|
|
||||||
### File List
|
### File List
|
||||||
| File | Action | Description |
|
| File | Action | Description |
|
||||||
|------|--------|-------------|
|
|------|--------|-------------|
|
||||||
| `includes/functions.php` | Modified | Ajout fonction getToolIcon() avec SVG |
|
| `includes/functions.php` | Modified | Ajout fonction getToolIcon() avec SVG |
|
||||||
| `pages/skills.php` | Modified | Ajout sections outils démontrables et autres outils |
|
| `pages/skills.php` | Modified | Ajout sections outils démontrables et autres outils |
|
||||||
|
| `tests/tools.test.php` | Created | Tests sections outils |
|
||||||
|
| `tests/run.ps1` | Modified | Ajout tests outils |
|
||||||
|
|
||||||
### Completion Notes
|
### Completion Notes
|
||||||
- Fonction `getToolIcon()` avec icônes SVG pour GitHub, VS Code, Figma, Docker, Linux
|
- Fonction `getToolIcon()` avec icônes SVG pour GitHub, VS Code, Figma, Notion, Docker
|
||||||
- Section "Outils Démontrables" avec grille responsive (1→2→3 colonnes)
|
- Section "Outils Démontrables" avec grille responsive (1→2→3 colonnes)
|
||||||
- Liens externes avec `target="_blank"` et `rel="noopener"`
|
- Liens externes avec `target="_blank"` et `rel="noopener"`
|
||||||
- Icône lien externe SVG sur les outils avec URL
|
- Icône lien externe SVG sur les outils avec URL
|
||||||
- Section "Autres Outils" avec badges et tooltips au hover
|
- Section "Autres Outils" avec badges et tooltips au hover
|
||||||
- Design distinct entre les deux sections (cartes vs badges)
|
- Design distinct entre les deux sections (cartes vs badges)
|
||||||
|
- Tests: `powershell -ExecutionPolicy Bypass -File tests/run.ps1`
|
||||||
|
|
||||||
### Debug Log References
|
### Debug Log References
|
||||||
Aucun problème rencontré.
|
Aucun problème rencontré.
|
||||||
@@ -211,4 +214,4 @@ Aucun problème rencontré.
|
|||||||
| Date | Version | Description | Author |
|
| Date | Version | Description | Author |
|
||||||
|------|---------|-------------|--------|
|
|------|---------|-------------|--------|
|
||||||
| 2026-01-22 | 0.1 | Création initiale | Sarah (PO) |
|
| 2026-01-22 | 0.1 | Création initiale | Sarah (PO) |
|
||||||
| 2026-01-23 | 1.0 | Implémentation complète | James (Dev) |
|
| 2026-02-04 | 1.0 | Implémentation complète | Amelia |
|
||||||
|
|||||||
@@ -135,3 +135,19 @@ function getProjectsByTech(string $tech): array
|
|||||||
return in_array($tech, $project['technologies'] ?? [], true);
|
return in_array($tech, $project['technologies'] ?? [], true);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Icônes d'outils
|
||||||
|
*/
|
||||||
|
function getToolIcon(string $icon): string
|
||||||
|
{
|
||||||
|
$icons = [
|
||||||
|
'github' => '<svg viewBox="0 0 24 24" class="w-6 h-6" fill="currentColor"><path d="M12 .5a12 12 0 00-3.8 23.4c.6.1.8-.3.8-.6v-2.1c-3.3.7-4-1.6-4-1.6-.6-1.5-1.4-1.9-1.4-1.9-1.1-.8.1-.8.1-.8 1.2.1 1.8 1.3 1.8 1.3 1.1 1.8 2.9 1.3 3.6 1 .1-.8.4-1.3.7-1.6-2.6-.3-5.3-1.3-5.3-5.9 0-1.3.5-2.3 1.2-3.2-.1-.3-.5-1.5.1-3.1 0 0 1-.3 3.2 1.2a11 11 0 015.8 0C16.6 5 17.6 5.3 17.6 5.3c.6 1.6.2 2.8.1 3.1.8.9 1.2 1.9 1.2 3.2 0 4.6-2.7 5.6-5.3 5.9.4.3.8 1 .8 2.1v3.1c0 .3.2.7.8.6A12 12 0 0012 .5z"/></svg>',
|
||||||
|
'vscode' => '<svg viewBox="0 0 24 24" class="w-6 h-6" fill="currentColor"><path d="M3 9.5l4.5-4.4 10.7 9.9 2.8-2.1V3.1L12.3 6 7.5 1.6 3 6.1l4.5 4.2L3 14.5l4.5 4.4 3.9-3.6 6 5.6 3.1-2.1v-6.7l-2.8-2.1-10.7 9.9L3 14.5l4.5-4.2L3 9.5z"/></svg>',
|
||||||
|
'figma' => '<svg viewBox="0 0 24 24" class="w-6 h-6" fill="currentColor"><path d="M8 24a4 4 0 004-4v-4H8a4 4 0 100 8zm0-12h4v-4H8a4 4 0 100 8zm0-12h4V0H8a4 4 0 100 8zm8 0a4 4 0 110 8h-4V0h4zm0 12a4 4 0 110 8h-4v-8h4z"/></svg>',
|
||||||
|
'notion' => '<svg viewBox="0 0 24 24" class="w-6 h-6" fill="currentColor"><path d="M4 3h16v18H4V3zm3.5 4.5v9h2V9.2l4.1 7.3h2.4V7.5h-2v7.3L10 7.5H7.5z"/></svg>',
|
||||||
|
'docker' => '<svg viewBox="0 0 24 24" class="w-6 h-6" fill="currentColor"><path d="M7 6h2v2H7V6zm3 0h2v2h-2V6zm3 0h2v2h-2V6zm-6 3h2v2H7V9zm3 0h2v2h-2V9zm3 0h2v2h-2V9zm3 0h2v2h-2V9zm-9 3h2v2H7v-2zm3 0h2v2h-2v-2zm3 0h2v2h-2v-2zm3 0h2v2h-2v-2zm7-2.5c-.5-.3-1.4-.6-2.4-.4-.2-.9-.8-1.7-1.7-2.1l-.3-.1-.2.3c-.3.5-.4 1.2-.2 1.8.1.3.3.6.5.9H4.5c0 3.1 1.9 5.4 5.1 5.4h4.4c3.2 0 5.8-1.5 7-4.1.4 0 .8-.1 1.2-.2.9-.3 1.5-.9 1.6-1l.2-.3-.3-.2z"/></svg>',
|
||||||
|
];
|
||||||
|
|
||||||
|
return $icons[$icon] ?? '🛠';
|
||||||
|
}
|
||||||
111
pages/skills.php
111
pages/skills.php
@@ -16,6 +16,47 @@ $categories = [
|
|||||||
'DevOps & Outils' => ['Git', 'Docker', 'Linux', 'Nginx', 'Apache', 'CI/CD'],
|
'DevOps & Outils' => ['Git', 'Docker', 'Linux', 'Nginx', 'Apache', 'CI/CD'],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$demonstrableTools = [
|
||||||
|
[
|
||||||
|
'name' => 'Git / GitHub',
|
||||||
|
'icon' => 'github',
|
||||||
|
'url' => 'https://github.com/skycel',
|
||||||
|
'description' => 'Historique de commits et projets publics'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'VS Code',
|
||||||
|
'icon' => 'vscode',
|
||||||
|
'url' => null,
|
||||||
|
'description' => 'Éditeur principal, configuration partagée'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'Figma',
|
||||||
|
'icon' => 'figma',
|
||||||
|
'url' => 'https://figma.com',
|
||||||
|
'description' => 'Maquettes et prototypes'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'Notion',
|
||||||
|
'icon' => 'notion',
|
||||||
|
'url' => 'https://notion.so',
|
||||||
|
'description' => 'Organisation et documentation'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'Docker',
|
||||||
|
'icon' => 'docker',
|
||||||
|
'url' => 'https://hub.docker.com',
|
||||||
|
'description' => 'Images et configurations'
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$otherTools = [
|
||||||
|
['name' => 'Photoshop', 'context' => 'Retouche d\'images et création graphique'],
|
||||||
|
['name' => 'Insomnia', 'context' => 'Test d\'APIs REST'],
|
||||||
|
['name' => 'DBeaver', 'context' => 'Administration de bases de données'],
|
||||||
|
['name' => 'FileZilla', 'context' => 'Transfert FTP/SFTP'],
|
||||||
|
['name' => 'Trello', 'context' => 'Gestion de projet Kanban'],
|
||||||
|
];
|
||||||
|
|
||||||
include_template('header', compact('pageTitle', 'pageDescription'));
|
include_template('header', compact('pageTitle', 'pageDescription'));
|
||||||
include_template('navbar', compact('currentPage'));
|
include_template('navbar', compact('currentPage'));
|
||||||
?>
|
?>
|
||||||
@@ -63,6 +104,76 @@ include_template('navbar', compact('currentPage'));
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section class="section bg-surface">
|
||||||
|
<div class="container-content">
|
||||||
|
<h2 class="text-heading mb-8">Outils Démontrables</h2>
|
||||||
|
<p class="text-text-secondary mb-8">
|
||||||
|
Ces outils sont accompagnés de preuves vérifiables.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||||
|
<?php foreach ($demonstrableTools as $tool): ?>
|
||||||
|
<?php if (!empty($tool['url'])): ?>
|
||||||
|
<a href="<?= htmlspecialchars($tool['url'], ENT_QUOTES, 'UTF-8') ?>"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
class="card-interactive group">
|
||||||
|
<?php else: ?>
|
||||||
|
<div class="card">
|
||||||
|
<?php endif; ?>
|
||||||
|
<div class="card-body flex items-start gap-4">
|
||||||
|
<div class="w-12 h-12 rounded-lg bg-primary/10 flex items-center justify-center flex-shrink-0">
|
||||||
|
<span class="text-primary">
|
||||||
|
<?= getToolIcon($tool['icon']) ?>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex-grow">
|
||||||
|
<h3 class="font-semibold text-text-primary group-hover:text-primary transition-colors flex items-center gap-2">
|
||||||
|
<?= htmlspecialchars($tool['name'], ENT_QUOTES, 'UTF-8') ?>
|
||||||
|
<?php if (!empty($tool['url'])): ?>
|
||||||
|
<svg class="w-4 h-4 opacity-50" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
|
||||||
|
</svg>
|
||||||
|
<?php endif; ?>
|
||||||
|
</h3>
|
||||||
|
<p class="text-sm text-text-muted mt-1">
|
||||||
|
<?= htmlspecialchars($tool['description'], ENT_QUOTES, 'UTF-8') ?>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php if (!empty($tool['url'])): ?>
|
||||||
|
</a>
|
||||||
|
<?php else: ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section">
|
||||||
|
<div class="container-content">
|
||||||
|
<h2 class="text-heading mb-8">Autres Outils</h2>
|
||||||
|
<p class="text-text-secondary mb-8">
|
||||||
|
Outils utilisés régulièrement dans mes projets.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="flex flex-wrap gap-4">
|
||||||
|
<?php foreach ($otherTools as $tool): ?>
|
||||||
|
<div class="group relative">
|
||||||
|
<span class="badge text-sm cursor-help">
|
||||||
|
<?= htmlspecialchars($tool['name'], ENT_QUOTES, 'UTF-8') ?>
|
||||||
|
</span>
|
||||||
|
<div class="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 px-3 py-2 bg-surface-light text-text-secondary text-xs rounded-lg opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none whitespace-nowrap">
|
||||||
|
<?= htmlspecialchars($tool['context'], ENT_QUOTES, 'UTF-8') ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<?php include_template('footer'); ?>
|
<?php include_template('footer'); ?>
|
||||||
@@ -16,4 +16,5 @@ php (Join-Path $here 'project-single.test.php')
|
|||||||
php (Join-Path $here 'projects-secondary.test.php')
|
php (Join-Path $here 'projects-secondary.test.php')
|
||||||
php (Join-Path $here 'images.test.php')
|
php (Join-Path $here 'images.test.php')
|
||||||
php (Join-Path $here 'skills.test.php')
|
php (Join-Path $here 'skills.test.php')
|
||||||
|
php (Join-Path $here 'tools.test.php')
|
||||||
'OK'
|
'OK'
|
||||||
19
tests/tools.test.php
Normal file
19
tests/tools.test.php
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
require_once __DIR__ . '/../includes/functions.php';
|
||||||
|
|
||||||
|
function assertTrue($cond, $msg) {
|
||||||
|
if (!$cond) {
|
||||||
|
fwrite(STDERR, $msg . PHP_EOL);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$content = file_get_contents(__DIR__ . '/../pages/skills.php');
|
||||||
|
assertTrue(strpos($content, 'Outils Démontrables') !== false, 'missing demonstrable section');
|
||||||
|
assertTrue(strpos($content, 'Autres Outils') !== false, 'missing other tools section');
|
||||||
|
assertTrue(strpos($content, 'target="_blank"') !== false, 'missing external link target');
|
||||||
|
|
||||||
|
$icon = getToolIcon('github');
|
||||||
|
assertTrue(strpos($icon, '<svg') !== false, 'icon svg missing');
|
||||||
|
|
||||||
|
fwrite(STDOUT, "OK\n");
|
||||||
Reference in New Issue
Block a user