├── TP1
├── correction
│ ├── .eslintrc.json
│ ├── .gitignore
│ ├── README.md
│ ├── next.config.mjs
│ ├── package-lock.json
│ ├── package.json
│ ├── postcss.config.mjs
│ ├── public
│ │ ├── next.svg
│ │ └── vercel.svg
│ ├── src
│ │ └── app
│ │ │ ├── blog
│ │ │ ├── [id]
│ │ │ │ └── page.tsx
│ │ │ └── page.tsx
│ │ │ ├── datas.ts
│ │ │ ├── favicon.ico
│ │ │ ├── globals.css
│ │ │ ├── layout.tsx
│ │ │ ├── page.tsx
│ │ │ └── types.ts
│ ├── tailwind.config.ts
│ └── tsconfig.json
└── enonce
│ ├── .eslintrc.json
│ ├── .gitignore
│ ├── README.md
│ ├── next.config.mjs
│ ├── package-lock.json
│ ├── package.json
│ ├── postcss.config.mjs
│ ├── public
│ ├── next.svg
│ └── vercel.svg
│ ├── src
│ └── app
│ │ ├── data.ts
│ │ ├── favicon.ico
│ │ ├── globals.css
│ │ ├── layout.tsx
│ │ ├── page.tsx
│ │ └── types.ts
│ ├── tailwind.config.ts
│ └── tsconfig.json
└── tp2
├── .eslintrc.json
├── .gitignore
├── README.md
├── components.json
├── next.config.mjs
├── package-lock.json
├── package.json
├── postcss.config.mjs
├── public
├── minerals.png
└── vitamins.png
├── src
├── app
│ ├── api
│ │ └── foods
│ │ │ ├── [name]
│ │ │ └── route.ts
│ │ │ └── all
│ │ │ └── route.ts
│ ├── favicon.ico
│ ├── food
│ │ └── [name]
│ │ │ ├── layout.tsx
│ │ │ └── page.tsx
│ ├── globals.css
│ ├── layout.tsx
│ └── page.tsx
├── components
│ └── ui
│ │ ├── button.tsx
│ │ ├── command.tsx
│ │ ├── dialog.tsx
│ │ └── popover.tsx
├── data.ts
├── lib
│ └── utils.ts
└── types
│ └── index.ts
├── tailwind.config.ts
└── tsconfig.json
/TP1/correction/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/TP1/correction/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
--------------------------------------------------------------------------------
/TP1/correction/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | # or
12 | pnpm dev
13 | # or
14 | bun dev
15 | ```
16 |
17 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
18 |
19 | You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
20 |
21 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
22 |
23 | ## Learn More
24 |
25 | To learn more about Next.js, take a look at the following resources:
26 |
27 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
29 |
30 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
31 |
32 | ## Deploy on Vercel
33 |
34 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
35 |
36 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
37 |
--------------------------------------------------------------------------------
/TP1/correction/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {};
3 |
4 | export default nextConfig;
5 |
--------------------------------------------------------------------------------
/TP1/correction/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "blog",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "next": "14.2.3",
13 | "react": "^18",
14 | "react-dom": "^18"
15 | },
16 | "devDependencies": {
17 | "@types/node": "^20",
18 | "@types/react": "^18",
19 | "@types/react-dom": "^18",
20 | "eslint": "^8",
21 | "eslint-config-next": "14.2.3",
22 | "postcss": "^8",
23 | "tailwindcss": "^3.4.1",
24 | "typescript": "^5"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/TP1/correction/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/TP1/correction/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/TP1/correction/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/TP1/correction/src/app/blog/[id]/page.tsx:
--------------------------------------------------------------------------------
1 | import { articles } from "@/app/datas";
2 | import { Metadata } from "next";
3 |
4 | export function generateMetadata({ params }: { params: { id: string }}): Metadata {
5 | const article = articles.find((element) => element.id === parseInt(params.id));
6 | return {
7 | title: article?.title,
8 | description: article?.description
9 | }
10 | }
11 |
12 | export default function ArticlePage({ params }: { params: { id: string }}) {
13 | const article = articles.find((element) => element.id === parseInt(params.id));
14 | return (
15 | <>
16 | {article &&
17 |
20 |
{article.title} le {article.date} par {article.author}
21 |
{article.description}
22 |
23 | }
24 | >
25 | )
26 | }
--------------------------------------------------------------------------------
/TP1/correction/src/app/blog/page.tsx:
--------------------------------------------------------------------------------
1 | import Link from "next/link"
2 | import { articles } from "../datas"
3 | import { Article } from "../types"
4 | import type { Metadata } from "next";
5 |
6 | export const metadata: Metadata = {
7 | title: "Ben BK - Le Blog",
8 | description: "Randonneur à ses heures perdues.",
9 | };
10 |
11 | export default function BlogPage() {
12 | return (
13 | <>
14 | {articles.map((article: Article) => {
15 | const link = `blog/${article.id}`
16 | return (
17 |
20 |
{article.title} le {article.date} par {article.author}
21 | Voir l'article
22 |
23 | )
24 | })}
25 | >
26 | )
27 | }
28 |
--------------------------------------------------------------------------------
/TP1/correction/src/app/datas.ts:
--------------------------------------------------------------------------------
1 | export const articles = [
2 | {
3 | "id": 1,
4 | "title": "Les merveilles de la randonnée en montagne",
5 | "description": "Découvrez les paysages époustouflants des montagnes et les bienfaits de la randonnée en altitude.",
6 | "date": "2024-05-01",
7 | "author": "Jean Dupont"
8 | },
9 | {
10 | "id": 2,
11 | "title": "Randonnée en forêt : conseils et astuces",
12 | "description": "Tout ce qu'il faut savoir pour une randonnée réussie en forêt, des équipements aux itinéraires.",
13 | "date": "2024-05-03",
14 | "author": "Marie Martin"
15 | },
16 | {
17 | "id": 3,
18 | "title": "Les plus belles randonnées côtières",
19 | "description": "Partez à la découverte des sentiers côtiers et admirez les vues imprenables sur l'océan.",
20 | "date": "2024-05-05",
21 | "author": "Luc Leroy"
22 | },
23 | {
24 | "id": 4,
25 | "title": "Randonnée et bien-être : les bénéfices pour la santé",
26 | "description": "Explorons les nombreux bienfaits de la randonnée sur la santé physique et mentale.",
27 | "date": "2024-05-07",
28 | "author": "Sophie Petit"
29 | },
30 | {
31 | "id": 5,
32 | "title": "Les randonnées en famille : des moments inoubliables",
33 | "description": "Des idées de randonnées adaptées pour toute la famille, des plus petits aux plus grands.",
34 | "date": "2024-05-09",
35 | "author": "Pierre Blanc"
36 | },
37 | {
38 | "id": 6,
39 | "title": "Préparer sa randonnée : les indispensables à emporter",
40 | "description": "Liste des équipements et provisions à ne pas oublier pour partir en randonnée en toute sérénité.",
41 | "date": "2024-05-11",
42 | "author": "Elise Dupuis"
43 | },
44 | {
45 | "id": 7,
46 | "title": "Randonnées insolites : explorez des lieux méconnus",
47 | "description": "Partez à l'aventure et découvrez des sentiers de randonnée hors des sentiers battus.",
48 | "date": "2024-05-13",
49 | "author": "Nicolas Moreau"
50 | },
51 | {
52 | "id": 8,
53 | "title": "Randonnée en hiver : les précautions à prendre",
54 | "description": "Conseils pour randonner en toute sécurité pendant la saison hivernale.",
55 | "date": "2024-05-15",
56 | "author": "Claire Richard"
57 | },
58 | {
59 | "id": 9,
60 | "title": "Les applications utiles pour les randonneurs",
61 | "description": "Découvrez les meilleures applications pour planifier vos randonnées et vous orienter en chemin.",
62 | "date": "2024-05-17",
63 | "author": "Julien Fabre"
64 | },
65 | {
66 | "id": 10,
67 | "title": "Randonnée et photographie : capturer la beauté de la nature",
68 | "description": "Astuces pour réussir vos photos de randonnée et immortaliser des paysages spectaculaires.",
69 | "date": "2024-05-19",
70 | "author": "Laura Moulin"
71 | }
72 | ]
--------------------------------------------------------------------------------
/TP1/correction/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BenBktech/Formation-NextJS/89897f3e60e9c6303da0c38184790324d37dc506/TP1/correction/src/app/favicon.ico
--------------------------------------------------------------------------------
/TP1/correction/src/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | :root {
6 | --foreground-rgb: 0, 0, 0;
7 | --background-start-rgb: 214, 219, 220;
8 | --background-end-rgb: 255, 255, 255;
9 | }
10 |
11 | @media (prefers-color-scheme: dark) {
12 | :root {
13 | --foreground-rgb: 255, 255, 255;
14 | --background-start-rgb: 0, 0, 0;
15 | --background-end-rgb: 0, 0, 0;
16 | }
17 | }
18 |
19 | @layer utilities {
20 | .text-balance {
21 | text-wrap: balance;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/TP1/correction/src/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from "next";
2 | import { Inter } from "next/font/google";
3 | import "./globals.css";
4 |
5 | const inter = Inter({ subsets: ["latin"] });
6 |
7 | export const metadata: Metadata = {
8 | title: "Ben BK",
9 | description: "Randonneur à ses heures perdues.",
10 | };
11 |
12 | export default function RootLayout({
13 | children,
14 | }: Readonly<{
15 | children: React.ReactNode;
16 | }>) {
17 | return (
18 |
19 |
20 |
24 |
27 | {children}
28 |
29 |
35 |
36 |
37 | );
38 | }
39 |
--------------------------------------------------------------------------------
/TP1/correction/src/app/page.tsx:
--------------------------------------------------------------------------------
1 | import Link from "next/link";
2 |
3 | export default function Home() {
4 | return (
5 | <>
6 | Bienvenue sur mon site !
7 | Accéder au blog
8 | >
9 | );
10 | }
11 |
--------------------------------------------------------------------------------
/TP1/correction/src/app/types.ts:
--------------------------------------------------------------------------------
1 | export interface Article {
2 | id: number;
3 | title: string;
4 | description: string;
5 | date: string;
6 | author: string;
7 | }
--------------------------------------------------------------------------------
/TP1/correction/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from "tailwindcss";
2 |
3 | const config: Config = {
4 | content: [
5 | "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
6 | "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
7 | "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
8 | ],
9 | theme: {
10 | extend: {
11 | backgroundImage: {
12 | "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
13 | "gradient-conic":
14 | "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
15 | },
16 | },
17 | },
18 | plugins: [],
19 | };
20 | export default config;
21 |
--------------------------------------------------------------------------------
/TP1/correction/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["dom", "dom.iterable", "esnext"],
4 | "allowJs": true,
5 | "skipLibCheck": true,
6 | "strict": true,
7 | "noEmit": true,
8 | "esModuleInterop": true,
9 | "module": "esnext",
10 | "moduleResolution": "bundler",
11 | "resolveJsonModule": true,
12 | "isolatedModules": true,
13 | "jsx": "preserve",
14 | "incremental": true,
15 | "plugins": [
16 | {
17 | "name": "next"
18 | }
19 | ],
20 | "paths": {
21 | "@/*": ["./src/*"]
22 | }
23 | },
24 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
25 | "exclude": ["node_modules"]
26 | }
27 |
--------------------------------------------------------------------------------
/TP1/enonce/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/TP1/enonce/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
--------------------------------------------------------------------------------
/TP1/enonce/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | # or
12 | pnpm dev
13 | # or
14 | bun dev
15 | ```
16 |
17 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
18 |
19 | You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
20 |
21 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
22 |
23 | ## Learn More
24 |
25 | To learn more about Next.js, take a look at the following resources:
26 |
27 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
29 |
30 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
31 |
32 | ## Deploy on Vercel
33 |
34 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
35 |
36 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
37 |
--------------------------------------------------------------------------------
/TP1/enonce/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {};
3 |
4 | export default nextConfig;
5 |
--------------------------------------------------------------------------------
/TP1/enonce/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "enonce",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "next": "14.2.3",
13 | "react": "^18",
14 | "react-dom": "^18"
15 | },
16 | "devDependencies": {
17 | "@types/node": "^20",
18 | "@types/react": "^18",
19 | "@types/react-dom": "^18",
20 | "eslint": "^8",
21 | "eslint-config-next": "14.2.3",
22 | "postcss": "^8",
23 | "tailwindcss": "^3.4.1",
24 | "typescript": "^5"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/TP1/enonce/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/TP1/enonce/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/TP1/enonce/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/TP1/enonce/src/app/data.ts:
--------------------------------------------------------------------------------
1 | export const articles = [
2 | {
3 | "id": 1,
4 | "title": "Les merveilles de la randonnée en montagne",
5 | "description": "Découvrez les paysages époustouflants des montagnes et les bienfaits de la randonnée en altitude.",
6 | "date": "2024-05-01",
7 | "author": "Jean Dupont"
8 | },
9 | {
10 | "id": 2,
11 | "title": "Randonnée en forêt : conseils et astuces",
12 | "description": "Tout ce qu'il faut savoir pour une randonnée réussie en forêt, des équipements aux itinéraires.",
13 | "date": "2024-05-03",
14 | "author": "Marie Martin"
15 | },
16 | {
17 | "id": 3,
18 | "title": "Les plus belles randonnées côtières",
19 | "description": "Partez à la découverte des sentiers côtiers et admirez les vues imprenables sur l'océan.",
20 | "date": "2024-05-05",
21 | "author": "Luc Leroy"
22 | },
23 | {
24 | "id": 4,
25 | "title": "Randonnée et bien-être : les bénéfices pour la santé",
26 | "description": "Explorons les nombreux bienfaits de la randonnée sur la santé physique et mentale.",
27 | "date": "2024-05-07",
28 | "author": "Sophie Petit"
29 | },
30 | {
31 | "id": 5,
32 | "title": "Les randonnées en famille : des moments inoubliables",
33 | "description": "Des idées de randonnées adaptées pour toute la famille, des plus petits aux plus grands.",
34 | "date": "2024-05-09",
35 | "author": "Pierre Blanc"
36 | },
37 | {
38 | "id": 6,
39 | "title": "Préparer sa randonnée : les indispensables à emporter",
40 | "description": "Liste des équipements et provisions à ne pas oublier pour partir en randonnée en toute sérénité.",
41 | "date": "2024-05-11",
42 | "author": "Elise Dupuis"
43 | },
44 | {
45 | "id": 7,
46 | "title": "Randonnées insolites : explorez des lieux méconnus",
47 | "description": "Partez à l'aventure et découvrez des sentiers de randonnée hors des sentiers battus.",
48 | "date": "2024-05-13",
49 | "author": "Nicolas Moreau"
50 | },
51 | {
52 | "id": 8,
53 | "title": "Randonnée en hiver : les précautions à prendre",
54 | "description": "Conseils pour randonner en toute sécurité pendant la saison hivernale.",
55 | "date": "2024-05-15",
56 | "author": "Claire Richard"
57 | },
58 | {
59 | "id": 9,
60 | "title": "Les applications utiles pour les randonneurs",
61 | "description": "Découvrez les meilleures applications pour planifier vos randonnées et vous orienter en chemin.",
62 | "date": "2024-05-17",
63 | "author": "Julien Fabre"
64 | },
65 | {
66 | "id": 10,
67 | "title": "Randonnée et photographie : capturer la beauté de la nature",
68 | "description": "Astuces pour réussir vos photos de randonnée et immortaliser des paysages spectaculaires.",
69 | "date": "2024-05-19",
70 | "author": "Laura Moulin"
71 | }
72 | ]
--------------------------------------------------------------------------------
/TP1/enonce/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BenBktech/Formation-NextJS/89897f3e60e9c6303da0c38184790324d37dc506/TP1/enonce/src/app/favicon.ico
--------------------------------------------------------------------------------
/TP1/enonce/src/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | :root {
6 | --foreground-rgb: 0, 0, 0;
7 | --background-start-rgb: 214, 219, 220;
8 | --background-end-rgb: 255, 255, 255;
9 | }
10 |
11 | @media (prefers-color-scheme: dark) {
12 | :root {
13 | --foreground-rgb: 255, 255, 255;
14 | --background-start-rgb: 0, 0, 0;
15 | --background-end-rgb: 0, 0, 0;
16 | }
17 | }
18 |
19 | body {
20 | color: rgb(var(--foreground-rgb));
21 | background: linear-gradient(
22 | to bottom,
23 | transparent,
24 | rgb(var(--background-end-rgb))
25 | )
26 | rgb(var(--background-start-rgb));
27 | }
28 |
29 | @layer utilities {
30 | .text-balance {
31 | text-wrap: balance;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/TP1/enonce/src/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from "next";
2 | import { Inter } from "next/font/google";
3 | import "./globals.css";
4 |
5 | const inter = Inter({ subsets: ["latin"] });
6 |
7 | export const metadata: Metadata = {
8 | title: "Create Next App",
9 | description: "Generated by create next app",
10 | };
11 |
12 | export default function RootLayout({
13 | children,
14 | }: Readonly<{
15 | children: React.ReactNode;
16 | }>) {
17 | return (
18 |
19 | {children}
20 |
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/TP1/enonce/src/app/page.tsx:
--------------------------------------------------------------------------------
1 | import Image from "next/image";
2 |
3 | export default function Home() {
4 | return (
5 |
6 |
7 |
8 | Get started by editing
9 | src/app/page.tsx
10 |
11 |
29 |
30 |
31 |
32 |
40 |
41 |
42 |
111 |
112 | );
113 | }
114 |
--------------------------------------------------------------------------------
/TP1/enonce/src/app/types.ts:
--------------------------------------------------------------------------------
1 | export interface Article {
2 | id: number;
3 | title: string;
4 | description: string;
5 | date: string;
6 | author: string;
7 | }
--------------------------------------------------------------------------------
/TP1/enonce/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from "tailwindcss";
2 |
3 | const config: Config = {
4 | content: [
5 | "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
6 | "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
7 | "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
8 | ],
9 | theme: {
10 | extend: {
11 | backgroundImage: {
12 | "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
13 | "gradient-conic":
14 | "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
15 | },
16 | },
17 | },
18 | plugins: [],
19 | };
20 | export default config;
21 |
--------------------------------------------------------------------------------
/TP1/enonce/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["dom", "dom.iterable", "esnext"],
4 | "allowJs": true,
5 | "skipLibCheck": true,
6 | "strict": true,
7 | "noEmit": true,
8 | "esModuleInterop": true,
9 | "module": "esnext",
10 | "moduleResolution": "bundler",
11 | "resolveJsonModule": true,
12 | "isolatedModules": true,
13 | "jsx": "preserve",
14 | "incremental": true,
15 | "plugins": [
16 | {
17 | "name": "next"
18 | }
19 | ],
20 | "paths": {
21 | "@/*": ["./src/*"]
22 | }
23 | },
24 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
25 | "exclude": ["node_modules"]
26 | }
27 |
--------------------------------------------------------------------------------
/tp2/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/tp2/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
--------------------------------------------------------------------------------
/tp2/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | # or
12 | pnpm dev
13 | # or
14 | bun dev
15 | ```
16 |
17 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
18 |
19 | You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
20 |
21 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
22 |
23 | ## Learn More
24 |
25 | To learn more about Next.js, take a look at the following resources:
26 |
27 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
29 |
30 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
31 |
32 | ## Deploy on Vercel
33 |
34 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
35 |
36 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
37 |
--------------------------------------------------------------------------------
/tp2/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "default",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "tailwind.config.ts",
8 | "css": "src/app/globals.css",
9 | "baseColor": "slate",
10 | "cssVariables": true,
11 | "prefix": ""
12 | },
13 | "aliases": {
14 | "components": "@/components",
15 | "utils": "@/lib/utils"
16 | }
17 | }
--------------------------------------------------------------------------------
/tp2/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {};
3 |
4 | export default nextConfig;
5 |
--------------------------------------------------------------------------------
/tp2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tp2",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "@radix-ui/react-dialog": "^1.0.5",
13 | "@radix-ui/react-popover": "^1.0.7",
14 | "@radix-ui/react-slot": "^1.0.2",
15 | "class-variance-authority": "^0.7.0",
16 | "clsx": "^2.1.1",
17 | "cmdk": "^1.0.0",
18 | "lucide-react": "^0.395.0",
19 | "next": "14.2.4",
20 | "react": "^18",
21 | "react-dom": "^18",
22 | "recharts": "^2.12.7",
23 | "tailwind-merge": "^2.3.0",
24 | "tailwindcss-animate": "^1.0.7"
25 | },
26 | "devDependencies": {
27 | "@types/node": "^20",
28 | "@types/react": "^18",
29 | "@types/react-dom": "^18",
30 | "eslint": "^8",
31 | "eslint-config-next": "14.2.4",
32 | "postcss": "^8",
33 | "tailwindcss": "^3.4.1",
34 | "typescript": "^5"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/tp2/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/tp2/public/minerals.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BenBktech/Formation-NextJS/89897f3e60e9c6303da0c38184790324d37dc506/tp2/public/minerals.png
--------------------------------------------------------------------------------
/tp2/public/vitamins.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BenBktech/Formation-NextJS/89897f3e60e9c6303da0c38184790324d37dc506/tp2/public/vitamins.png
--------------------------------------------------------------------------------
/tp2/src/app/api/foods/[name]/route.ts:
--------------------------------------------------------------------------------
1 | import { foods } from "@/data";
2 |
3 | export async function GET(
4 | request: Request,
5 | { params }: { params: { name: string }}
6 | ) {
7 | console.log('ok');
8 | console.log(params.name);
9 | const index = foods.findIndex(
10 | (food) => food.name.toLowerCase().replace(/ /g, '-') === params.name
11 | )
12 | console.log(foods[index]);
13 | if(index !== -1) {
14 | return new Response(JSON.stringify(foods[index]), {
15 | headers: {
16 | "Content-Type": "application/json"
17 | },
18 | status: 200
19 | })
20 | }
21 | else {
22 | return new Response("Food not found.", {
23 | headers: {
24 | "Content-Type": "application/json"
25 | },
26 | status: 404
27 | });
28 | }
29 | }
--------------------------------------------------------------------------------
/tp2/src/app/api/foods/all/route.ts:
--------------------------------------------------------------------------------
1 | import { foods } from "@/data";
2 |
3 | export async function GET() {
4 | return Response.json(foods);
5 | }
--------------------------------------------------------------------------------
/tp2/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BenBktech/Formation-NextJS/89897f3e60e9c6303da0c38184790324d37dc506/tp2/src/app/favicon.ico
--------------------------------------------------------------------------------
/tp2/src/app/food/[name]/layout.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'; // Ajoutez cet import
2 | import type { Metadata } from "next";
3 |
4 | export function generateMetadata({ params }: { params: { name: string }}): Metadata {
5 | const title = `Discover ${params.name} - NutriSpark`;
6 | const description = `Learn all about the nutritional values of ${params.name} on NutriTech. Explore now!`;
7 | return {
8 | title,
9 | description,
10 | };
11 | }
12 |
13 | export default function FoodLayout({
14 | children,
15 | }: Readonly<{
16 | children: React.ReactNode;
17 | }>) {
18 | return (
19 |
20 | {children}
21 |
22 | );
23 | }
24 |
--------------------------------------------------------------------------------
/tp2/src/app/food/[name]/page.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 | import Image from "next/image";
3 | import { useState, useEffect } from "react";
4 | import { IFood, IMacronutrientData } from "@/types";
5 | import { PieChart, Pie, Cell, ResponsiveContainer } from 'recharts';
6 | import { useRouter } from "next/navigation";
7 | import { Undo2 } from 'lucide-react';
8 |
9 | const FoodPage = ({ params }: { params: { name: string }}) => {
10 |
11 | const router = useRouter();
12 |
13 | const [food, setFood] = useState(null);
14 | const [isLoading, setIsLoading] = useState(true);
15 | const [macronutriments, setMacronutriments] = useState([]);
16 |
17 | const COLORS = ['#F28907', '#5079F2', '#F2220F'];
18 |
19 | const fetchFood = async() => {
20 | try {
21 | const APIQueryURL = `/api/foods/${params.name}`;
22 | const response = await fetch(APIQueryURL);
23 | const data = await response.json();
24 |
25 | // Macronutriments
26 | const macronutrimentsDatas: IMacronutrientData[] = [
27 | { name: 'carbohydrates', value: data.carbohydrates },
28 | { name: 'protein', value: data.protein },
29 | { name: 'fat', value: data.fat },
30 | ];
31 |
32 | setMacronutriments(macronutrimentsDatas);
33 |
34 | // Food General Informations
35 | setFood(data);
36 | console.log(data);
37 | }
38 | catch(error) {
39 | console.log("Error fetching Food:", error);
40 | }
41 | finally {
42 | setIsLoading(false);
43 | }
44 | }
45 |
46 | useEffect(() => {
47 | const initialize = async() => {
48 | await fetchFood();
49 | }
50 | initialize();
51 | }, [params.name]);
52 |
53 | return (
54 | <>
55 | {(!isLoading && food && macronutriments) ? (
56 |
57 |
router.back()} />
58 |
59 | {food.name}
60 |
61 |
62 |
63 |
64 |
65 |
75 | {macronutriments.map((entry, index) => (
76 | |
77 | ))}
78 |
79 |
80 |
81 |
82 | Carbohydrates
83 | Protein
84 | Fat
85 |
86 |
87 |
88 |
Nutritional Information per 100 grams:
89 |
90 |
91 |
92 |
Carbohydrates: {food.carbohydrates}g
93 |
94 |
95 |
96 |
Protein: {food.protein}g
97 |
98 |
99 |
100 |
Fat: {food.fat}g
101 |
102 |
103 |
104 |
105 |
106 |
107 | Vitamins: {food.vitamins?.join(', ')}
108 |
109 |
110 |
111 |
112 |
113 | Minerals: {food.minerals?.join(', ')}
114 |
115 |
116 |
117 |
118 |
119 |
120 | ) : (
121 |
124 | )}
125 | >
126 | );
127 | }
128 |
129 | export default FoodPage;
130 |
--------------------------------------------------------------------------------
/tp2/src/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | .colorInfo {
6 | @apply w-5 h-5 border mr-2;
7 | }
8 |
9 | .colorInfo.carbohydrates {
10 | @apply bg-[#F28907];
11 | }
12 |
13 | .colorInfo.protein {
14 | @apply bg-[#5079F2];
15 | }
16 |
17 | .colorInfo.fat {
18 | @apply bg-[#F2220F];
19 | }
20 |
21 | .title_colored {
22 | @apply bg-gradient-to-r from-[#75fd38] to-[#e1f3ab] bg-clip-text text-transparent;
23 | }
24 |
25 | @layer base {
26 | :root {
27 | --background: 0 0% 100%;
28 | --foreground: 222.2 84% 4.9%;
29 |
30 | --card: 0 0% 100%;
31 | --card-foreground: 222.2 84% 4.9%;
32 |
33 | --popover: 0 0% 100%;
34 | --popover-foreground: 222.2 84% 4.9%;
35 |
36 | --primary: 222.2 47.4% 11.2%;
37 | --primary-foreground: 210 40% 98%;
38 |
39 | --secondary: 210 40% 96.1%;
40 | --secondary-foreground: 222.2 47.4% 11.2%;
41 |
42 | --muted: 210 40% 96.1%;
43 | --muted-foreground: 215.4 16.3% 46.9%;
44 |
45 | --accent: 210 40% 96.1%;
46 | --accent-foreground: 222.2 47.4% 11.2%;
47 |
48 | --destructive: 0 84.2% 60.2%;
49 | --destructive-foreground: 210 40% 98%;
50 |
51 | --border: 214.3 31.8% 91.4%;
52 | --input: 214.3 31.8% 91.4%;
53 | --ring: 222.2 84% 4.9%;
54 |
55 | --radius: 0.5rem;
56 | }
57 |
58 | .dark {
59 | --background: 222.2 84% 4.9%;
60 | --foreground: 210 40% 98%;
61 |
62 | --card: 222.2 84% 4.9%;
63 | --card-foreground: 210 40% 98%;
64 |
65 | --popover: 222.2 84% 4.9%;
66 | --popover-foreground: 210 40% 98%;
67 |
68 | --primary: 210 40% 98%;
69 | --primary-foreground: 222.2 47.4% 11.2%;
70 |
71 | --secondary: 217.2 32.6% 17.5%;
72 | --secondary-foreground: 210 40% 98%;
73 |
74 | --muted: 217.2 32.6% 17.5%;
75 | --muted-foreground: 215 20.2% 65.1%;
76 |
77 | --accent: 217.2 32.6% 17.5%;
78 | --accent-foreground: 210 40% 98%;
79 |
80 | --destructive: 0 62.8% 30.6%;
81 | --destructive-foreground: 210 40% 98%;
82 |
83 | --border: 217.2 32.6% 17.5%;
84 | --input: 217.2 32.6% 17.5%;
85 | --ring: 212.7 26.8% 83.9%;
86 | }
87 | }
88 |
89 | @layer base {
90 | * {
91 | @apply border-border;
92 | }
93 | body {
94 | @apply bg-background text-foreground;
95 | }
96 | }
--------------------------------------------------------------------------------
/tp2/src/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from "next";
2 | import "./globals.css";
3 |
4 | import { Inter as FontSans } from "next/font/google"
5 |
6 | import { cn } from "@/lib/utils"
7 |
8 | const fontSans = FontSans({
9 | subsets: ["latin"],
10 | variable: "--font-sans",
11 | })
12 |
13 | export const metadata: Metadata = {
14 | title: "Welcome to NutriSpark",
15 | description: "Discover the nutritional values of your favorite foods. Use the search below to get started.",
16 | };
17 |
18 | export default function RootLayout({
19 | children,
20 | }: Readonly<{
21 | children: React.ReactNode;
22 | }>) {
23 | return (
24 |
25 |
26 |
32 | {children}
33 |
34 |
35 | );
36 | }
37 |
--------------------------------------------------------------------------------
/tp2/src/app/page.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 | import { useState, useEffect } from "react";
3 | import { IFood, IFoodReduced } from "@/types";
4 | import { Check, ChevronsUpDown } from "lucide-react";
5 | import { cn } from "@/lib/utils";
6 | import { Button } from "@/components/ui/button";
7 | import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
8 | import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
9 | import { useRouter } from "next/navigation";
10 |
11 | export default function Home() {
12 |
13 | const router = useRouter();
14 | const [foods, setFoods] = useState([]);
15 | const [open, setOpen] = useState(false);
16 | const [value, setValue] = useState("");
17 | const [isLoading, setIsLoading] = useState(true);
18 |
19 | const fetchFoods = async() => {
20 | try {
21 | const response = await fetch('/api/foods/all');
22 | const data = await response.json();
23 | const foodsReduced: IFoodReduced[] = data.map((food: IFood) => ({
24 | value: food.name.toLowerCase().replace(/ /g, '-'),
25 | label: food.name
26 | }));
27 | setFoods(foodsReduced);
28 | }
29 | catch(error) {
30 | console.log(error);
31 | }
32 | }
33 |
34 | useEffect(() => {
35 | const initialize = async() => {
36 | await fetchFoods();
37 | setIsLoading(false);
38 | }
39 | initialize();
40 | }, [])
41 |
42 | useEffect(() => {
43 | if(value.length > 0) {
44 | router.push(`/food/${value}`);
45 | }
46 | }, [value]);
47 |
48 | return (
49 | <>
50 | {!isLoading ? (
51 |
52 |
Welcome to NutriSpark
53 |
54 | Discover the nutritional values of your favorite foods. Use the search below to get started.
55 |
56 |
57 |
58 |
69 |
70 |
71 |
72 |
73 | No food found.
74 |
75 | {foods.map((food) => (
76 | {
80 | setValue(currentValue === value ? "" : currentValue);
81 | setOpen(false);
82 | }}
83 | className="hover:bg-gray-700"
84 | >
85 |
91 | {food.label}
92 |
93 | ))}
94 |
95 |
96 |
97 |
98 |
99 | ) : (
100 |
103 | )}
104 | >
105 | );
106 | }
107 |
--------------------------------------------------------------------------------
/tp2/src/components/ui/button.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import { Slot } from "@radix-ui/react-slot"
3 | import { cva, type VariantProps } from "class-variance-authority"
4 |
5 | import { cn } from "@/lib/utils"
6 |
7 | const buttonVariants = cva(
8 | "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
9 | {
10 | variants: {
11 | variant: {
12 | default: "bg-primary text-primary-foreground hover:bg-primary/90",
13 | destructive:
14 | "bg-destructive text-destructive-foreground hover:bg-destructive/90",
15 | outline:
16 | "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
17 | secondary:
18 | "bg-secondary text-secondary-foreground hover:bg-secondary/80",
19 | ghost: "hover:bg-accent hover:text-accent-foreground",
20 | link: "text-primary underline-offset-4 hover:underline",
21 | },
22 | size: {
23 | default: "h-10 px-4 py-2",
24 | sm: "h-9 rounded-md px-3",
25 | lg: "h-11 rounded-md px-8",
26 | icon: "h-10 w-10",
27 | },
28 | },
29 | defaultVariants: {
30 | variant: "default",
31 | size: "default",
32 | },
33 | }
34 | )
35 |
36 | export interface ButtonProps
37 | extends React.ButtonHTMLAttributes,
38 | VariantProps {
39 | asChild?: boolean
40 | }
41 |
42 | const Button = React.forwardRef(
43 | ({ className, variant, size, asChild = false, ...props }, ref) => {
44 | const Comp = asChild ? Slot : "button"
45 | return (
46 |
51 | )
52 | }
53 | )
54 | Button.displayName = "Button"
55 |
56 | export { Button, buttonVariants }
57 |
--------------------------------------------------------------------------------
/tp2/src/components/ui/command.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import { type DialogProps } from "@radix-ui/react-dialog"
5 | import { Command as CommandPrimitive } from "cmdk"
6 | import { Search } from "lucide-react"
7 |
8 | import { cn } from "@/lib/utils"
9 | import { Dialog, DialogContent } from "@/components/ui/dialog"
10 |
11 | const Command = React.forwardRef<
12 | React.ElementRef,
13 | React.ComponentPropsWithoutRef
14 | >(({ className, ...props }, ref) => (
15 |
23 | ))
24 | Command.displayName = CommandPrimitive.displayName
25 |
26 | interface CommandDialogProps extends DialogProps {}
27 |
28 | const CommandDialog = ({ children, ...props }: CommandDialogProps) => {
29 | return (
30 |
37 | )
38 | }
39 |
40 | const CommandInput = React.forwardRef<
41 | React.ElementRef,
42 | React.ComponentPropsWithoutRef
43 | >(({ className, ...props }, ref) => (
44 |
45 |
46 |
54 |
55 | ))
56 |
57 | CommandInput.displayName = CommandPrimitive.Input.displayName
58 |
59 | const CommandList = React.forwardRef<
60 | React.ElementRef,
61 | React.ComponentPropsWithoutRef
62 | >(({ className, ...props }, ref) => (
63 |
68 | ))
69 |
70 | CommandList.displayName = CommandPrimitive.List.displayName
71 |
72 | const CommandEmpty = React.forwardRef<
73 | React.ElementRef,
74 | React.ComponentPropsWithoutRef
75 | >((props, ref) => (
76 |
81 | ))
82 |
83 | CommandEmpty.displayName = CommandPrimitive.Empty.displayName
84 |
85 | const CommandGroup = React.forwardRef<
86 | React.ElementRef,
87 | React.ComponentPropsWithoutRef
88 | >(({ className, ...props }, ref) => (
89 |
97 | ))
98 |
99 | CommandGroup.displayName = CommandPrimitive.Group.displayName
100 |
101 | const CommandSeparator = React.forwardRef<
102 | React.ElementRef,
103 | React.ComponentPropsWithoutRef
104 | >(({ className, ...props }, ref) => (
105 |
110 | ))
111 | CommandSeparator.displayName = CommandPrimitive.Separator.displayName
112 |
113 | const CommandItem = React.forwardRef<
114 | React.ElementRef,
115 | React.ComponentPropsWithoutRef
116 | >(({ className, ...props }, ref) => (
117 |
125 | ))
126 |
127 | CommandItem.displayName = CommandPrimitive.Item.displayName
128 |
129 | const CommandShortcut = ({
130 | className,
131 | ...props
132 | }: React.HTMLAttributes) => {
133 | return (
134 |
141 | )
142 | }
143 | CommandShortcut.displayName = "CommandShortcut"
144 |
145 | export {
146 | Command,
147 | CommandDialog,
148 | CommandInput,
149 | CommandList,
150 | CommandEmpty,
151 | CommandGroup,
152 | CommandItem,
153 | CommandShortcut,
154 | CommandSeparator,
155 | }
156 |
--------------------------------------------------------------------------------
/tp2/src/components/ui/dialog.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as DialogPrimitive from "@radix-ui/react-dialog"
5 | import { X } from "lucide-react"
6 |
7 | import { cn } from "@/lib/utils"
8 |
9 | const Dialog = DialogPrimitive.Root
10 |
11 | const DialogTrigger = DialogPrimitive.Trigger
12 |
13 | const DialogPortal = DialogPrimitive.Portal
14 |
15 | const DialogClose = DialogPrimitive.Close
16 |
17 | const DialogOverlay = React.forwardRef<
18 | React.ElementRef,
19 | React.ComponentPropsWithoutRef
20 | >(({ className, ...props }, ref) => (
21 |
29 | ))
30 | DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
31 |
32 | const DialogContent = React.forwardRef<
33 | React.ElementRef,
34 | React.ComponentPropsWithoutRef
35 | >(({ className, children, ...props }, ref) => (
36 |
37 |
38 |
46 | {children}
47 |
48 |
49 | Close
50 |
51 |
52 |
53 | ))
54 | DialogContent.displayName = DialogPrimitive.Content.displayName
55 |
56 | const DialogHeader = ({
57 | className,
58 | ...props
59 | }: React.HTMLAttributes) => (
60 |
67 | )
68 | DialogHeader.displayName = "DialogHeader"
69 |
70 | const DialogFooter = ({
71 | className,
72 | ...props
73 | }: React.HTMLAttributes) => (
74 |
81 | )
82 | DialogFooter.displayName = "DialogFooter"
83 |
84 | const DialogTitle = React.forwardRef<
85 | React.ElementRef,
86 | React.ComponentPropsWithoutRef
87 | >(({ className, ...props }, ref) => (
88 |
96 | ))
97 | DialogTitle.displayName = DialogPrimitive.Title.displayName
98 |
99 | const DialogDescription = React.forwardRef<
100 | React.ElementRef,
101 | React.ComponentPropsWithoutRef
102 | >(({ className, ...props }, ref) => (
103 |
108 | ))
109 | DialogDescription.displayName = DialogPrimitive.Description.displayName
110 |
111 | export {
112 | Dialog,
113 | DialogPortal,
114 | DialogOverlay,
115 | DialogClose,
116 | DialogTrigger,
117 | DialogContent,
118 | DialogHeader,
119 | DialogFooter,
120 | DialogTitle,
121 | DialogDescription,
122 | }
123 |
--------------------------------------------------------------------------------
/tp2/src/components/ui/popover.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as PopoverPrimitive from "@radix-ui/react-popover"
5 |
6 | import { cn } from "@/lib/utils"
7 |
8 | const Popover = PopoverPrimitive.Root
9 |
10 | const PopoverTrigger = PopoverPrimitive.Trigger
11 |
12 | const PopoverContent = React.forwardRef<
13 | React.ElementRef,
14 | React.ComponentPropsWithoutRef
15 | >(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
16 |
17 |
27 |
28 | ))
29 | PopoverContent.displayName = PopoverPrimitive.Content.displayName
30 |
31 | export { Popover, PopoverTrigger, PopoverContent }
32 |
--------------------------------------------------------------------------------
/tp2/src/data.ts:
--------------------------------------------------------------------------------
1 | import { IFood } from "./types";
2 |
3 | export const foods: IFood[] = [
4 | { name: "Apple", calories: 52, carbohydrates: 14, protein: 0.3, fat: 0.2, fiber: 2.4, sugar: 10.4, vitamins: ["Vitamin C", "Vitamin K"], minerals: ["Potassium"] },
5 | { name: "Banana", calories: 96, carbohydrates: 23, protein: 1.3, fat: 0.3, fiber: 2.6, sugar: 12.2, vitamins: ["Vitamin B6", "Vitamin C"], minerals: ["Potassium", "Magnesium"] },
6 | { name: "Chicken", calories: 165, carbohydrates: 0, protein: 31, fat: 3.6, vitamins: ["Vitamin B6", "Vitamin B12"], minerals: ["Phosphorus", "Selenium"] },
7 | { name: "Salmon", calories: 206, carbohydrates: 0, protein: 22, fat: 12, vitamins: ["Vitamin D", "Vitamin B12"], minerals: ["Selenium", "Phosphorus"] },
8 | { name: "White Rice", calories: 130, carbohydrates: 28, protein: 2.4, fat: 0.3, fiber: 0.4, vitamins: ["Thiamine", "Niacin"], minerals: ["Magnesium", "Phosphorus"] },
9 | { name: "Almonds", calories: 173, carbohydrates: 6.1, protein: 6, fat: 15, fiber: 3.5, sugar: 1.2, vitamins: ["Vitamin E", "Riboflavin"], minerals: ["Magnesium", "Calcium"] },
10 | { name: "Whole Milk", calories: 149, carbohydrates: 11.7, protein: 7.7, fat: 8, vitamins: ["Vitamin D", "Vitamin B12"], minerals: ["Calcium", "Phosphorus"] },
11 | { name: "Egg", calories: 72, carbohydrates: 0.4, protein: 6.3, fat: 4.8, vitamins: ["Vitamin A", "Vitamin D"], minerals: ["Iron", "Zinc"] },
12 | { name: "Broccoli", calories: 34, carbohydrates: 6.6, protein: 2.8, fat: 0.4, fiber: 2.6, vitamins: ["Vitamin C", "Vitamin K"], minerals: ["Calcium", "Iron"] },
13 | { name: "Carrot", calories: 41, carbohydrates: 9.6, protein: 0.9, fat: 0.2, fiber: 2.8, vitamins: ["Vitamin A", "Vitamin K"], minerals: ["Potassium", "Calcium"] },
14 | { name: "Tomato", calories: 18, carbohydrates: 3.9, protein: 0.9, fat: 0.2, fiber: 1.2, vitamins: ["Vitamin C", "Vitamin K"], minerals: ["Potassium", "Iron"] },
15 | { name: "Spinach", calories: 23, carbohydrates: 3.6, protein: 2.9, fat: 0.4, fiber: 2.2, vitamins: ["Vitamin A", "Vitamin C"], minerals: ["Iron", "Calcium"] },
16 | { name: "Sweet Potato", calories: 86, carbohydrates: 20, protein: 1.6, fat: 0.1, fiber: 3, vitamins: ["Vitamin A", "Vitamin C"], minerals: ["Potassium", "Magnesium"] },
17 | { name: "Plain Yogurt", calories: 59, carbohydrates: 3.6, protein: 10, fat: 0.4, vitamins: ["Vitamin B12", "Vitamin B2"], minerals: ["Calcium", "Phosphorus"] },
18 | { name: "Cheddar Cheese", calories: 403, carbohydrates: 1.3, protein: 24, fat: 33, vitamins: ["Vitamin A", "Vitamin B12"], minerals: ["Calcium", "Phosphorus"] },
19 | { name: "Tofu", calories: 76, carbohydrates: 1.9, protein: 8, fat: 4.8, vitamins: ["Vitamin B1", "Vitamin B2"], minerals: ["Calcium", "Iron"] },
20 | { name: "Chickpeas", calories: 164, carbohydrates: 27.4, protein: 8.9, fat: 2.6, fiber: 7.6, vitamins: ["Folate", "Vitamin B6"], minerals: ["Iron", "Magnesium"] },
21 | { name: "Quinoa", calories: 120, carbohydrates: 21.3, protein: 4.1, fat: 1.9, fiber: 2.8, vitamins: ["Folate", "Vitamin B1"], minerals: ["Iron", "Magnesium"] },
22 | { name: "Avocado", calories: 160, carbohydrates: 8.5, protein: 2, fat: 14.7, fiber: 6.7, vitamins: ["Vitamin K", "Vitamin E"], minerals: ["Potassium", "Magnesium"] },
23 | { name: "Blueberries", calories: 57, carbohydrates: 14.5, protein: 0.7, fat: 0.3, fiber: 2.4, vitamins: ["Vitamin C", "Vitamin K"], minerals: ["Manganese", "Copper"] },
24 | { name: "Oats", calories: 389, carbohydrates: 66.3, protein: 16.9, fat: 6.9, fiber: 10.6, vitamins: ["Vitamin B1", "Vitamin B5"], minerals: ["Magnesium", "Zinc"] },
25 | { name: "Lentils", calories: 116, carbohydrates: 20.1, protein: 9, fat: 0.4, fiber: 7.9, vitamins: ["Folate", "Vitamin B6"], minerals: ["Iron", "Manganese"] },
26 | { name: "Red Bell Pepper", calories: 31, carbohydrates: 6, protein: 1, fat: 0.3, fiber: 2.1, vitamins: ["Vitamin C", "Vitamin A"], minerals: ["Potassium", "Manganese"] },
27 | { name: "Oranges", calories: 47, carbohydrates: 11.8, protein: 0.9, fat: 0.1, fiber: 2.4, sugar: 9.4, vitamins: ["Vitamin C", "Folate"], minerals: ["Calcium", "Potassium"] },
28 | { name: "Kiwi", calories: 61, carbohydrates: 14.7, protein: 1.1, fat: 0.5, fiber: 3, sugar: 8.9, vitamins: ["Vitamin C", "Vitamin K"], minerals: ["Potassium", "Magnesium"] },
29 | { name: "Potato", calories: 77, carbohydrates: 17.6, protein: 2, fat: 0.1, fiber: 2.2, vitamins: ["Vitamin C", "Vitamin B6"], minerals: ["Potassium", "Phosphorus"] },
30 | { name: "Celery", calories: 16, carbohydrates: 3, protein: 0.7, fat: 0.2, fiber: 1.6, vitamins: ["Vitamin K", "Vitamin A"], minerals: ["Calcium", "Potassium"] },
31 | { name: "Cauliflower", calories: 25, carbohydrates: 4.9, protein: 1.9, fat: 0.3, fiber: 2, vitamins: ["Vitamin C", "Vitamin K"], minerals: ["Calcium", "Potassium"] },
32 | { name: "Strawberries", calories: 32, carbohydrates: 7.7, protein: 0.7, fat: 0.3, fiber: 2, sugar: 4.9, vitamins: ["Vitamin C", "Folate"], minerals: ["Manganese", "Potassium"] },
33 | { name: "Pineapple", calories: 50, carbohydrates: 13.1, protein: 0.5, fat: 0.1, fiber: 1.4, sugar: 9.9, vitamins: ["Vitamin C", "Vitamin B6"], minerals: ["Manganese", "Potassium"] },
34 | { name: "Mango", calories: 60, carbohydrates: 15, protein: 0.8, fat: 0.4, fiber: 1.6, sugar: 13.7, vitamins: ["Vitamin C", "Vitamin A"], minerals: ["Potassium", "Magnesium"] },
35 | { name: "Grapes", calories: 69, carbohydrates: 18.1, protein: 0.7, fat: 0.2, fiber: 0.9, sugar: 15.5, vitamins: ["Vitamin C", "Vitamin K"], minerals: ["Potassium", "Copper"] },
36 | { name: "Grapefruit", calories: 42, carbohydrates: 10.7, protein: 0.8, fat: 0.1, fiber: 1.6, sugar: 7, vitamins: ["Vitamin C", "Vitamin A"], minerals: ["Potassium", "Calcium"] },
37 | { name: "Cantaloupe", calories: 34, carbohydrates: 8.2, protein: 0.8, fat: 0.2, fiber: 0.9, sugar: 7.9, vitamins: ["Vitamin A", "Vitamin C"], minerals: ["Potassium", "Magnesium"] },
38 | { name: "Zucchini", calories: 17, carbohydrates: 3.1, protein: 1.2, fat: 0.3, fiber: 1, vitamins: ["Vitamin A", "Vitamin C"], minerals: ["Potassium", "Magnesium"] },
39 | { name: "Cucumber", calories: 16, carbohydrates: 3.6, protein: 0.7, fat: 0.1, fiber: 0.5, vitamins: ["Vitamin K", "Vitamin C"], minerals: ["Potassium", "Magnesium"] },
40 | { name: "Pear", calories: 57, carbohydrates: 15.2, protein: 0.4, fat: 0.1, fiber: 3.1, sugar: 9.8, vitamins: ["Vitamin C", "Vitamin K"], minerals: ["Potassium", "Copper"] },
41 | { name: "Peach", calories: 39, carbohydrates: 9.5, protein: 0.9, fat: 0.3, fiber: 1.5, sugar: 8.4, vitamins: ["Vitamin C", "Vitamin A"], minerals: ["Potassium", "Manganese"] },
42 | { name: "Apricot", calories: 48, carbohydrates: 11.1, protein: 1.4, fat: 0.4, fiber: 2, sugar: 9.2, vitamins: ["Vitamin A", "Vitamin C"], minerals: ["Potassium", "Copper"] },
43 | { name: "Plum", calories: 46, carbohydrates: 11.4, protein: 0.7, fat: 0.3, fiber: 1.4, sugar: 9.9, vitamins: ["Vitamin C", "Vitamin K"], minerals: ["Potassium", "Copper"] },
44 | { name: "Cherry", calories: 50, carbohydrates: 12, protein: 1, fat: 0.3, fiber: 1.6, sugar: 8.5, vitamins: ["Vitamin C", "Vitamin A"], minerals: ["Potassium", "Manganese"] },
45 | { name: "Pomegranate", calories: 83, carbohydrates: 18.7, protein: 1.7, fat: 1.2, fiber: 4, sugar: 13.7, vitamins: ["Vitamin C", "Folate"], minerals: ["Potassium", "Copper"] },
46 | { name: "Papaya", calories: 43, carbohydrates: 10.8, protein: 0.5, fat: 0.3, fiber: 1.7, sugar: 7.8, vitamins: ["Vitamin C", "Folate"], minerals: ["Potassium", "Magnesium"] },
47 | { name: "Watermelon", calories: 30, carbohydrates: 7.6, protein: 0.6, fat: 0.2, fiber: 0.4, sugar: 6.2, vitamins: ["Vitamin C", "Vitamin A"], minerals: ["Potassium", "Magnesium"] },
48 | { name: "Lettuce", calories: 15, carbohydrates: 2.9, protein: 1.4, fat: 0.2, fiber: 1.3, vitamins: ["Vitamin A", "Vitamin K"], minerals: ["Potassium", "Calcium"] },
49 | { name: "Cabbage", calories: 25, carbohydrates: 5.8, protein: 1.3, fat: 0.1, fiber: 2.5, vitamins: ["Vitamin C", "Vitamin K"], minerals: ["Potassium", "Calcium"] },
50 | { name: "Brussels Sprouts", calories: 43, carbohydrates: 8.9, protein: 3.4, fat: 0.3, fiber: 3.8, vitamins: ["Vitamin C", "Vitamin K"], minerals: ["Potassium", "Magnesium"] },
51 | { name: "Eggplant", calories: 25, carbohydrates: 5.9, protein: 1, fat: 0.2, fiber: 3, vitamins: ["Vitamin C", "Vitamin K"], minerals: ["Potassium", "Magnesium"] },
52 | { name: "Leek", calories: 61, carbohydrates: 14.2, protein: 1.5, fat: 0.3, fiber: 1.8, vitamins: ["Vitamin A", "Vitamin C"], minerals: ["Potassium", "Magnesium"] },
53 | { name: "Turnip", calories: 28, carbohydrates: 6.2, protein: 0.9, fat: 0.1, fiber: 1.8, vitamins: ["Vitamin C", "Folate"], minerals: ["Potassium", "Calcium"] },
54 | { name: "Radish", calories: 16, carbohydrates: 3.4, protein: 0.7, fat: 0.1, fiber: 1.6, vitamins: ["Vitamin C", "Folate"], minerals: ["Potassium", "Magnesium"] },
55 | { name: "Beetroot", calories: 43, carbohydrates: 9.6, protein: 1.6, fat: 0.2, fiber: 2.8, vitamins: ["Vitamin C", "Folate"], minerals: ["Potassium", "Magnesium"] },
56 | { name: "Corn", calories: 86, carbohydrates: 19, protein: 3.2, fat: 1.2, fiber: 2.7, vitamins: ["Vitamin B3", "Vitamin B5"], minerals: ["Potassium", "Magnesium"] },
57 | { name: "Artichoke", calories: 47, carbohydrates: 10.5, protein: 3.3, fat: 0.2, fiber: 5.4, vitamins: ["Vitamin C", "Folate"], minerals: ["Potassium", "Magnesium"] },
58 | { name: "Watercress", calories: 11, carbohydrates: 1.3, protein: 2.3, fat: 0.1, fiber: 0.5, vitamins: ["Vitamin A", "Vitamin C"], minerals: ["Calcium", "Potassium"] },
59 | { name: "Swiss Chard", calories: 19, carbohydrates: 3.7, protein: 1.8, fat: 0.2, fiber: 1.6, vitamins: ["Vitamin A", "Vitamin K"], minerals: ["Calcium", "Potassium"] },
60 | { name: "Squash", calories: 26, carbohydrates: 6.5, protein: 1, fat: 0.1, fiber: 0.5, vitamins: ["Vitamin A", "Vitamin C"], minerals: ["Calcium", "Potassium"] },
61 | { name: "Fennel", calories: 31, carbohydrates: 7.3, protein: 1.2, fat: 0.2, fiber: 3.1, vitamins: ["Vitamin C", "Folate"], minerals: ["Potassium", "Magnesium"] },
62 | { name: "Green Beans", calories: 31, carbohydrates: 7, protein: 1.8, fat: 0.1, fiber: 2.7, vitamins: ["Vitamin C", "Vitamin A"], minerals: ["Calcium", "Potassium"] },
63 | { name: "Romaine Lettuce", calories: 17, carbohydrates: 3.3, protein: 1.2, fat: 0.3, fiber: 2.1, vitamins: ["Vitamin A", "Vitamin K"], minerals: ["Calcium", "Potassium"] },
64 | { name: "Onion", calories: 40, carbohydrates: 9.3, protein: 1.1, fat: 0.1, fiber: 1.7, vitamins: ["Vitamin C", "Folate"], minerals: ["Potassium", "Magnesium"] },
65 | { name: "Shallot", calories: 72, carbohydrates: 16.8, protein: 2.5, fat: 0.1, fiber: 3.2, vitamins: ["Vitamin C", "Vitamin B6"], minerals: ["Potassium", "Magnesium"] },
66 | { name: "Red Cabbage", calories: 31, carbohydrates: 7.4, protein: 1.4, fat: 0.2, fiber: 2.1, vitamins: ["Vitamin C", "Vitamin K"], minerals: ["Potassium", "Calcium"] },
67 | { name: "Peas", calories: 81, carbohydrates: 14.5, protein: 5.4, fat: 0.4, fiber: 5.1, vitamins: ["Vitamin C", "Folate"], minerals: ["Potassium", "Magnesium"] },
68 | { name: "Black Beans", calories: 132, carbohydrates: 23.7, protein: 8.9, fat: 0.5, fiber: 8.7, vitamins: ["Folate", "Vitamin B6"], minerals: ["Iron", "Magnesium"] },
69 | { name: "White Fish", calories: 84, carbohydrates: 0, protein: 18.8, fat: 1.2, vitamins: ["Vitamin D", "Vitamin B12"], minerals: ["Selenium", "Phosphorus"] },
70 | { name: "Tuna", calories: 132, carbohydrates: 0, protein: 28, fat: 1, vitamins: ["Vitamin B12", "Vitamin B6"], minerals: ["Selenium", "Phosphorus"] },
71 | { name: "Shrimp", calories: 99, carbohydrates: 0.2, protein: 24, fat: 0.3, vitamins: ["Vitamin B12", "Vitamin E"], minerals: ["Selenium", "Phosphorus"] },
72 | { name: "Oysters", calories: 68, carbohydrates: 3.9, protein: 7, fat: 2.5, vitamins: ["Vitamin B12", "Vitamin D"], minerals: ["Zinc", "Selenium"] },
73 | { name: "Beef", calories: 250, carbohydrates: 0, protein: 26, fat: 15, vitamins: ["Vitamin B12", "Vitamin B6"], minerals: ["Iron", "Zinc"] },
74 | { name: "Pork", calories: 242, carbohydrates: 0, protein: 27, fat: 14, vitamins: ["Vitamin B12", "Vitamin B6"], minerals: ["Phosphorus", "Zinc"] },
75 | { name: "Lamb", calories: 294, carbohydrates: 0, protein: 25, fat: 21, vitamins: ["Vitamin B12", "Vitamin B6"], minerals: ["Iron", "Zinc"] },
76 | { name: "Duck", calories: 337, carbohydrates: 0, protein: 19, fat: 28, vitamins: ["Vitamin B12", "Vitamin B6"], minerals: ["Iron", "Zinc"] },
77 | { name: "Rabbit", calories: 173, carbohydrates: 0, protein: 33, fat: 3.5, vitamins: ["Vitamin B12", "Vitamin B3"], minerals: ["Phosphorus", "Selenium"] },
78 | { name: "Turkey", calories: 189, carbohydrates: 0, protein: 29, fat: 7.4, vitamins: ["Vitamin B12", "Vitamin B6"], minerals: ["Phosphorus", "Selenium"] },
79 | { name: "Butter", calories: 717, carbohydrates: 0.1, protein: 0.9, fat: 81, vitamins: ["Vitamin A", "Vitamin D"], minerals: ["Calcium", "Phosphorus"] },
80 | { name: "Sour Cream", calories: 292, carbohydrates: 2.9, protein: 2.1, fat: 30, vitamins: ["Vitamin A", "Vitamin D"], minerals: ["Calcium", "Phosphorus"] },
81 | { name: "Olive Oil", calories: 884, carbohydrates: 0, protein: 0, fat: 100, vitamins: ["Vitamin E", "Vitamin K"], minerals: ["Iron"] },
82 | { name: "White Bread", calories: 265, carbohydrates: 49, protein: 9, fat: 3.2, fiber: 2.7, vitamins: ["Vitamin B1", "Vitamin B3"], minerals: ["Iron", "Calcium"] },
83 | { name: "Pasta", calories: 131, carbohydrates: 25, protein: 5.2, fat: 1.1, fiber: 1.4, vitamins: ["Vitamin B1", "Vitamin B3"], minerals: ["Iron", "Magnesium"] },
84 | { name: "Walnuts", calories: 196, carbohydrates: 3.9, protein: 4.3, fat: 20, fiber: 2, sugar: 1.1, vitamins: ["Vitamin E", "Folate"], minerals: ["Magnesium", "Phosphorus"] },
85 | { name: "Hazelnuts", calories: 178, carbohydrates: 4.7, protein: 4.2, fat: 17, fiber: 2.7, sugar: 1.2, vitamins: ["Vitamin E", "Thiamine"], minerals: ["Magnesium", "Copper"] },
86 | { name: "Pistachios", calories: 159, carbohydrates: 7.7, protein: 5.8, fat: 12.9, fiber: 3, sugar: 2.2, vitamins: ["Vitamin B6", "Thiamine"], minerals: ["Magnesium", "Phosphorus"] },
87 | { name: "Cashews", calories: 155, carbohydrates: 8.6, protein: 5.2, fat: 12.3, fiber: 1, sugar: 1.7, vitamins: ["Vitamin K", "Thiamine"], minerals: ["Magnesium", "Phosphorus"] }
88 | ];
--------------------------------------------------------------------------------
/tp2/src/lib/utils.ts:
--------------------------------------------------------------------------------
1 | import { type ClassValue, clsx } from "clsx"
2 | import { twMerge } from "tailwind-merge"
3 |
4 | export function cn(...inputs: ClassValue[]) {
5 | return twMerge(clsx(inputs))
6 | }
7 |
--------------------------------------------------------------------------------
/tp2/src/types/index.ts:
--------------------------------------------------------------------------------
1 | export interface IFood {
2 | name: string;
3 | calories: number;
4 | carbohydrates: number; // in grams
5 | protein: number; // in grams
6 | fat: number; // in grams
7 | fiber?: number; // in grams, optional
8 | sugar?: number; // in grams, optional
9 | vitamins?: string[]; // array of vitamins, optional
10 | minerals?: string[]; // array of minerals, optional
11 | }
12 |
13 | export interface IFoodReduced {
14 | value: string;
15 | label: string;
16 | }
17 |
18 | export interface IMacronutrientData {
19 | name: 'carbohydrates' | 'protein' | 'fat';
20 | value: number;
21 | }
--------------------------------------------------------------------------------
/tp2/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from "tailwindcss"
2 | const { fontFamily } = require("tailwindcss/defaultTheme")
3 |
4 | const config = {
5 | darkMode: ["class"],
6 | content: [
7 | './pages/**/*.{ts,tsx}',
8 | './components/**/*.{ts,tsx}',
9 | './app/**/*.{ts,tsx}',
10 | './src/**/*.{ts,tsx}',
11 | ],
12 | prefix: "",
13 | theme: {
14 | container: {
15 | center: true,
16 | padding: "2rem",
17 | screens: {
18 | "2xl": "1400px",
19 | },
20 | },
21 | extend: {
22 | fontFamily: {
23 | sans: ["var(--font-sans)", ...fontFamily.sans],
24 | },
25 | colors: {
26 | border: "hsl(var(--border))",
27 | input: "hsl(var(--input))",
28 | ring: "hsl(var(--ring))",
29 | background: "hsl(var(--background))",
30 | foreground: "hsl(var(--foreground))",
31 | primary: {
32 | DEFAULT: "hsl(var(--primary))",
33 | foreground: "hsl(var(--primary-foreground))",
34 | },
35 | secondary: {
36 | DEFAULT: "hsl(var(--secondary))",
37 | foreground: "hsl(var(--secondary-foreground))",
38 | },
39 | destructive: {
40 | DEFAULT: "hsl(var(--destructive))",
41 | foreground: "hsl(var(--destructive-foreground))",
42 | },
43 | muted: {
44 | DEFAULT: "hsl(var(--muted))",
45 | foreground: "hsl(var(--muted-foreground))",
46 | },
47 | accent: {
48 | DEFAULT: "hsl(var(--accent))",
49 | foreground: "hsl(var(--accent-foreground))",
50 | },
51 | popover: {
52 | DEFAULT: "hsl(var(--popover))",
53 | foreground: "hsl(var(--popover-foreground))",
54 | },
55 | card: {
56 | DEFAULT: "hsl(var(--card))",
57 | foreground: "hsl(var(--card-foreground))",
58 | },
59 | },
60 | borderRadius: {
61 | lg: "var(--radius)",
62 | md: "calc(var(--radius) - 2px)",
63 | sm: "calc(var(--radius) - 4px)",
64 | },
65 | keyframes: {
66 | "accordion-down": {
67 | from: { height: "0" },
68 | to: { height: "var(--radix-accordion-content-height)" },
69 | },
70 | "accordion-up": {
71 | from: { height: "var(--radix-accordion-content-height)" },
72 | to: { height: "0" },
73 | },
74 | },
75 | animation: {
76 | "accordion-down": "accordion-down 0.2s ease-out",
77 | "accordion-up": "accordion-up 0.2s ease-out",
78 | },
79 | },
80 | },
81 | plugins: [require("tailwindcss-animate")],
82 | } satisfies Config
83 |
84 | export default config
--------------------------------------------------------------------------------
/tp2/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["dom", "dom.iterable", "esnext"],
4 | "allowJs": true,
5 | "skipLibCheck": true,
6 | "strict": true,
7 | "noEmit": true,
8 | "esModuleInterop": true,
9 | "module": "esnext",
10 | "moduleResolution": "bundler",
11 | "resolveJsonModule": true,
12 | "isolatedModules": true,
13 | "jsx": "preserve",
14 | "incremental": true,
15 | "plugins": [
16 | {
17 | "name": "next"
18 | }
19 | ],
20 | "paths": {
21 | "@/*": ["./src/*"]
22 | }
23 | },
24 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
25 | "exclude": ["node_modules"]
26 | }
27 |
--------------------------------------------------------------------------------