Skip to content

Commit 2e1d669

Browse files
authored
Merge pull request #162 from CodeSpace-Academy/main
Bring over changes from old repo to new repo
2 parents 7e15e58 + d41dc3e commit 2e1d669

34 files changed

+1087
-1802
lines changed

.env

Lines changed: 0 additions & 1 deletion
This file was deleted.

.github/workflows/linting.yml

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,30 +13,32 @@ jobs:
1313
strategy:
1414
matrix:
1515
node-version: [18.x, 20.x, 22.x]
16-
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
1716

18-
steps:
19-
- uses: actions/checkout@v4
20-
21-
- name: Use Node.js ${{ matrix.node-version }}
22-
uses: actions/setup-node@v4
23-
with:
24-
node-version: ${{ matrix.node-version }}
25-
cache: 'npm'
26-
27-
- name: Cache node modules
28-
uses: actions/[email protected]
29-
with:
30-
path: node_modules
31-
key: node-modules-${{ runner.os }}-node-${{ matrix.node-version }}-${{ hashFiles('package-lock.json') }}
32-
restore-keys: |
33-
node-modules-${{ runner.os }}-node-${{ matrix.node-version }}
17+
env: # Set environment variables at the job level
18+
MONGODB_URI: ${{ secrets.MONGODB_URI }} # Ensure this is correctly set
3419

35-
# Install dependencies with --legacy-peer-deps to avoid peer conflict issues
36-
- run: npm ci --legacy-peer-deps
37-
38-
# Linting step
39-
- run: npm run lint
40-
41-
# Build step
42-
- run: npm run build --if-present
20+
steps:
21+
- uses: actions/checkout@v4
22+
- name: Use Node.js ${{ matrix.node-version }}
23+
uses: actions/setup-node@v4
24+
with:
25+
node-version: ${{ matrix.node-version }}
26+
cache: 'npm'
27+
- name: Debug MongoDB URI
28+
run: echo "MONGODB_URI is set to: $MONGODB_URI" # Use the env variable instead of the secret directly
29+
env:
30+
MONGODB_URI: ${{ secrets.MONGODB_URI }}
31+
- name: Cache node modules
32+
uses: actions/[email protected]
33+
with:
34+
path: node_modules
35+
key: node-modules-${{ runner.os }}-node-${{ matrix.node-version }}-${{ hashFiles('package-lock.json') }}
36+
restore-keys: |
37+
node-modules-${{ runner.os }}-node-${{ matrix.node-version }}
38+
- run: npm ci --legacy-peer-deps
39+
- run: npm run lint
40+
- run: npm run build --if-present
41+
- name: Run tests
42+
run: |
43+
cd backend
44+
npx mocha --config .mocharc.json

.storybook/main.js

Lines changed: 0 additions & 28 deletions
This file was deleted.

.storybook/main.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import type { StorybookConfig } from "@storybook/nextjs";
2+
3+
const config: StorybookConfig = {
4+
stories: [
5+
"../app/components/**/*.mdx",
6+
"../app/components/**/*.stories.@(js|jsx|mjs|ts|tsx)",
7+
"../app/components/**/**/*.mdx",
8+
"../app/components/**/**/*.stories.@(js|jsx|mjs|ts|tsx)",
9+
"../app/components/stories/**/*.mdx",
10+
"../app/components/stories/**/*.stories.@(js|jsx|mjs|ts|tsx)",
11+
"../app/components/stories/*.mdx",
12+
"../app/components/stories/*.stories.@(js|jsx|mjs|ts|tsx)",
13+
],
14+
addons: [
15+
"@storybook/addon-onboarding",
16+
"@storybook/addon-links",
17+
"@storybook/addon-essentials",
18+
"@chromatic-com/storybook",
19+
"@storybook/addon-interactions",
20+
"@storybook/addon-styling-webpack"
21+
],
22+
framework: {
23+
name: "@storybook/nextjs",
24+
options: {},
25+
},
26+
};
27+
export default config;
Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
/** @type { import('@storybook/react').Preview } */
2-
const preview = {
1+
// .storybook/preview.js
2+
3+
import type { Preview } from "@storybook/react";
4+
import '../app/global.css';
5+
6+
const preview: Preview = {
37
parameters: {
48
controls: {
59
matchers: {
@@ -8,8 +12,7 @@ const preview = {
812
},
913
},
1014
},
11-
12-
tags: ["autodocs"]
1315
};
1416

1517
export default preview;
18+

app/api/recipe/[id]/route.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { NextResponse } from 'next/server';
2+
import clientPromise from '../../../../lib/mongodb';
3+
4+
/**
5+
* Server-side API route to fetch a single recipe by its ID.
6+
*/
7+
export async function GET(_req, { params }) {
8+
const { id } = params;
9+
10+
try {
11+
// Connect to the MongoDB client
12+
const client = await clientPromise;
13+
const db = client.db('devdb');
14+
15+
// Fetch the recipe document by its _id
16+
const recipe = await db.collection('recipes').findOne({ _id: id });
17+
18+
if (!recipe) {
19+
return NextResponse.json({ error: 'Recipe not found' }, { status: 404 });
20+
}
21+
22+
// Return the recipe data
23+
return NextResponse.json(recipe);
24+
} catch (error) {
25+
return NextResponse.json({ error: 'Failed to fetch recipe' }, { status: 500 });
26+
}
27+
}

app/api/recipes.js

Lines changed: 0 additions & 32 deletions
This file was deleted.

app/api/recipes/route.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import clientPromise from "../../../lib/mongodb";
2+
3+
/**
4+
* API route handler for fetching paginated recipes from the 'recipes' collection in MongoDB.
5+
*
6+
* @async
7+
* @function
8+
* @param {Object} req - The request object containing query parameters for pagination.
9+
* @returns {Promise<void>} Sends a JSON response containing the paginated recipes or an error message.
10+
*/
11+
export async function GET(req) {
12+
try {
13+
// Await the MongoDB client connection
14+
const client = await clientPromise;
15+
const db = client.db("devdb"); // Connect to the 'devdb' database
16+
17+
// Parse the 'page' and 'limit' query parameters from the URL, with defaults
18+
const url = new URL(req.url);
19+
const page = parseInt(url.searchParams.get("page") || "1", 10);
20+
const limit = parseInt(url.searchParams.get("limit") || "20", 10);
21+
22+
// Calculate the number of documents to skip for pagination
23+
const skip = (page - 1) * limit;
24+
25+
// Fetch the paginated recipes from the collection
26+
const recipes = await db.collection("recipes")
27+
.find({})
28+
.skip(skip)
29+
.limit(limit)
30+
.toArray();
31+
32+
// Send a 200 (OK) response with the fetched recipes in JSON format
33+
return new Response(JSON.stringify({ recipes }), { status: 200 });
34+
} catch (e) {
35+
36+
37+
return new Response(JSON.stringify({ error: "Failed to fetch data" }), { status: 500 });
38+
}
39+
}

app/components/Carousel.js

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
"use client";
2+
3+
import { useState } from "react";
4+
import Image from 'next/image';
5+
6+
export default function Carousel({ images }) {
7+
const [currentIndex, setCurrentIndex] = useState(0);
8+
9+
const prevSlide = () => {
10+
setCurrentIndex((prevIndex) =>
11+
prevIndex === 0 ? images.length - 1 : prevIndex - 1
12+
);
13+
};
14+
15+
const nextSlide = () => {
16+
setCurrentIndex((prevIndex) =>
17+
prevIndex === images.length - 1 ? 0 : prevIndex + 1
18+
);
19+
};
20+
21+
// Determine if there are more than one image
22+
const hasMultipleImages = images.length > 1;
23+
24+
return (
25+
<div className="relative w-full h-64 overflow-hidden">
26+
<Image
27+
src={images[currentIndex]}
28+
alt={`Slide ${currentIndex}`}
29+
width={500} height={500} quality={75} priority
30+
className="w-full h-full object-contain"
31+
/>
32+
{/* Previous Button */}
33+
{hasMultipleImages && (
34+
<button
35+
onClick={prevSlide}
36+
className="absolute left-0 top-1/2 transform -translate-y-1/2 bg-white p-2 rounded-full shadow"
37+
>
38+
<svg
39+
xmlns="http://www.w3.org/2000/svg"
40+
className="h-6 w-6 text-gray-800"
41+
fill="none"
42+
viewBox="0 0 24 24"
43+
stroke="currentColor"
44+
>
45+
<path
46+
strokeLinecap="round"
47+
strokeLinejoin="round"
48+
strokeWidth={2}
49+
d="M15 19l-7-7 7-7"
50+
/>
51+
</svg>
52+
</button>
53+
)}
54+
{/* Next Button */}
55+
{hasMultipleImages && (
56+
<button
57+
onClick={nextSlide}
58+
className="absolute right-0 top-1/2 transform -translate-y-1/2 bg-white p-2 rounded-full shadow"
59+
>
60+
<svg
61+
xmlns="http://www.w3.org/2000/svg"
62+
className="h-6 w-6 text-gray-800"
63+
fill="none"
64+
viewBox="0 0 24 24"
65+
stroke="currentColor"
66+
>
67+
<path
68+
strokeLinecap="round"
69+
strokeLinejoin="round"
70+
strokeWidth={2}
71+
d="M9 5l7 7-7 7"
72+
/>
73+
</svg>
74+
</button>
75+
)}
76+
</div>
77+
);
78+
}

app/components/CookTimeIcon.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export function CookTimeIcon() {
2+
return (
3+
<svg fill="#000000" width="25px" height="25px" viewBox="0 0 512.853 512.853" xmlns="http://www.w3.org/2000/svg">
4+
<g>
5+
{/* Your SVG path data here */}
6+
</g>
7+
</svg>
8+
);
9+
}
10+

app/components/PrepTimeIcon.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export function PrepTimeIcon() {
2+
return (
3+
<svg fill="#000000" width="25px" height="25px" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
4+
<g>
5+
{/* Your SVG path data here */}
6+
</g>
7+
</svg>
8+
);
9+
}
10+

0 commit comments

Comments
 (0)