瀏覽代碼

feat(about): add localized About page with English and French content to enhance user experience
style(locales): update donation text to include a heart emoji for better engagement
refactor(workout-session): comment out unused user authentication logic in workout session service for future implementation
style(globals): add dark mode styling for code elements to improve readability

Mathias 1 月之前
父節點
當前提交
c2effa6972

+ 18 - 0
app/[locale]/about/page.tsx

@@ -0,0 +1,18 @@
+import { getLocalizedMdx } from "@/shared/lib/mdx/load-mdx";
+
+type PageProps = {
+  params: Promise<{ locale: string }>;
+};
+
+export default async function AboutPage({ params }: PageProps) {
+  const { locale } = await params;
+  const content = await getLocalizedMdx("about", locale);
+
+  return (
+    <div className="bg-muted/50 py-12 min-h-screen">
+      <div className="container mx-auto max-w-3xl px-4">
+        <div className="prose prose-neutral max-w-none dark:prose-invert">{content}</div>
+      </div>
+    </div>
+  );
+}

+ 44 - 0
content/about/en.mdx

@@ -0,0 +1,44 @@
+import Link from "next/link";
+
+# About Workout.cool
+
+## Why Workout.cool?
+
+Workout.cool was born out of the desire to offer a reliable, modern, and actively maintained workout platform, after the original project **workout.lol** was abandoned.
+
+## The Story
+
+Workout.cool is the result of a community-driven adventure.
+
+I was the **first open source contributor** to the `workout.lol` project.
+
+This means I saw the project *come to life*, *grow*, then get **sold** and ultimately **abandoned** by its new owner.
+
+Like many users, I felt a **deep frustration** and a *sense of abandonment* watching a tool I had contributed so much to disappear, with feature requests left unanswered and growing old.
+
+---
+
+*For months*, I tried to contact the new owner—**never receiving a single reply** despite many attempts (*about 15*).
+
+Faced with this **silence** and the **distress of the community**, I decided to **take matters into my own hands**:
+
+> Rather than let all this work vanish, **I relaunched an even more ambitious, modern, and open project for everyone.**
+
+This project is not driven by profit, but by **passion** and a desire to serve the open source fitness community.
+
+**Someone had to save the community—_I decided to be that someone!_**
+
+## Open Source & Community
+
+Workout.cool is open source, ensuring transparency, modularity, and scalability.  
+Everyone is welcome to contribute—code, documentation, or ideas!
+
+- [See the project on GitHub](https://github.com/Snouzy/workout-cool)
+- [Buy a coffee to support](https://ko-fi.com/workoutcool)
+
+## Join the Mission!
+
+Want to contribute, suggest a feature, or simply support the project?  
+Contact us or open an issue on GitHub!
+
+**[hello@workout.cool](mailto:hello@workout.cool)**

+ 44 - 0
content/about/fr.mdx

@@ -0,0 +1,44 @@
+import Link from "next/link";
+
+# À propos de Workout.cool
+
+## Pourquoi Workout.cool ?
+
+Workout.cool est né de la volonté de proposer une plateforme d'entraînement fiable, moderne et maintenue, après l'abandon du projet **workout.lol**.
+
+## L'histoire
+
+Workout.cool est le fruit d'une aventure communautaire.
+
+J'ai été le **premier contributeur open source** du projet `workout.lol`.
+
+De ce fait, j'ai vu ce projet *naître*, *grandir*, puis être **vendu** et finalement **abandonné** par son nouveau propriétaire.
+
+Comme beaucoup d'utilisateurs, j'ai ressenti une **grande frustration** et un *sentiment d'abandon* en voyant disparaître un outil auquel j'avais tant contribué, et en voyant les demandes d'évolution se perdre et prendre de l'âge.
+
+---
+
+*Pendant des mois*, j'ai tenté de contacter le nouveau propriétaire, **sans jamais obtenir de réponse** malgré de nombreux essais (*environ 15*).
+
+Face à ce **silence** et à la **détresse de la communauté**, j'ai décidé de **prendre les choses en main** :
+
+> Plutôt que de laisser ce travail disparaître, **j'ai relancé un projet encore plus ambitieux, moderne et ouvert à tous.**
+
+Ce projet n'est pas motivé par le profit, mais par la **passion** et l'envie de servir la communauté fitness open source.
+
+**Quelqu'un devait sauver la communauté, _j'ai décidé d'être ce quelqu'un_ !**
+
+## Open source & communauté
+
+Workout.cool est open source, garantir transparence, modularité et évolutivité.  
+Toute contribution est la bienvenue, que ce soit pour le code, la documentation ou les idées !
+
+- [Voir le projet sur GitHub](https://github.com/Snouzy/workout-cool)
+- [Payer un café en guise de soutien](https://ko-fi.com/workoutcool)
+
+## Rejoignez la mission !
+
+Vous souhaitez contribuer, proposer une fonctionnalité ou simplement soutenir le projet ?  
+Contactez-nous ou ouvrez une issue sur GitHub !
+
+**[hello@workout.cool](mailto:hello@workout.cool)**

+ 1 - 1
locales/fr.ts

@@ -323,7 +323,7 @@ export default {
     consent_banner: "Nous utilisons des cookies pour améliorer votre expérience. En cliquant sur Accepter, vous acceptez nos cookies.",
     about: "À propos",
     profile: "Profil",
-    donate: "Faire un don",
+    donate: "Faire un don ❤️",
     my_account: "Mon compte",
     dashboard: "Tableau de bord",
     home: "Accueil",

+ 21 - 28
src/shared/lib/workout-session/use-workout-session.service.ts

@@ -10,11 +10,6 @@ import type { WorkoutSession } from "./types/workout-session";
 // This is an abstraction layer to handle the local storage and/or the API calls.
 // He's the orchestrator.
 
-// TODO: replace with auth context
-function isUserLoggedIn(): boolean {
-  return !!localStorage.getItem("userToken");
-}
-
 export const useWorkoutSessionService = () => {
   const { data: session } = useSession();
   const userId = session?.user?.id;
@@ -79,35 +74,33 @@ export const useWorkoutSessionService = () => {
   };
 
   const update = async (id: string, data: Partial<WorkoutSession>) => {
-    if (userId) {
-      // TODO: Créer une action updateWorkoutSessionAction
-      const result = await updateWorkoutSessionAction({ id, data });
-      if (result.serverError) throw new Error(result.serverError);
-    }
-    return workoutSessionLocal.update(id, data);
+    // if (userId) {
+    //   // TODO: Créer une action updateWorkoutSessionAction
+    //   const result = await updateWorkoutSessionAction({ id, data });
+    //   if (result.serverError) throw new Error(result.serverError);
+    // }
+    // return workoutSessionLocal.update(id, data);
   };
 
   const complete = async (id: string) => {
-    const data = {
-      status: "completed" as const,
-      endedAt: new Date().toISOString(),
-    };
-
-    if (isUserLoggedIn()) {
-      const result = await completeWorkoutSessionAction({ id });
-      if (result.serverError) throw new Error(result.serverError);
-    }
-
-    return workoutSessionLocal.update(id, data);
+    // const data = {
+    //   status: "completed" as const,
+    //   endedAt: new Date().toISOString(),
+    // };
+    // if (isUserLoggedIn()) {
+    //   const result = await completeWorkoutSessionAction({ id });
+    //   if (result.serverError) throw new Error(result.serverError);
+    // }
+    // return workoutSessionLocal.update(id, data);
   };
 
   const remove = async (id: string) => {
-    if (isUserLoggedIn()) {
-      // TODO: Créer une action deleteWorkoutSessionAction
-      const result = await deleteWorkoutSessionAction({ id });
-      if (result.serverError) throw new Error(result.serverError);
-    }
-    workoutSessionLocal.remove(id);
+    // if (isUserLoggedIn()) {
+    //   // TODO: Créer une action deleteWorkoutSessionAction
+    //   const result = await deleteWorkoutSessionAction({ id });
+    //   if (result.serverError) throw new Error(result.serverError);
+    // }
+    // workoutSessionLocal.remove(id);
   };
 
   return { getAll, add, update, complete, remove };

+ 4 - 0
src/shared/styles/globals.css

@@ -82,6 +82,10 @@
   @apply animate-pulse bg-gray-200 dark:bg-gray-700;
 }
 
+.dark code {
+  @apply text-black;
+}
+
 @layer components {
   .sidebar .nav-link {
     @apply mx-[2px] mt-1 flex items-center gap-2.5 border border-transparent px-5 py-2.5 text-sm font-medium leading-tight text-gray transition hover:text-black dark:text-gray-500 dark:hover:text-white;