bujo et modification de texte

This commit is contained in:
2026-01-18 21:50:42 +04:00
parent a581da5d50
commit 088550a85a
32 changed files with 2544 additions and 62 deletions

View File

@@ -1,5 +1,12 @@
// @ts-check // @ts-check
import { defineConfig } from 'astro/config'; import { defineConfig } from 'astro/config';
import tailwindcss from "@tailwindcss/vite";
import mdx from "@astrojs/mdx";
// https://astro.build/config // https://astro.build/config
export default defineConfig({}); export default defineConfig({
vite: {
plugins: [tailwindcss()],
},
integrations: [mdx()]
});

View File

@@ -36,8 +36,19 @@ const codexCollection = defineCollection({
}), }),
}); });
const bujoCollection = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
publishDate: z.date(),
tags: z.array(z.string()),
period: z.string().optional(),
}),
});
export const collections = { export const collections = {
journal: journalCollection, journal: journalCollection,
logs: logsCollection, logs: logsCollection,
codex: codexCollection, codex: codexCollection,
bujo: bujoCollection,
}; };

1341
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -9,6 +9,9 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^5.16.8" "@astrojs/mdx": "^4.3.13",
"@tailwindcss/vite": "^4.1.18",
"astro": "^5.16.8",
"tailwindcss": "^4.1.18"
} }
} }

View File

@@ -0,0 +1,41 @@
---
import { getCollection } from 'astro:content';
const months = [
"Janvier", "Février", "Mars", "Avril", "Mai", "Juin",
"Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"
];
// 1. Récupérer tous les événements futurs
const futureEvents = await getCollection('bujo', ({ id }) => {
return id.startsWith('future/');
});
// 2. Grouper les événements par mois
const eventsByMonth = {};
futureEvents.forEach(event => {
const monthIndex = event.data.publishDate.getMonth(); // 0 = Janvier, 1 = Février, etc.
if (!eventsByMonth[monthIndex]) {
eventsByMonth[monthIndex] = [];
}
eventsByMonth[monthIndex].push(event);
});
---
<h1 class="text-3xl font-bold mb-2">Future Log</h1>
<p class="text-slate-500 mb-8">La vue d'ensemble de l'année à venir. Les grands rendez-vous, les voyages, les jalons importants.</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
{months.map((monthName, index) => (
<div class="bg-white p-4 rounded-lg border border-slate-200 shadow-sm">
<h3 class="font-bold text-lg mb-3 text-slate-800">{monthName} 2026</h3>
<div class="space-y-2">
{eventsByMonth[index] ? eventsByMonth[index].map(event => (
<div class="text-sm p-2 bg-blue-50 rounded text-blue-800">{event.data.publishDate.getDate()} - {event.data.title}</div>
)) : (
<div class="h-6 bg-slate-100 rounded opacity-50"></div>
)}
</div>
</div>
))}
</div>

View File

@@ -0,0 +1,59 @@
---
const { months } = Astro.props;
---
<h1 class="text-3xl font-bold mb-6 border-b pb-4">Index du Journal</h1>
<section class="mb-8">
<h2 class="text-2xl font-semibold mb-4 text-slate-700">Fondations</h2>
<ul class="list-disc list-inside space-y-2">
<li><a href="/bujo/keys" class="text-blue-600 hover:underline">Clés (Keys) - Notre langage de symboles</a></li>
<li><a href="/bujo/future-log" class="text-blue-600 hover:underline">Future Log - Le planning annuel</a></li>
</ul>
</section>
<section class="mb-8">
<h2 class="text-2xl font-semibold mb-4 text-slate-700">Logs Temporels</h2>
<p class="text-slate-600 mb-4">Le cœur du journal, où le temps est cartographié mois par mois.</p>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
{months.map(monthPath => {
const [year, month] = monthPath.split('/');
const monthName = new Date(parseInt(year), parseInt(month) - 1).toLocaleString('fr-FR', { month: 'long' });
return (
<a href={`/bujo/${monthPath}`} class="bg-slate-100 p-4 rounded-lg text-center font-semibold hover:bg-blue-100 transition-colors">
{monthName.charAt(0).toUpperCase() + monthName.slice(1)} {year}
</a>
)
})}
</div>
</section>
<section>
<h2 class="text-2xl font-semibold mb-4 text-slate-700">Collections</h2>
<p class="text-slate-600 mb-4">Les pages thématiques qui rassemblent idées, suivis et inspirations.</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="bg-slate-50 p-4 rounded-lg">
<h3 class="font-semibold text-slate-800 mb-2">Organisation & Suivi</h3>
<ul class="list-disc list-inside space-y-2 text-sm">
<li><a href="/bujo/collections/trackers-mensuels" class="text-blue-600 hover:underline">Trackers d'Habitudes</a></li>
<li><a href="/bujo/collections/objectifs-du-mois" class="text-blue-600 hover:underline">Objectifs du Mois</a></li>
<li><a href="/bujo/collections/suivi-depenses" class="text-blue-600 hover:underline">Suivi des Dépenses</a></li>
</ul>
</div>
<div class="bg-slate-50 p-4 rounded-lg">
<h3 class="font-semibold text-slate-800 mb-2">Inspiration & Bien-être</h3>
<ul class="list-disc list-inside space-y-2 text-sm">
<li><a href="/bujo/collections/gratitude" class="text-blue-600 hover:underline">Journal de Gratitude</a></li>
<li><a href="/bujo/collections/brain-dump" class="text-blue-600 hover:underline">Brain Dump (Vide-esprit)</a></li>
<li><a href="/bujo/collections/bucket-list" class="text-blue-600 hover:underline">Bucket List</a></li>
</ul>
</div>
<div class="bg-slate-50 p-4 rounded-lg">
<h3 class="font-semibold text-slate-800 mb-2">Créativité & Culture</h3>
<ul class="list-disc list-inside space-y-2 text-sm">
<li><a href="/bujo/collections/livres-a-lire" class="text-blue-600 hover:underline">Livres à lire</a></li>
<li><a href="/bujo/collections/films-a-voir" class="text-blue-600 hover:underline">Films & Séries à voir</a></li>
<li><a href="/bujo/collections/idees-projets" class="text-blue-600 hover:underline">Idées de Projets Créatifs</a></li>
</ul>
</div>
</div>
</section>

View File

@@ -0,0 +1,50 @@
---
---
<h1 class="text-3xl font-bold mb-6 border-b pb-4">Les Clés</h1>
<p class="mb-6">Ceci est notre langage pour capturer les pensées rapidement. Chaque symbole a une intention.</p>
<div class="space-y-8">
<section>
<h2 class="text-xl font-bold text-slate-700 border-b pb-2 mb-4">Symboles de Base</h2>
<ul class="space-y-4 text-lg">
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl">•</span><span>Tâche à faire</span></li>
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl text-green-600">X</span><span>Tâche terminée</span></li>
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl text-blue-600">&gt;</span><span>Tâche reportée (migrée)</span></li>
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl text-orange-600">&lt;</span><span>Tâche planifiée (calendrier)</span></li>
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl">○</span><span>Événement</span></li>
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl"></span><span>Note / Idée</span></li>
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl text-slate-400"><s>•</s></span><span>Tâche annulée</span></li>
</ul>
</section>
<section>
<h2 class="text-xl font-bold text-slate-700 border-b pb-2 mb-4">Signifiants de Priorité (Préfixes)</h2>
<p class="text-sm text-slate-500 mb-4">Placés à gauche du symbole de base pour ajouter du contexte.</p>
<ul class="space-y-4 text-lg">
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl text-red-500">*</span><span>Priorité absolue</span></li>
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl text-yellow-500">!</span><span>Inspiration, Eurêka !</span></li>
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl text-green-700">$</span><span>Aspect financier</span></li>
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl">👁️</span><span>À explorer / Rechercher</span></li>
</ul>
</section>
<section>
<h2 class="text-xl font-bold text-slate-700 border-b pb-2 mb-4">Souffle de Vie (Bien-être & Réflexion)</h2>
<ul class="space-y-4 text-lg">
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl">△</span><span>Leçon apprise, réflexion</span></li>
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl text-pink-500">♡</span><span>Moment de gratitude</span></li>
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl">⭘</span><span>En attente (dépend de qqn d'autre)</span></li>
<li class="flex items-center"><span class="w-8 text-center font-mono text-xl">⚓</span><span>Rituel, habitude ancrée</span></li>
</ul>
</section>
<section class="mt-12 pt-6 border-t">
<h3 class="text-lg font-semibold mb-2">Exemple d'utilisation :</h3>
<div class="p-4 bg-slate-50 rounded-lg text-slate-700 font-mono">
<p>* • Finaliser le projet A</p>
<p>$ Penser à renouveler l'abonnement</p>
<p>! △ La patience est la forme la plus douce du courage.</p>
<p>○ Dîner avec Marc à 20h</p>
</div>
</section>
</div>

View File

@@ -0,0 +1,39 @@
---
// Exemple de données. Plus tard, cela pourrait venir de fichiers de contenu.
const books = [
{ title: "Vers la beauté", author: "David Foenkinos", status: "En cours" },
];
const booksByStatus = {
'En cours': books.filter(b => b.status === 'En cours'),
'À lire': books.filter(b => b.status === 'À lire'),
'À acheter': books.filter(b => b.status === 'À acheter'),
'Lu': books.filter(b => b.status === 'Lu'),
};
const statusStyles = {
'En cours': 'bg-blue-100 text-blue-800',
'À lire': 'bg-yellow-100 text-yellow-800',
'Lu': 'bg-green-100 text-green-800',
};
---
<h1 class="text-3xl font-bold mb-2">Collection : Livres à lire</h1>
<p class="text-slate-500 mb-8">La pile de savoir et d'évasion qui attend d'être explorée.</p>
{Object.entries(booksByStatus).map(([status, bookList]) => (
<section class="mb-8">
<h2 class="text-xl font-bold text-slate-700 border-b pb-2 mb-4">{status}</h2>
<ul class="space-y-3">
{bookList.map(book => (
<li class="p-4 bg-white rounded-md shadow-sm border border-slate-200 flex justify-between items-center">
<div>
<p class="font-semibold">{book.title}</p>
<p class="text-sm text-slate-500">{book.author}</p>
</div>
<span class={`text-xs font-semibold px-2 py-1 rounded-full ${statusStyles[status]}`}>{book.status}</span>
</li>
))}
</ul>
</section>
))}

View File

@@ -0,0 +1,38 @@
---
// Example data.
const items = [
{ title: "Demon Slayer : La forteresse infinie", type: "Film", status: "Vu" },
];
const itemsByStatus = {
'En cours': items.filter(b => b.status === 'En cours'),
'À voir': items.filter(b => b.status === 'À voir'),
'Vu': items.filter(b => b.status === 'Vu'),
};
const statusStyles = {
'En cours': 'bg-blue-100 text-blue-800',
'À voir': 'bg-yellow-100 text-yellow-800',
'Vu': 'bg-green-100 text-green-800',
};
---
<h1 class="text-3xl font-bold mb-2">Collection : Films & Séries à voir</h1>
<p class="text-slate-500 mb-8">Pour ne jamais être à court d'idées lors d'une soirée cinéma.</p>
{Object.entries(itemsByStatus).map(([status, itemList]) => (
<section class="mb-8">
<h2 class="text-xl font-bold text-slate-700 border-b pb-2 mb-4">{status}</h2>
<ul class="space-y-3">
{itemList.map(item => (
<li class="p-4 bg-white rounded-md shadow-sm border border-slate-200 flex justify-between items-center">
<div>
<p class="font-semibold">{item.title}</p>
<p class="text-sm text-slate-500">{item.type}</p>
</div>
<span class={`text-xs font-semibold px-2 py-1 rounded-full ${statusStyles[status]}`}>{item.status}</span>
</li>
))}
</ul>
</section>
))}

View File

@@ -0,0 +1,46 @@
---
// Example data. This could later come from content files.
const objectives = [
{
title: "Finaliser le pivot structurel du site",
steps: [
]
},
{
title: "Lancer la section 'Journal de Bord'",
steps: [
{ text: "Créer l'architecture du Bujo", done: true },
{ text: "Remplir les collections de base", done: true },
]
},
{
title: "Améliorer ma pratique d'Obsidian",
steps: [
]
},
{
title: "Améliorer ma pratique d'Astro",
steps: [
]
}
];
---
<h1 class="text-3xl font-bold mb-2">Collection : Objectifs du Mois</h1>
<p class="text-slate-500 mb-8">Découper les grandes ambitions en étapes réalisables pour rester motivé.</p>
<div class="space-y-6">
{objectives.map(obj => (
<div class="bg-white p-4 rounded-lg border border-slate-200 shadow-sm">
<h3 class="font-semibold text-lg text-slate-800 mb-3">{obj.title}</h3>
<ul class="space-y-2">
{obj.steps.map(step => (
<li class="flex items-center text-sm">
<input type="checkbox" checked={step.done} class="h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 mr-3" />
<span class:list={[{ "line-through text-slate-400": step.done }]}>{step.text}</span>
</li>
))}
</ul>
</div>
))}
</div>

View File

@@ -0,0 +1,10 @@
---
const { collectionTitle } = Astro.props;
const capitalizedTitle = collectionTitle ? collectionTitle.charAt(0).toUpperCase() + collectionTitle.slice(1) : "Collection";
---
<h1 class="text-3xl font-bold mb-2">Collection : {capitalizedTitle}</h1>
<p class="text-slate-500 mb-8">Cette collection est en cours de construction.</p>
<div class="p-8 text-center bg-slate-50 rounded-lg border-2 border-dashed border-slate-300">
<p class="text-slate-500 italic">Contenu à venir...</p>
</div>

View File

@@ -0,0 +1,63 @@
---
// Exemple de données. Plus tard, cela pourrait venir de fichiers de contenu.
const habits = [
"Sport (3x/sem)",
"Méditation",
"Lecture",
"Écriture (Log/Journal)",
"Pratique du code",
"Budget respecté",
"Coucher avant 23h"
];
const daysInMonth = 31; // Pour Janvier, à rendre dynamique plus tard
// C'est ici que vous contrôlez l'état du tracker.
// Pour chaque habitude, listez les jours où elle a été complétée.
const completedHabits = {
"Sport (3x/sem)": [],
"Méditation": [],
"Lecture": [],
"Écriture (Log/Journal)": [17, 18],
"Pratique du code": [17,18],
"Budget respecté": [],
"Coucher avant 23h": [],
};
---
<h1 class="text-3xl font-bold mb-2">Collection : Trackers Mensuels</h1>
<p class="text-slate-500 mb-8">Une vue d'ensemble pour cultiver la discipline et observer les schémas qui se dessinent.</p>
<section>
<h2 class="text-2xl font-semibold mb-4 text-slate-800">Janvier 2026</h2>
<div class="overflow-x-auto rounded-lg border border-slate-200">
<table class="min-w-full text-sm text-left">
<thead class="bg-slate-50 text-slate-600">
<tr>
<th class="p-2 font-semibold">Habitude</th>
{Array.from({ length: daysInMonth }, (_, i) => (
<th class="w-10 h-10 p-1 text-center font-mono font-normal">{i + 1}</th>
))}
</tr>
</thead>
<tbody class="bg-white">
{habits.map(habit => (
<tr class="border-t border-slate-200 align-middle">
<td class="p-2 font-semibold">{habit}</td>
{Array.from({ length: daysInMonth }, (_, i) => {
const day = i + 1;
const isCompleted = completedHabits[habit]?.includes(day);
const cellClass = isCompleted ? 'bg-green-400' : 'bg-white';
return (
<td class="p-1 text-center">
<div class={`w-6 h-6 border border-slate-300 rounded-sm mx-auto ${cellClass}`}></div>
</td>
);
})}
</tr>
))}
</tbody>
</table>
</div>
<p class="text-xs text-slate-400 mt-2">Astuce : Sur mobile, la grille peut être scrollée horizontalement.</p>
</section>

View File

@@ -0,0 +1,24 @@
---
const { symbol } = Astro.props;
const keyMap = {
'•': { style: '' },
'X': { style: 'text-green-600' },
'>': { style: 'text-blue-600' },
'<': { style: 'text-orange-600' },
'○': { style: '' },
'': { style: '' },
's': { style: 'text-slate-400', symbol: '<s>•</s>' }, // Cas spécial pour la tâche annulée
'*': { style: 'text-red-500' },
'!': { style: 'text-yellow-500' },
'$': { style: 'text-green-700' },
'👁️': { style: '' },
'△': { style: '' },
'♡': { style: 'text-pink-500' },
'⭘': { style: '' },
'⚓': { style: '' },
};
const currentKey = keyMap[symbol] || { style: '', symbol: symbol };
---
<span class:list={["w-8 inline-block text-center font-mono text-xl", currentKey.style]} set:html={currentKey.symbol || symbol} />

View File

@@ -0,0 +1,62 @@
---
const { logs, year, month } = Astro.props;
const yearNum = parseInt(year);
const monthNum = parseInt(month);
const monthName = new Date(yearNum, monthNum - 1).toLocaleString('fr-FR', { month: 'long' });
const capitalizedMonthName = monthName.charAt(0).toUpperCase() + monthName.slice(1);
// --- Logique du Calendrier ---
const daysInMonth = new Date(yearNum, monthNum, 0).getDate();
const firstDayOfMonth = new Date(yearNum, monthNum - 1, 1).getDay(); // 0=Dim, 1=Lun, ...
const startOffset = firstDayOfMonth === 0 ? 6 : firstDayOfMonth - 1;
const weekDays = ['Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam', 'Dim'];
const logsByDay = new Map(logs.map(log => {
const day = log.data.publishDate.getDate();
return [day, log];
}));
---
<h1 class="text-3xl font-bold mb-2">Monthly Log</h1>
<p class="text-slate-500 mb-8">{capitalizedMonthName} {year}</p>
<!-- Vue Calendrier -->
<div class="grid grid-cols-7 gap-1 text-center mb-12">
<!-- Jours de la semaine -->
{weekDays.map(day => <div class="font-bold text-sm text-slate-500 py-2">{day}</div>)}
<!-- Jours vides avant le début du mois -->
{Array.from({ length: startOffset }).map(() => <div />)}
<!-- Jours du mois -->
{Array.from({ length: daysInMonth }, (_, i) => i + 1).map(day => {
const log = logsByDay.get(day);
const currentDate = new Date(yearNum, monthNum - 1, day);
const isToday = new Date().toDateString() === currentDate.toDateString();
const dayOfWeek = currentDate.getDay();
const isWeekend = dayOfWeek === 0 || dayOfWeek === 6;
return (
<a href={log ? `/bujo/${log.slug}` : '#'} class:list={[
"h-12 w-12 flex items-center justify-center rounded-full transition-colors",
{ "bg-slate-50 text-slate-500": isWeekend && !log },
{ "bg-blue-500 text-white font-bold": isToday && log },
{ "border-2 border-blue-500": isToday && !log },
{ "bg-blue-100 hover:bg-blue-200 font-semibold": log && !isToday },
{ "pointer-events-none": !log }
]}>{day}</a>
);
})}
</div>
<!-- Liste des entrées -->
<h2 class="text-2xl font-semibold mb-4 border-t pt-8">Toutes les entrées du mois</h2>
<ul class="space-y-4">
{logs.map(log => (
<li class="border-b border-slate-200 pb-3">
<a href={`/bujo/${log.slug}`} class="text-lg font-semibold text-blue-600 hover:underline">{log.data.title}</a>
</li>
))}
</ul>

View File

@@ -0,0 +1,71 @@
---
title: "Daily Log - 18 Janvier 2026"
publishDate: 2026-01-18
tags: ["Daily", "Pivot", "Organisation"]
---
import Key from '~/components/bujo/Key.astro';
<div class="mb-8 p-4 bg-blue-50 border-l-4 border-blue-400">
<h2 class="text-xl font-bold text-slate-800 mb-2"><Key symbol="⚓" /> Ancrage & Bien-être</h2>
<ul class="space-y-2">
<li><Key symbol="•" /> Routine du matin (douche, dents...)</li>
<li><Key symbol="X" /> Activité physique</li>
<li><Key symbol="" /> Qualité du sommeil (1-5) : 3</li>
<li><Key symbol="" /> Humeur du jour (1-5) : 4</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="*" /> Objectifs du Dimanche</h2>
<p class="text-sm text-slate-500 mb-3">Une ou deux choses pour profiter de la journée et se sentir bien.</p>
<ul class="space-y-2">
<li><Key symbol="X" /> [Objectif principal]</li>
<li><Key symbol="X" /> [Autre petite tâche]</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="$" /> Organisation & Budget</h2>
<ul class="space-y-2">
<li><Key symbol="X" /> Planifier les repas de la semaine à venir</li>
<li><Key symbol="X" /> Chercher une activité gratuite ou un bon plan</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="•" /> Foyer & Préparation de la semaine</h2>
<ul class="space-y-2">
<li><Key symbol="X" /> Session de rangement (15 min)</li>
<li><Key symbol="X" /> Préparer les vêtements pour lundi</li>
<li><Key symbol="X" /> Tâche ménagère au choix (lessive, vaisselle...)</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="♡" /> Loisirs & Note du jour</h2>
<p class="text-slate-600 mt-2">Un moment pour soi, une pensée, une petite victoire :</p>
<p class="mt-4 p-3 bg-amber-50 text-amber-900 border-l-4 border-amber-400 rounded-r-lg italic">Ce matin après la séance d'hier c'était très compliqué de pouvoir tenir la routine du jour. Je me suis réveillé vers 13h30, je suis sorti du lit vers 14h 14h30... Mais je me sens reposé, je n'ai pas le cou qui tire aujourd'hui, ou encore de migraine particulière. Deux objectifs principales aujourd'hui. La première était de faire le résumé de la session de JDR d'hier. La seconde de commencer à créer mon bullet Journal, ce n'est que le début mais c'est déjà ça.. J'ai réussi à faire les deux et j'ai fait ma lessive, j'ai tendu mon ligne. J'ai rangé un peu mes affaires. Jai créé mon bullet journal aujourdhui je suis trop content.. Il y a tellement de chose à faire encore mais franchement, ça fait plaisir !</p>
<textarea id="daily-note" class="w-full mt-2 p-2 border rounded bg-slate-50" rows="2" placeholder="..."></textarea>
</div>
<script is:inline>
{`
// On s'assure que le script s'exécute une fois la page chargée
document.addEventListener('DOMContentLoaded', () => {
const textarea = document.getElementById('daily-note');
// Clé unique pour cette entrée de journal, basée sur la date
const storageKey = 'note-' + new URL(window.location.href).pathname;
// 1. Charger la note sauvegardée au chargement de la page
const savedNote = localStorage.getItem(storageKey);
if (savedNote) {
textarea.value = savedNote;
}
// 2. Sauvegarder la note à chaque fois que l'on écrit dedans
textarea.addEventListener('input', () => {
localStorage.setItem(storageKey, textarea.value);
});
});
`}
</script>

View File

@@ -0,0 +1,35 @@
---
title: "Négocier contrat Cirrus"
publishDate: 2026-04-01
tags: ["future-log", "pro"]
---
*• Préparer la renégociation du contrat.
Deux ans d'ancienneté, c'est un pivot stratégique. Le moment est venu d'aligner le contrat avec la valeur apportée.
### A. Bilan des Réalisations (Le Factuel)
• Lister les réalisations concrètes :
- $ Chiffres clés (hausse CA, gain de temps, économies).
- • Projets complexes menés de A à Z.
- • Tâches et responsabilités acquises hors contrat initial (Argument n°1).
### B. Étude du Marché
👁️ Rechercher ma valeur sur le marché actuel :
- • Consulter les simulateurs de salaire (Apec, Glassdoor).
- • Analyser les offres d'emploi pour des postes similaires.
L'objectif n'est pas de menacer, mais de démontrer une connaissance de ma valeur.
### C. Préparer le "Panier de Négociation"
• Définir les demandes au-delà du salaire :
- $ Rémunération : Salaire de base, primes.
- ♡ Qualité de vie : Télétravail, aménagement d'horaires.
- • Évolution : Formation certifiante, changement de poste.
### D. L'Entretien
< ○ Demander un entretien spécifique pour discuter de mon évolution.
Pendant l'entretien : rester positif, être précis dans les demandes, et préparer une réponse au "non" ("Que dois-je accomplir dans les 6 prochains mois ?").

View File

@@ -0,0 +1,6 @@
---
title: "Vacances, rencontres et affaires"
publishDate: 2026-09-15
tags: ["future-log", "perso"]
---
Préparer le voyage pour la métropole et réserver les billets.

View File

@@ -1,44 +0,0 @@
import { defineCollection, z } from 'astro:content';
// Collection pour le Journal de bord de la campagne JDR
const journalCollection = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
author: z.string(),
publishDate: z.date(),
tags: z.array(z.string()).optional(),
}),
});
// Collection pour les logs de développement et de réflexion
const logsCollection = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
publishDate: z.date(),
tags: z.array(z.string()).optional(),
}),
});
// Collection pour le "Codex de la Substance" (apprentissage)
const codexCollection = defineCollection({
type: "content",
schema: z.object({
title: z.string(),
subtitle: z.string(),
publishDate: z.date(),
tags: z.array(z.string()),
domain: z.string(), // Le nouveau champ pour le domaine d'étude
concept2D: z.string(),
mecanique: z.string(),
vision3D: z.string(),
status: z.enum(["Acquis", "En cours", "À explorer"]),
}),
});
export const collections = {
journal: journalCollection,
logs: logsCollection,
codex: codexCollection,
};

View File

@@ -2,7 +2,7 @@
title: "Le Murmure des Rouages" title: "Le Murmure des Rouages"
author: "G'Mas" author: "G'Mas"
publishDate: 2026-01-18 publishDate: 2026-01-18
tags: ["Mine", "Combat", "Krutik", "Nyrae", "Jinn", "Vase Grise"] tags: ["Mine", "Combat", "Kruthik", "Nyrae", "Jinn", "Vase Grise"]
--- ---
### Les Griffes de l'Obscurité ### Les Griffes de l'Obscurité
@@ -13,11 +13,11 @@ S'enfonçant plus profondément dans les galeries désaffectées, le groupe atte
Nous fîmes finalement face à la fameuse porte dans la troisième salle. Les traces des enfants y menaient directement, mais le passage était condamné : le mécanisme était grippé et le gond droit était sorti de son axe, rendant les manivelles inutiles. Tandis que Gurdil soulevait la porte utilisant sa force innée, Bulle et la Bourgmestre s'escrimaient sur les chaînes, Nyrae restait à l'écart, observant la scène avec une ironie féline, comme si nous déployions beaucoup d'énergie pour peu de résultats. C'est alors que je repérais un **cliquet de sûreté** bloqué. En glissant ma main dans les rouages pour libérer un engrenage et agiter quelques ressorts, je parvins à réenclencher la sécurité. La porte reprit son axe, les chaînes se tendirent, et le panneau de fer monta jusqu'à son sommet, maintenu désormais par la sécurité que j'avais restaurée. Nous fîmes finalement face à la fameuse porte dans la troisième salle. Les traces des enfants y menaient directement, mais le passage était condamné : le mécanisme était grippé et le gond droit était sorti de son axe, rendant les manivelles inutiles. Tandis que Gurdil soulevait la porte utilisant sa force innée, Bulle et la Bourgmestre s'escrimaient sur les chaînes, Nyrae restait à l'écart, observant la scène avec une ironie féline, comme si nous déployions beaucoup d'énergie pour peu de résultats. C'est alors que je repérais un **cliquet de sûreté** bloqué. En glissant ma main dans les rouages pour libérer un engrenage et agiter quelques ressorts, je parvins à réenclencher la sécurité. La porte reprit son axe, les chaînes se tendirent, et le panneau de fer monta jusqu'à son sommet, maintenu désormais par la sécurité que j'avais restaurée.
Derrière la porte, des bruits de mastication écœurants rompirent le silence. Quatre **Krutiks** — des insectes de la taille d'un chien — dévoraient un rat géant. Trop occupés par leur festin, ils ne nous virent pas venir, et nous passâmes à l'attaque. **Gurdil** ouvrit le bal avec ses hachettes volantes, fauchant le premier adversaire. De mon côté, je déchaînai mon souffle à travers mon **souffle-quart** — ce bâton qui me sert tour à tour de guide, de boussole et de sarbacane — touchant un ennemi de plein fouet. Malheureusement, ces bestioles semblaient immunisées à mes toxines. **Bulle** acheva la première bête d'une flèche précise et de la vitesse d'un éclair, tandis que **Jinn** et **Nyrae** tentaient de contenir le reste de la meute. Derrière la porte, des bruits de mastication écœurants rompirent le silence. Quatre **Kruthiks** — des insectes de la taille d'un chien — dévoraient un rat géant. Trop occupés par leur festin, ils ne nous virent pas venir, et nous passâmes à l'attaque. **Gurdil** ouvrit le bal avec ses hachettes volantes, fauchant le premier adversaire. De mon côté, je déchaînai mon souffle à travers mon **souffle-quart** — ce bâton qui me sert tour à tour de guide, de boussole et de sarbacane — touchant un ennemi de plein fouet. Malheureusement, ces bestioles semblaient immunisées à mes toxines. **Bulle** acheva la première bête d'une flèche précise et de la vitesse d'un éclair, tandis que **Jinn** et **Nyrae** tentaient de contenir le reste de la meute.
Cependant, la chance tourna. Nos coups commencèrent à rater, comme si nous étions nous-mêmes perturbés par quelque chose. Gurdil, une goutte de sueur perlant sur son front, fixait une paroi rocheuse avec insistance, sentant un danger tapis. Soudain, un Krutik nous prit à revers tandis que le rocher surveillé par le nain se liquéfiait en une **Vase Grise**. Ce fléau, capable de dissoudre l'acier, constituait un danger certain malgré sa lenteur. Le combat devint chaotique : **Jinn**, submergé, s'effondra inconscient sous les assauts des deux derniers Krutiks. Cependant, la chance tourna. **Jinn**, dans une manœuvre aussi audacieuse que déroutante, tenta de rendre le festin des Kruthiks plus... appétissant. D'un geste, il projeta une gerbe de flammes non pas sur les créatures, mais sur la carcasse du rat, espérant que l'odeur de viande grillée les distrairait. L'effet fut immédiat, mais pas celui escompté : le rat fut entièrement carbonisé, et les créatures, privées de leur repas, devinrent encore plus hostiles. Le fouet de **Nyrae** claqua dans l'air, mais les Kruthiks, agiles et enragés, esquivèrent l'assaut. Nos coups commencèrent à rater, comme si nous étions nous-mêmes perturbés par la tournure des événements. Gurdil, une goutte de sueur perlant sur son front, fixait une paroi rocheuse avec insistance, sentant un danger tapis. Soudain, un Kruthik nous prit à revers tandis que le rocher surveillé par le nain se liquéfiait en une **Vase Grise**. Ce fléau, capable de dissoudre l'acier, constituait un danger certain malgré sa lenteur. Le combat devint chaotique : **Jinn**, après avoir courageusement vaporisé une partie de la vase d'un trait de feu, fut submergé et s'effondra inconscient sous les assauts des deux derniers Kruthiks.
Le groupe réagit alors avec une coordination héroïque. **Gurdil** pulvérisa un Krutik d'un coup de marteau dévastateur. **Nyrae** créa une ouverture en "tenaille", me permettant de fracasser une autre créature avec mon **bâton au quart d'un souffle**. **Bulle** marqua la Vase d'un _Éclair Traçant_, et **Nyrae** acheva la masse gélatineuse d'un coup de fouet salvateur avant qu'elle ne nous dissolve. Le groupe réagit alors avec une coordination héroïque. **Gurdil** pulvérisa un Kruthik d'un coup de marteau dévastateur. **Nyrae** créa une ouverture en "tenaille", me permettant de fracasser une autre créature avec mon **bâton au quart d'un souffle**. **Bulle** marqua la Vase d'un _Éclair Traçant_, et **Nyrae** acheva la masse gélatineuse d'un coup de fouet salvateur avant qu'elle ne nous dissolve.
Le calme revenu, nous avons secouru **Jinn**. Stabilisé par Bulle et soigné par Maielan, le Génasi reprit connaissance. Nyrae se contenta d'un simple "Mouais..." laconique en croisant son regard, soulignant le poids de l'épreuve. Après s'être lui même soigné, Jinn retrouva assez de forces pour continuer. Nous avons repris la marche jusqu'au bout du couloir. Là, un **mur maçonné**, étrangement propre et hors de place, nous barrait la route. Une partie de son centre est effondrée. C'est de l'autre côté, dans ce vide inconnu, que nous entendons enfin les voix des enfants. Qu'est-ce qui a bien pu être enfermé ici ? Le calme revenu, nous avons secouru **Jinn**. Stabilisé par Bulle et soigné par Maielan, le Génasi reprit connaissance. Nyrae se contenta d'un simple "Mouais..." laconique en croisant son regard, soulignant le poids de l'épreuve. Après s'être lui même soigné, Jinn retrouva assez de forces pour continuer. Nous avons repris la marche jusqu'au bout du couloir. Là, un **mur maçonné**, étrangement propre et hors de place, nous barrait la route. Une partie de son centre est effondrée. C'est de l'autre côté, dans ce vide inconnu, que nous entendons enfin les voix des enfants. Qu'est-ce qui a bien pu être enfermé ici ?
@@ -27,6 +27,6 @@ Le calme revenu, nous avons secouru **Jinn**. Stabilisé par Bulle et soigné pa
- **Jinn :** Affaibli mais conscient (récupération en cours). - **Jinn :** Affaibli mais conscient (récupération en cours).
- **G'mas (moi) :** En pleine forme, baigné par l'éclat de la grotte. - **G'mas (moi) :** En pleine forme, baigné par l'éclat de la grotte.
- **Gurdil :** Prêt au combat, hachette aux dents, hache à deux mains prête. - **Gurdil :** Prêt au combat, hachette aux dents, marteau à deux mains prêt.
- **Bulle & Nyrae :** Indemnes. - **Bulle & Nyrae :** Indemnes.
- **Tableau de chasse :** 5 Krutiks et 1 Vase Grise éliminés. - **Tableau de chasse :** 5 Kruthiks et 1 Vase Grise éliminés.

View File

@@ -0,0 +1,32 @@
---
title: "Déconstruction pour un Nouveau Souffle"
publishDate: 2026-01-18
tags: ["Architecture", "Pivot", "Blueprint", "GSAP", "State Management"]
---
**Log de Construction #04**
**Statut :** Pivot structurel / Phase de Blueprint
**Sujet :** Abandon du modèle actuel pour la Voie du "Slide Navigator"
### 1. Le Constat du Mécanicien
Après avoir testé l'architecture actuelle, le verdict tombe : les pièces s'emboîtent, mais le moteur ne tourne pas rond. L'expérience manque de fluidité, le "souffle de vie" (Hebel) s'éparpille dans une structure trop complexe qui ne rend pas hommage à l'esthétique *Storybook* que je vise.
Vouloir construire la carrosserie avant d'avoir stabilisé le châssis est une erreur de débutant que je choisis de corriger aujourd'hui.
### 2. La Voie du "Slide Navigator"
Je décide de revenir à l'essentiel : **la narration séquentielle**. Plutôt qu'un site web classique, je vais structurer l'expérience comme une galerie interactive, un "PowerPoint 3D" où chaque vue est une étape clé de mon pèlerinage.
Ce choix s'impose pour plusieurs raisons :
* **Contrôle du Flux :** Chaque "slide" devient une scène Three.js maîtrisée (position caméra, éclairage, UI spécifique).
* **Clarté Narrative :** On ne se perd plus dans le site ; on tourne les pages d'un grimoire numérique.
* **Prototypage Rapide :** Cela me permet de valider le passage de l'écran titre au menu "Hebel", puis à la Timeline, avec la précision d'un mécanicien qui règle ses soupapes.
### 3. Prochaines Étapes (Le Blueprint)
Le chantier se concentre désormais sur le **"State Controller"**. Il s'agira de définir un tableau d'objets contenant les coordonnées de chaque scène, puis d'utiliser **GSAP** pour créer des transitions fluides entre ces "slides", simulant un voyage cinématographique. Les calques d'interface HTML resteront superposés au canvas pour garantir une accessibilité totale.
*Le grain de sable ne s'arrête pas, il change de trajectoire pour mieux dessiner l'oasis.*

View File

@@ -0,0 +1,39 @@
---
import {ClientRouter} from 'astro:transitions';
import '../styles/global.css';
interface Props {
title: string;
}
const { title } = Astro.props;
---
<!doctype html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="description" content="Le journal de bord de l'artisan." />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
<ClientRouter />
</head>
<body class="bg-slate-100 text-slate-800 font-sans">
<main class="max-w-3xl mx-auto p-4 sm:p-8">
<header class="mb-8 text-center">
<a href="/bujo" class="text-2xl font-bold text-slate-900 hover:text-blue-700 transition-colors duration-300">
Journal de Bord
</a>
<p class="text-slate-500">Le codex de la vie de l'artisan.</p>
</header>
<div class="bg-white rounded-lg shadow-md p-6 sm:p-8">
<slot />
</div>
<footer class="text-center mt-12 text-sm text-slate-400">
<a href="/auteur" class="hover:text-slate-600">Retour à la page Auteur</a>
</footer>
</main>
</body>
</html>

60
src/modele/19.mdx Normal file
View File

@@ -0,0 +1,60 @@
---
title: "Daily Log - 19 Janvier 2026"
publishDate: 2026-01-19
tags: ["Daily", "Work", "Organisation"]
---
import Key from '~/components/bujo/Key.astro';
<div class="mb-8 p-4 bg-blue-50 border-l-4 border-blue-400">
<h2 class="text-xl font-bold text-slate-800 mb-2"><Key symbol="⚓" /> Ancrage & Bien-être</h2>
<ul class="space-y-2">
<li><Key symbol="•" /> Routine du matin (douche, dents...)</li>
<li><Key symbol="•" /> Activité physique douce (étirements, marche...)</li>
<li><Key symbol="" /> Qualité du sommeil (1-5) : __</li>
<li><Key symbol="" /> Humeur du jour (1-5) : __</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="*" /> Priorités du Jour (Pro & Perso)</h2>
<p class="text-sm text-slate-500 mb-3">Se concentrer sur 1 à 3 tâches essentielles pour avancer.</p>
<ul class="space-y-2">
<li><Key symbol="•" /> [Tâche pro n°1]</li>
<li><Key symbol="•" /> [Tâche pro n°2]</li>
<li><Key symbol="•" /> [Tâche perso importante]</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="$" /> Organisation & Budget</h2>
<ul class="space-y-2">
<li><Key symbol="•" /> Planifier le repas du soir</li>
<li><Key symbol="👁️" /> Point rapide sur les comptes</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="•" /> Foyer & Routine du soir</h2>
<ul class="space-y-2">
<li><Key symbol="•" /> Ranger l'espace de travail (5 min)</li>
<li><Key symbol="•" /> Préparer les affaires pour demain</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="♡" /> Loisirs & Note du jour</h2>
<p class="text-slate-600 mt-2">Un moment pour soi, une pensée, une petite victoire :</p>
<textarea id="daily-note-19" class="w-full mt-2 p-2 border rounded bg-slate-50" rows="2" placeholder="..."></textarea>
</div>
<script is:inline>
{`
document.addEventListener('DOMContentLoaded', () => {
const textarea = document.getElementById('daily-note-19');
const storageKey = 'note-/bujo/2026/01/19';
const savedNote = localStorage.getItem(storageKey);
if (savedNote) textarea.value = savedNote;
textarea.addEventListener('input', () => localStorage.setItem(storageKey, textarea.value));
});
`}
</script>

60
src/modele/20.mdx Normal file
View File

@@ -0,0 +1,60 @@
---
title: "Daily Log - 20 Janvier 2026"
publishDate: 2026-01-20
tags: ["Daily", "Work", "Organisation"]
---
import Key from '~/components/bujo/Key.astro';
<div class="mb-8 p-4 bg-blue-50 border-l-4 border-blue-400">
<h2 class="text-xl font-bold text-slate-800 mb-2"><Key symbol="⚓" /> Ancrage & Bien-être</h2>
<ul class="space-y-2">
<li><Key symbol="•" /> Routine du matin (douche, dents...)</li>
<li><Key symbol="•" /> Activité physique douce (étirements, marche...)</li>
<li><Key symbol="" /> Qualité du sommeil (1-5) : __</li>
<li><Key symbol="" /> Humeur du jour (1-5) : __</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="*" /> Priorités du Jour (Pro & Perso)</h2>
<p class="text-sm text-slate-500 mb-3">Se concentrer sur 1 à 3 tâches essentielles pour avancer.</p>
<ul class="space-y-2">
<li><Key symbol="•" /> [Tâche pro n°1]</li>
<li><Key symbol="•" /> [Tâche pro n°2]</li>
<li><Key symbol="•" /> [Tâche perso importante]</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="$" /> Organisation & Budget</h2>
<ul class="space-y-2">
<li><Key symbol="•" /> Planifier le repas du soir</li>
<li><Key symbol="👁️" /> Point rapide sur les comptes</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="•" /> Foyer & Routine du soir</h2>
<ul class="space-y-2">
<li><Key symbol="•" /> Ranger l'espace de travail (5 min)</li>
<li><Key symbol="•" /> Préparer les affaires pour demain</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="♡" /> Loisirs & Note du jour</h2>
<p class="text-slate-600 mt-2">Un moment pour soi, une pensée, une petite victoire :</p>
<textarea id="daily-note-20" class="w-full mt-2 p-2 border rounded bg-slate-50" rows="2" placeholder="..."></textarea>
</div>
<script is:inline>
{`
document.addEventListener('DOMContentLoaded', () => {
const textarea = document.getElementById('daily-note-20');
const storageKey = 'note-/bujo/2026/01/20';
const savedNote = localStorage.getItem(storageKey);
if (savedNote) textarea.value = savedNote;
textarea.addEventListener('input', () => localStorage.setItem(storageKey, textarea.value));
});
`}
</script>

60
src/modele/21.mdx Normal file
View File

@@ -0,0 +1,60 @@
---
title: "Daily Log - 21 Janvier 2026"
publishDate: 2026-01-21
tags: ["Daily", "Work", "Organisation"]
---
import Key from '~/components/bujo/Key.astro';
<div class="mb-8 p-4 bg-blue-50 border-l-4 border-blue-400">
<h2 class="text-xl font-bold text-slate-800 mb-2"><Key symbol="⚓" /> Ancrage & Bien-être</h2>
<ul class="space-y-2">
<li><Key symbol="•" /> Routine du matin (douche, dents...)</li>
<li><Key symbol="•" /> Activité physique douce (étirements, marche...)</li>
<li><Key symbol="" /> Qualité du sommeil (1-5) : __</li>
<li><Key symbol="" /> Humeur du jour (1-5) : __</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="*" /> Priorités du Jour (Pro & Perso)</h2>
<p class="text-sm text-slate-500 mb-3">Se concentrer sur 1 à 3 tâches essentielles pour avancer.</p>
<ul class="space-y-2">
<li><Key symbol="•" /> [Tâche pro n°1]</li>
<li><Key symbol="•" /> [Tâche pro n°2]</li>
<li><Key symbol="•" /> [Tâche perso importante]</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="$" /> Organisation & Budget</h2>
<ul class="space-y-2">
<li><Key symbol="•" /> Planifier le repas du soir</li>
<li><Key symbol="👁️" /> Point rapide sur les comptes</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="•" /> Foyer & Routine du soir</h2>
<ul class="space-y-2">
<li><Key symbol="•" /> Ranger l'espace de travail (5 min)</li>
<li><Key symbol="•" /> Préparer les affaires pour demain</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="♡" /> Loisirs & Note du jour</h2>
<p class="text-slate-600 mt-2">Un moment pour soi, une pensée, une petite victoire :</p>
<textarea id="daily-note-21" class="w-full mt-2 p-2 border rounded bg-slate-50" rows="2" placeholder="..."></textarea>
</div>
<script is:inline>
{`
document.addEventListener('DOMContentLoaded', () => {
const textarea = document.getElementById('daily-note-21');
const storageKey = 'note-/bujo/2026/01/21';
const savedNote = localStorage.getItem(storageKey);
if (savedNote) textarea.value = savedNote;
textarea.addEventListener('input', () => localStorage.setItem(storageKey, textarea.value));
});
`}
</script>

60
src/modele/22.mdx Normal file
View File

@@ -0,0 +1,60 @@
---
title: "Daily Log - 22 Janvier 2026"
publishDate: 2026-01-22
tags: ["Daily", "Work", "Organisation"]
---
import Key from '~/components/bujo/Key.astro';
<div class="mb-8 p-4 bg-blue-50 border-l-4 border-blue-400">
<h2 class="text-xl font-bold text-slate-800 mb-2"><Key symbol="⚓" /> Ancrage & Bien-être</h2>
<ul class="space-y-2">
<li><Key symbol="•" /> Routine du matin (douche, dents...)</li>
<li><Key symbol="•" /> Activité physique douce (étirements, marche...)</li>
<li><Key symbol="" /> Qualité du sommeil (1-5) : __</li>
<li><Key symbol="" /> Humeur du jour (1-5) : __</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="*" /> Priorités du Jour (Pro & Perso)</h2>
<p class="text-sm text-slate-500 mb-3">Se concentrer sur 1 à 3 tâches essentielles pour avancer.</p>
<ul class="space-y-2">
<li><Key symbol="•" /> [Tâche pro n°1]</li>
<li><Key symbol="•" /> [Tâche pro n°2]</li>
<li><Key symbol="•" /> [Tâche perso importante]</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="$" /> Organisation & Budget</h2>
<ul class="space-y-2">
<li><Key symbol="•" /> Planifier le repas du soir</li>
<li><Key symbol="👁️" /> Point rapide sur les comptes</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="•" /> Foyer & Routine du soir</h2>
<ul class="space-y-2">
<li><Key symbol="•" /> Ranger l'espace de travail (5 min)</li>
<li><Key symbol="•" /> Préparer les affaires pour demain</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="♡" /> Loisirs & Note du jour</h2>
<p class="text-slate-600 mt-2">Un moment pour soi, une pensée, une petite victoire :</p>
<textarea id="daily-note-22" class="w-full mt-2 p-2 border rounded bg-slate-50" rows="2" placeholder="..."></textarea>
</div>
<script is:inline>
{`
document.addEventListener('DOMContentLoaded', () => {
const textarea = document.getElementById('daily-note-22');
const storageKey = 'note-/bujo/2026/01/22';
const savedNote = localStorage.getItem(storageKey);
if (savedNote) textarea.value = savedNote;
textarea.addEventListener('input', () => localStorage.setItem(storageKey, textarea.value));
});
`}
</script>

60
src/modele/23.mdx Normal file
View File

@@ -0,0 +1,60 @@
---
title: "Daily Log - 23 Janvier 2026"
publishDate: 2026-01-23
tags: ["Daily", "Work", "Organisation"]
---
import Key from '~/components/bujo/Key.astro';
<div class="mb-8 p-4 bg-blue-50 border-l-4 border-blue-400">
<h2 class="text-xl font-bold text-slate-800 mb-2"><Key symbol="⚓" /> Ancrage & Bien-être</h2>
<ul class="space-y-2">
<li><Key symbol="•" /> Routine du matin (douche, dents...)</li>
<li><Key symbol="•" /> Activité physique douce (étirements, marche...)</li>
<li><Key symbol="" /> Qualité du sommeil (1-5) : __</li>
<li><Key symbol="" /> Humeur du jour (1-5) : __</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="*" /> Priorités du Jour (Pro & Perso)</h2>
<p class="text-sm text-slate-500 mb-3">Se concentrer sur 1 à 3 tâches essentielles pour avancer.</p>
<ul class="space-y-2">
<li><Key symbol="•" /> [Tâche pro n°1]</li>
<li><Key symbol="•" /> [Tâche pro n°2]</li>
<li><Key symbol="•" /> [Tâche perso importante]</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="$" /> Organisation & Budget</h2>
<ul class="space-y-2">
<li><Key symbol="•" /> Planifier le repas du soir</li>
<li><Key symbol="👁️" /> Point rapide sur les comptes</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="•" /> Foyer & Routine du soir</h2>
<ul class="space-y-2">
<li><Key symbol="•" /> Ranger l'espace de travail (5 min)</li>
<li><Key symbol="•" /> Préparer les affaires pour demain</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="♡" /> Loisirs & Note du jour</h2>
<p class="text-slate-600 mt-2">Un moment pour soi, une pensée, une petite victoire :</p>
<textarea id="daily-note-23" class="w-full mt-2 p-2 border rounded bg-slate-50" rows="2" placeholder="..."></textarea>
</div>
<script is:inline>
{`
document.addEventListener('DOMContentLoaded', () => {
const textarea = document.getElementById('daily-note-23');
const storageKey = 'note-/bujo/2026/01/23';
const savedNote = localStorage.getItem(storageKey);
if (savedNote) textarea.value = savedNote;
textarea.addEventListener('input', () => localStorage.setItem(storageKey, textarea.value));
});
`}
</script>

51
src/modele/24.mdx Normal file
View File

@@ -0,0 +1,51 @@
---
title: "Daily Log - 24 Janvier 2026"
publishDate: 2026-01-24
tags: ["Daily", "Weekend", "Organisation"]
---
import Key from '~/components/bujo/Key.astro';
<div class="mb-8 p-4 bg-blue-50 border-l-4 border-blue-400">
<h2 class="text-xl font-bold text-slate-800 mb-2"><Key symbol="⚓" /> Ancrage & Bien-être</h2>
<ul class="space-y-2">
<li><Key symbol="•" /> Routine du matin (douche, dents...)</li>
<li><Key symbol="•" /> Activité physique douce (étirements, marche...)</li>
<li><Key symbol="" /> Qualité du sommeil (1-5) : __</li>
<li><Key symbol="" /> Humeur du jour (1-5) : __</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="*" /> Objectifs du Samedi</h2>
<p class="text-sm text-slate-500 mb-3">Une ou deux choses pour profiter de la journée et se sentir bien.</p>
<ul class="space-y-2">
<li><Key symbol="•" /> [Objectif principal]</li>
<li><Key symbol="•" /> [Autre petite tâche]</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="•" /> Foyer & Organisation</h2>
<ul class="space-y-2">
<li><Key symbol="•" /> Session de rangement (15 min)</li>
<li><Key symbol="•" /> Tâche ménagère au choix (lessive, vaisselle...)</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="♡" /> Loisirs & Note du jour</h2>
<p class="text-slate-600 mt-2">Un moment pour soi, une pensée, une petite victoire :</p>
<textarea id="daily-note-24" class="w-full mt-2 p-2 border rounded bg-slate-50" rows="2" placeholder="..."></textarea>
</div>
<script is:inline>
{`
document.addEventListener('DOMContentLoaded', () => {
const textarea = document.getElementById('daily-note-24');
const storageKey = 'note-/bujo/2026/01/24';
const savedNote = localStorage.getItem(storageKey);
if (savedNote) textarea.value = savedNote;
textarea.addEventListener('input', () => localStorage.setItem(storageKey, textarea.value));
});
`}
</script>

59
src/modele/25.mdx Normal file
View File

@@ -0,0 +1,59 @@
---
title: "Daily Log - 25 Janvier 2026"
publishDate: 2026-01-25
tags: ["Daily", "Weekend", "Organisation"]
---
import Key from '~/components/bujo/Key.astro';
<div class="mb-8 p-4 bg-blue-50 border-l-4 border-blue-400">
<h2 class="text-xl font-bold text-slate-800 mb-2"><Key symbol="⚓" /> Ancrage & Bien-être</h2>
<ul class="space-y-2">
<li><Key symbol="•" /> Routine du matin (douche, dents...)</li>
<li><Key symbol="•" /> Activité physique douce (étirements, marche...)</li>
<li><Key symbol="" /> Qualité du sommeil (1-5) : __</li>
<li><Key symbol="" /> Humeur du jour (1-5) : __</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="*" /> Objectifs du Dimanche</h2>
<p class="text-sm text-slate-500 mb-3">Une ou deux choses pour profiter de la journée et se sentir bien.</p>
<ul class="space-y-2">
<li><Key symbol="•" /> [Objectif principal]</li>
<li><Key symbol="•" /> [Autre petite tâche]</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="$" /> Organisation & Budget</h2>
<ul class="space-y-2">
<li><Key symbol="•" /> Planifier les repas de la semaine à venir</li>
<li><Key symbol="👁️" /> Chercher une activité gratuite ou un bon plan</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="•" /> Foyer & Préparation de la semaine</h2>
<ul class="space-y-2">
<li><Key symbol="•" /> Session de rangement (15 min)</li>
<li><Key symbol="•" /> Préparer les vêtements pour lundi</li>
</ul>
</div>
<div class="mb-6">
<h2 class="text-xl font-bold text-slate-700"><Key symbol="♡" /> Loisirs & Note du jour</h2>
<p class="text-slate-600 mt-2">Un moment pour soi, une pensée, une petite victoire :</p>
<textarea id="daily-note-25" class="w-full mt-2 p-2 border rounded bg-slate-50" rows="2" placeholder="..."></textarea>
</div>
<script is:inline>
{`
document.addEventListener('DOMContentLoaded', () => {
const textarea = document.getElementById('daily-note-25');
const storageKey = 'note-/bujo/2026/01/25';
const savedNote = localStorage.getItem(storageKey);
if (savedNote) textarea.value = savedNote;
textarea.addEventListener('input', () => localStorage.setItem(storageKey, textarea.value));
});
`}
</script>

View File

@@ -41,6 +41,16 @@ import ParchmentCard from '../components/ui/ParchmentCard.astro';
<li><strong>CV en ligne :</strong> <a href="https://nohay.github.io/" target="_blank" rel="noopener noreferrer">Découvrir son parcours</a></li> <li><strong>CV en ligne :</strong> <a href="https://nohay.github.io/" target="_blank" rel="noopener noreferrer">Découvrir son parcours</a></li>
</ul> </ul>
</ParchmentCard> </ParchmentCard>
<ParchmentCard>
<h2>📖 Le Journal de Bord de l'Artisan</h2>
<p>
Au-delà des chroniques et des lignes de code, il y a le quotidien. Une quête d'équilibre entre la vie, la passion et la discipline. Ce journal de bord est une tentative de cartographier ce voyage intérieur.
</p>
<div class="text-center mt-4">
<a href="/bujo" class="bg-stone-700 text-white font-bold py-2 px-4 rounded hover:bg-stone-800 transition-colors duration-300">Accéder au Journal de Bord</a>
</div>
</ParchmentCard>
</GameLayout> </GameLayout>
</Layout> </Layout>

View File

@@ -0,0 +1,133 @@
---
import { getCollection, getEntry } from 'astro:content';
import LifeLayout from '../../layouts/LifeLayout.astro';
// Import des composants de page pour les garder modulaires
import BujoIndex from '../../components/bujo/BujoIndex.astro';
import BujoKeys from '../../components/bujo/BujoKeys.astro';
import MonthlyLog from '../../components/bujo/MonthlyLog.astro';
import BujoFutureLog from '../../components/bujo/BujoFutureLog.astro';
import CollectionTracker from '../../components/bujo/CollectionTracker.astro';
import CollectionObjectifs from '../../components/bujo/CollectionObjectifs.astro';
import CollectionBooks from '../../components/bujo/CollectionBooks.astro';
import CollectionPlaceholder from '../../components/bujo/CollectionPlaceholder.astro';
import CollectionFilms from '../../components/bujo/CollectionFilms.astro';
export async function getStaticPaths() {
const bujoEntries = await getCollection('bujo');
const paths = bujoEntries.map(entry => ({
params: { slug: entry.slug }
}));
// Ajouter les routes statiques/virtuelles
paths.push({ params: { slug: undefined } }); // Index
paths.push({ params: { slug: 'keys' } });
paths.push({ params: { slug: 'future-log' } });
paths.push({ params: { slug: 'collections/livres-a-lire' } });
paths.push({ params: { slug: 'collections/trackers-mensuels' } });
paths.push({ params: { slug: 'collections/objectifs-du-mois' } });
paths.push({ params: { slug: 'collections/suivi-depenses' } });
paths.push({ params: { slug: 'collections/gratitude' } });
paths.push({ params: { slug: 'collections/brain-dump' } });
paths.push({ params: { slug: 'collections/bucket-list' } });
paths.push({ params: { slug: 'collections/films-a-voir' } });
paths.push({ params: { slug: 'collections/idees-projets' } });
paths.push({ params: { slug: 'collections/idees-de-projets' } });
// Ajouter les routes pour les mois
const uniqueMonths = new Set<string>();
bujoEntries.forEach(log => {
const [year, month] = log.slug.split('/');
if (year && month && !isNaN(parseInt(year)) && !isNaN(parseInt(month))) {
uniqueMonths.add(`${year}/${month}`);
}
});
uniqueMonths.forEach(monthPath => {
paths.push({ params: { slug: monthPath } });
});
return paths;
}
const { slug } = Astro.params;
// 1. Gérer la page d'index (/bujo)
if (slug === undefined) {
const allLogs = await getCollection('bujo');
const uniqueMonths = new Set<string>();
allLogs.forEach(log => {
const [year, month] = log.slug.split('/');
if (year && month && !isNaN(parseInt(year)) && !isNaN(parseInt(month))) {
uniqueMonths.add(`${year}/${month}`);
}
});
Astro.props.page = 'index';
Astro.props.months = Array.from(uniqueMonths);
}
// 2. Gérer les pages statiques (clés, etc.)
else if (slug === 'keys') {
Astro.props.page = 'keys';
}
else if (slug === 'future-log') {
Astro.props.page = 'bujo-future-log';
}
// 3. Gérer les collections
else if (slug.startsWith('collections/')) {
if (slug === 'collections/trackers-mensuels') {
Astro.props.page = 'collection-tracker';
} else if (slug === 'collections/livres-a-lire') {
Astro.props.page = 'collection-books';
} else if (slug === 'collections/objectifs-du-mois') {
Astro.props.page = 'collection-objectifs';
} else if (slug === 'collections/films-a-voir') {
Astro.props.page = 'collection-films';
}
else {
Astro.props.page = 'collection-placeholder';
Astro.props.collectionTitle = slug.split('/')[1].replace(/-/g, ' ');
}
}
// 4. Gérer les logs mensuels (ex: /bujo/2026/01)
else if (slug.match(/^\d{4}\/\d{2}$/)) {
const [year, month] = slug.split('/');
const monthlyLogs = await getCollection('bujo', ({ slug: logSlug }) => logSlug.startsWith(slug));
Astro.props.page = 'monthly-log';
Astro.props.logs = monthlyLogs;
Astro.props.year = year;
Astro.props.month = month;
}
// 5. Gérer les entrées de contenu (Daily Logs)
else {
const entry = await getEntry('bujo', slug);
if (entry) {
const { Content } = await entry.render();
Astro.props.page = 'entry';
Astro.props.entry = entry;
Astro.props.Content = Content;
}
}
const { page, entry, Content, months, logs, year, month, collectionTitle } = Astro.props;
const title = page === 'index' ? 'Journal de Bord' : (entry ? entry.data.title : collectionTitle || 'Journal');
---
<LifeLayout title={title}>
{page === 'index' && <BujoIndex months={months} />}
{page === 'keys' && <BujoKeys />}
{page === 'bujo-future-log' && <BujoFutureLog />}
{page === 'collection-tracker' && <CollectionTracker />}
{page === 'collection-objectifs' && <CollectionObjectifs />}
{page === 'collection-books' && <CollectionBooks />}
{page === 'collection-films' && <CollectionFilms />}
{page === 'collection-placeholder' && <CollectionPlaceholder collectionTitle={collectionTitle} />}
{page === 'monthly-log' && <MonthlyLog logs={logs} year={year} month={month} />}
{page === 'entry' && Content && (
<article class="prose prose-slate lg:prose-xl max-w-none">
<h1 class="text-3xl font-bold mb-2">{entry.data.title}</h1>
<Content />
</article>
)}
</LifeLayout>

1
src/styles/global.css Normal file
View File

@@ -0,0 +1 @@
@import "tailwindcss";

View File

@@ -1,5 +1,10 @@
{ {
"extends": "astro/tsconfigs/strict", "extends": "astro/tsconfigs/base",
"include": [".astro/types.d.ts", "**/*"], "compilerOptions": {
"exclude": ["dist"] "baseUrl": ".",
"paths": {
"~/*": ["src/*"],
"@/*": ["src/*"]
}
}
} }