Configuration
Configurer un projet de tutoriel
Introduction
Il s’agit d’un guide plus approfondi expliquant comment configurer un projet Next.js très simple avec gt-next.
Nous vous accompagnerons de bout en bout, de la configuration du projet jusqu’à sa traduction.
Au fil de ce tutoriel, nous progresserons de concepts simples vers des notions plus avancées.
Ce tutoriel suppose que vous avez une compréhension générale de TypeScript, Next.js et React.
Voici la liste des éléments que nous aborderons dans ce tutoriel :
- Configurer un nouveau projet Next.js
- Utiliser le composant
<T>pour traduire une application - Utiliser des composants de variables comme
<Var>,<Currency>,<DateTime>et<Num>pour traduire du contenu dynamique - Utiliser des composants conditionnels comme
<Plural>et<Branch>pour traduire du contenu conditionnel - Utiliser le routage i18n dans votre application
Notre application sera une application simple qui nous permettra de vérifier le taux de conversion entre des devises.
Nous utiliserons uniquement des styles en ligne et la bibliothèque gt-next afin de rester aussi minimalistes que possible.
Cet exemple est basé sur le tutoriel Currency Converter de GeeksforGeeks.
Configurez votre application Next.js
Commencez par créer une nouvelle application Next.js. Pour cela, exécutez la commande suivante :
npx create-next-app@latestCela ouvre l’assistant de configuration, où vous pouvez choisir le nom de votre application et le modèle à utiliser.
Pour ce tutoriel, utilisez le nom currencies et sélectionnez « Yes » lorsque vous êtes invité à indiquer si vous souhaitez utiliser TypeScript.
Accédez au répertoire du projet et lançons l’application !
cd currencies
npm install
npm run devCela démarrera l’application sur http://localhost:3000.
Ajoutons du contenu !
Maintenant que notre application est configurée, remplaçons le contenu de notre app pour afficher un simple convertisseur de devises.
Copiez puis collez le code suivant dans les files src/app/page.tsx et src/app/layout.tsx.
Ne vous préoccupez pas trop de son fonctionnement pour l’instant. Ce code se contente de simuler une requête vers une API de taux de change et d’afficher le taux entre deux devises.
"use client";
import { useEffect, useState, useCallback } from "react";
// A map between two currencies and their exchange rate (from -> to)
type ExchTable = Record<string, Record<string, number>>;
const EXCH_RATES: ExchTable = {
usd: { usd: 1, inr: 73.5, eur: 0.85, jpy: 105.45, gbp: 0.72 },
inr: { usd: 0.014, inr: 1, eur: 0.012, jpy: 1.46, gbp: 0.01 },
eur: { usd: 1.18, inr: 85.5, eur: 1, jpy: 123.5, gbp: 0.85 },
jpy: { usd: 0.0095, inr: 0.68, eur: 0.0081, jpy: 1, gbp: 0.0068 },
gbp: { usd: 1.39, inr: 99.5, eur: 1.17, jpy: 146.5, gbp: 1 },
};
// some styles for button
const buttonStyle = {
backgroundColor: "#007bff",
color: "white",
border: "none",
padding: "10px 20px",
cursor: "pointer",
borderRadius: "5px",
fontSize: "16px",
margin: "20px",
};
/**
* Cette fonction simule une requête API pour obtenir le taux de change actuel.
* Attend 1 seconde avant de renvoyer le taux de change.
* @returns le taux de change entre deux devises
*/
async function fetchExchangeRate(from: string, to: string): Promise<number> {
await new Promise((resolve) => setTimeout(resolve, 1000));
return EXCH_RATES[from][to];
}
function Page() {
// exch rates
const [info, setInfo] = useState<ExchTable>({});
const options = ["usd", "inr", "eur", "jpy", "gbp"];
// currencies
const [from, setFrom] = useState("usd");
const [to, setTo] = useState("inr");
// values
const [input, setInput] = useState(0);
const [output, setOutput] = useState(0);
// Function to convert the currency
const convert = useCallback(() => {
if (info?.[from]?.[to]) {
const rate = info[from][to];
setOutput(input * rate);
} else {
setOutput(0);
}
}, [info, input, to, from]);
// Calling the api whenever from or to currency changes
useEffect(() => {
// If the exchange rate is already present, then convert
if (info?.[from]?.[to]) {
convert();
return;
}
// Fetch the exchange rate
(async () => {
const response = await fetchExchangeRate(from, to);
// Enter new response without overwriting old info
setInfo((prevInfo) => ({
...prevInfo,
[from]: {
...(prevInfo?.[from] || undefined),
[to]: response,
},
}));
})();
}, [from, to, convert, info]);
// Call convert whenever a user switches the currency
useEffect(() => {
convert();
}, [info, convert]);
// Function to switch between two currency
function flip() {
const temp = from;
setFrom(to);
setTo(temp);
}
return (
<div style={{ margin: "0 auto", width: "50%", textAlign: "center" }}>
<div style={{ margin: "20px 0", paddingBottom: "20px" }}>
<h1 style={{ fontSize: "2.5em", fontWeight: "bold" }}>
Convertisseur de devises
</h1>
</div>
<div style={{ flex: 2, textAlign: "center", margin: "20px 0" }}>
<h3>Montant</h3>
<input
type="text"
placeholder="Saisissez le montant"
style={{ textAlign: "center" }}
onChange={(e) => {
setInput(Number(e.target.value));
}}
/>
</div>
<div
style={{ display: "flex", justifyContent: "center", margin: "20px 0" }}
>
<div style={{ flex: 1, textAlign: "center" }}>
<label htmlFor="from">
<h3>De</h3>
</label>
<select
name="from"
id="from"
value={from}
onChange={(e) => setFrom(e.target.value)}
>
{options.map((option) => (
<option key={option} value={option}>
{option.toUpperCase()}
</option>
))}
</select>
</div>
<div style={{ flex: 1, textAlign: "center" }}>
<button
onClick={() => {
flip();
}}
style={buttonStyle}
>
Inverser
</button>
</div>
<div style={{ flex: 1, textAlign: "center" }}>
<label htmlFor="to">
<h3>Vers</h3>
</label>
<select
name="to"
id="to"
value={to}
onChange={(e) => setTo(e.target.value)}
>
{options.map((option) => (
<option key={option} value={option}>
{option.toUpperCase()}
</option>
))}
</select>
</div>
</div>
<div style={{ margin: "0 auto", width: "50%", textAlign: "center" }}>
<button
onClick={() => {
convert();
}}
style={buttonStyle}
>
Convertir
</button>
<h2>Montant converti :</h2>
<p>{input + " " + from + " = " + output.toFixed(2) + " " + to}</p>
</div>
</div>
);
}
export default Page;import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});
export const metadata: Metadata = {
title: "Convertisseur de Devises",
description: "Un convertisseur de devises simple",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
{children}
</body>
</html>
);
}Conclusion
Comment trouvez-vous ce guide ?