Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implemented both dynamic metadata on the recipe detail page so that each recipe has unique SEO information & SEO best practices. #68

Open
wants to merge 100 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
c926858
Merge pull request #50 from CodeSpace-Academy/main
Phillip-tech Oct 21, 2024
98b0cab
Merge branch 'main' of https://github.com/CodeSpace-Academy/ASE_2024_…
Phillip-tech Oct 21, 2024
5867fb8
nav bar setup
Phillip-tech Oct 21, 2024
d26196a
Created an Api endpoint to fetch Data
kutlwano10 Oct 21, 2024
0d7dc18
Merge branch 'deployment' of https://github.com/CodeSpace-Academy/ASE…
kutlwano10 Oct 21, 2024
eaf326b
use client-side rendering for RecipeGrid component
KoketsoMoilwe20 Oct 21, 2024
32d0155
implement useState for managing recipe data in RecipeGrid
KoketsoMoilwe20 Oct 21, 2024
21eac74
add useEffect hook for fetching recipe data
KoketsoMoilwe20 Oct 21, 2024
cf9ecb7
render RecipeCards in a responsive grid layout
KoketsoMoilwe20 Oct 21, 2024
60ea6b8
create RecipeCard component for displaying recipe details
KoketsoMoilwe20 Oct 21, 2024
6d750a6
Render RecipeGrid component
KoketsoMoilwe20 Oct 21, 2024
f390a74
Merge branch 'Grid-and-Card-Layout' into deployment
KoketsoMoilwe20 Oct 21, 2024
d844efd
Merge branch 'deployment' of https://github.com/CodeSpace-Academy/ASE…
KoketsoMoilwe20 Oct 21, 2024
c7b11f0
Merge pull request #58 from CodeSpace-Academy/main
KoketsoMoilwe20 Oct 21, 2024
de812c9
Merge pull request #59 from CodeSpace-Academy/Grid-and-Card-Layout
KoketsoMoilwe20 Oct 21, 2024
d0b3d54
Merge branch 'deployment' of https://github.com/CodeSpace-Academy/ASE…
Phillip-tech Oct 21, 2024
aa77c91
loading state with skeletonMain component
KitsoMogale Oct 21, 2024
1c0799a
change title to name for recipe name display
KoketsoMoilwe20 Oct 21, 2024
a6684e3
Testing
SABELOMAWELA Oct 21, 2024
c2f3c77
Merge branch 'Grid-and-Card-Layout' of https://github.com/CodeSpace-A…
SABELOMAWELA Oct 21, 2024
4740d09
"Wrapped RecipeCard component with Next.js Link component, adding nav…
SABELOMAWELA Oct 21, 2024
c69e292
"Display recipe title and description on the recipe detail page"
SABELOMAWELA Oct 21, 2024
83213f4
"Added servings information to RecipeCard component and reformatted l…
SABELOMAWELA Oct 21, 2024
c17627c
Merge branch 'deployment' of https://github.com/CodeSpace-Academy/ASE…
KitsoMogale Oct 21, 2024
d554da4
"Added formatTime function, updated RecipeDetail component to display…
SABELOMAWELA Oct 22, 2024
8f32083
Merge pull request #60 from CodeSpace-Academy/Grid-and-Card-Layout
KoketsoMoilwe20 Oct 22, 2024
d54d53b
"Refactored RecipeDetail component to include router, added active ta…
SABELOMAWELA Oct 22, 2024
ba0d197
Merge branch 'deployment' of https://github.com/CodeSpace-Academy/ASE…
SABELOMAWELA Oct 22, 2024
8e49b19
Merge branch 'Productdetail' of https://github.com/CodeSpace-Academy/…
SABELOMAWELA Oct 22, 2024
ec18e8d
Merge branch 'deployment' of https://github.com/CodeSpace-Academy/ASE…
KoketsoMoilwe20 Oct 22, 2024
a611b3e
"Updated Navbar component, removed RecipeCards component, refactored …
Phillip-tech Oct 22, 2024
ed33aad
Merge branch 'Nav_Bar' into deployment
Phillip-tech Oct 22, 2024
ac85235
Merge branch 'deployment' of https://github.com/CodeSpace-Academy/ASE…
SABELOMAWELA Oct 22, 2024
79cf3a3
skeleton css fixed
KitsoMogale Oct 22, 2024
4620924
Merge branch 'loading' into deployment
KitsoMogale Oct 22, 2024
97d9c33
added loading state for reipe details
KitsoMogale Oct 22, 2024
aaaa5a9
Created Get request to get the database recipe
kutlwano10 Oct 22, 2024
17fb159
Merge branch 'deployment' of https://github.com/CodeSpace-Academy/ASE…
kutlwano10 Oct 22, 2024
e5c2cf0
changed MONGODB_URI
kutlwano10 Oct 22, 2024
1f7697f
Update layout.js
Mateo-Benzien Oct 23, 2024
38730c6
"Updated API routes, components, and dependencies in Next.js app, inc…
SABELOMAWELA Oct 23, 2024
c35bb84
Made Api endpoints for recipe & for recipe ID using mongoDB URI
kutlwano10 Oct 23, 2024
5ea257f
Added mobile menu and drag functionality to Navbar component
Phillip-tech Oct 23, 2024
d258867
Fetch data from database(MongoDb)
KoketsoMoilwe20 Oct 23, 2024
42f520c
Merge pull request #64 from CodeSpace-Academy/Grid-and-Card-Layout
KoketsoMoilwe20 Oct 23, 2024
d8a18ca
Updated Navbar component with drag functionality, added mobile menu a…
Phillip-tech Oct 23, 2024
5faea70
Factored mobile menu and drag functionality to Navbar component"
Phillip-tech Oct 23, 2024
ace3021
Merge branch 'Nav_Bar' into deployment
Phillip-tech Oct 23, 2024
83aff99
"Updated imports in RecipeGrid and recipe page components"
SABELOMAWELA Oct 23, 2024
47c7b1d
"Updated imports in RecipeGrid and recipe page components"
SABELOMAWELA Oct 23, 2024
41e9791
Added fuse.js dependency and updated Navbar component
Mmakgosana Oct 23, 2024
d48dbd9
Updated RootLayout to use new wrapper
Phillip-tech Oct 23, 2024
a3c6308
Created NavWrapper component
Phillip-tech Oct 23, 2024
778a161
Fixed Module to include the ID , then i inserted lean() on Both API …
kutlwano10 Oct 23, 2024
61146b8
merged single api endpoint
kutlwano10 Oct 23, 2024
dede863
Merge branch 'deployment' of https://github.com/CodeSpace-Academy/ASE…
kutlwano10 Oct 23, 2024
4a8ee60
Extracted navbar position logic into new ClientNavWrapper
Phillip-tech Oct 23, 2024
129f1b0
"Refactor recipe route to support search query parameter and remove F…
Mmakgosana Oct 23, 2024
89b3cf4
Created a new file 'Navbar.js' for the Navbar component
Phillip-tech Oct 23, 2024
2056439
Modify styling
KoketsoMoilwe20 Oct 23, 2024
ff0c286
Update route.js
KoketsoMoilwe20 Oct 23, 2024
e40133d
Merge branch 'deployment' of https://github.com/CodeSpace-Academy/ASE…
kutlwano10 Oct 23, 2024
b54b09f
Fixed Key id for recipeGrid
kutlwano10 Oct 23, 2024
4d7fbfb
Merge branch 'deployment' of https://github.com/CodeSpace-Academy/ASE…
SABELOMAWELA Oct 23, 2024
a5f038e
"Refactored RecipeDetail component: updated console logs, modified re…
SABELOMAWELA Oct 23, 2024
d12f32c
"Refactored RecipeDetail component: updated console logs, changed rec…
SABELOMAWELA Oct 23, 2024
6ba9c9d
Merge pull request #66 from Cheplusplus/Productdetail
SABELOMAWELA Oct 23, 2024
8978516
"Updated RecipeDetail component: refactored recipe data display, adde…
SABELOMAWELA Oct 23, 2024
f07169b
"Updated RecipeDetail component: added margin top to container, chang…
SABELOMAWELA Oct 23, 2024
b75815d
Merge branch 'deployment' of https://github.com/Cheplusplus/ASE_2024_…
Oct 24, 2024
0a62bcc
Merge branch 'Productdetail' of https://github.com/CodeSpace-Academy/…
KoketsoMoilwe20 Oct 24, 2024
17afed7
Merge branch 'Productdetail' of https://github.com/Cheplusplus/ASE_20…
KoketsoMoilwe20 Oct 24, 2024
78ee8ab
add tags display to recipe detail page
KoketsoMoilwe20 Oct 24, 2024
9b5a7cc
"Refactored RecipeDetailCard component and RecipeDetail page, extract…
SABELOMAWELA Oct 24, 2024
4bb8985
"Updated import paths for connectToDatabase and Recipe in recipe rout…
SABELOMAWELA Oct 24, 2024
6531fed
"Updated import paths for connectToDatabase and Recipe in recipe rout…
SABELOMAWELA Oct 24, 2024
ffe2b89
Change component to serverside
KoketsoMoilwe20 Oct 24, 2024
a5a63d9
Merge branch 'deployment' of https://github.com/Cheplusplus/ASE_2024_…
KoketsoMoilwe20 Oct 24, 2024
b65d316
Merge branch 'deployment' of https://github.com/Cheplusplus/ASE_2024_…
Mmakgosana Oct 24, 2024
a77ac19
commit
Oct 24, 2024
9a324e6
Merge branch 'Add-Site-Wide-Meta-Tags' into deployment
Oct 24, 2024
e1cfe23
i Fixed layout conflicts
kutlwano10 Oct 24, 2024
84bfbba
package-lock json update
Oct 24, 2024
6e7134b
Merge branch 'deployment' of https://github.com/Cheplusplus/ASE_2024_…
Oct 24, 2024
ab64511
Create build action
Cheplusplus Oct 24, 2024
2ada079
Update node.js.yml
Cheplusplus Oct 24, 2024
2839938
public url for env variable
Oct 24, 2024
99ddc26
Update node.js.yml
Cheplusplus Oct 24, 2024
a273d74
Update node.js.yml
Cheplusplus Oct 24, 2024
241fbdb
Reduced spacing in layout
Phillip-tech Oct 24, 2024
1a9cc10
Merge branch 'deployment' of https://github.com/Cheplusplus/ASE_2024_…
Phillip-tech Oct 24, 2024
811fb39
Refactored Navbar component: removed useEffect hook, rearranged mobil…
Phillip-tech Oct 24, 2024
7f01939
public url for env variable
Karabo-M-Radebe Oct 25, 2024
c3eb6e3
implemented dynamic metadata on the recipe detail page
Mateo-Benzien Oct 25, 2024
2071d71
layout updated
kutlwano10 Oct 25, 2024
44ed36c
Merge branch 'deployment' of https://github.com/Cheplusplus/ASE_2024_…
kutlwano10 Oct 25, 2024
f3d3894
remove 'git error'
kutlwano10 Oct 25, 2024
942c704
Merged deployment
kutlwano10 Oct 25, 2024
9d4fcd1
Merge branch 'main' of https://github.com/Cheplusplus/ASE_2024_GROUP_…
SABELOMAWELA Oct 25, 2024
8ce63ad
"Added @fortawesome/fontawesome-common-types, @fortawesome/fontawesom…
SABELOMAWELA Oct 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs

name: Node.js CI

env:
MONGODB_URI: ${{ vars.MONGODB_URI }}
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
build:

runs-on: ubuntu-latest
environment: build
env:
MONGODB_URI: ${{ secrets.MONGODB_URI }}
NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }}
strategy:
matrix:
node-version: [18.x, 20.x, 22.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/

steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm i
- run: npm run build
26 changes: 26 additions & 0 deletions app/api/recipe/[id]/route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import connectToDatabase from "@/lib/connectMongoose";
import Recipe from "@/models/Recipe";
import { NextResponse } from "next/server";
import mongoose from "mongoose";

/**
*
* @param {*} req
* @param {id} param1 - This Will get the exact recipe id from database
* @returns - The recipe object by its Id
*/

export async function GET(req, { params }) {
try {
let { id } = params;
console.log(id)
// id = new mongoose.Types.ObjectId();
console.log(id)
await connectToDatabase();
const recipe = await Recipe.findOne({ _id: id });

return NextResponse.json({ recipe }, { status: 200 });
} catch (error) {
console.error(error);
}
}
32 changes: 32 additions & 0 deletions app/api/recipe/route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import connectToDatabase from "@/lib/connectMongoose";
import Recipe from "@/models/Recipe";
import { NextResponse } from "next/server";

export async function GET(req) {
try {
await connectToDatabase(); // Ensure the database is connected

const { search } = req.nextUrl.searchParams; // Get the 'search' query parameter
let query = {};

// Check if the search parameter is provided and build the query
if (search) {
query = {
$or: [
{ name: { $regex: search, $options: "i" } }, // Assuming 'name' is a field in your Recipe model
{ ingredients: { $regex: search, $options: "i" } } // Assuming 'ingredients' is another field
]
};
}

// Fetch recipes based on the search query
const recipes = await Recipe.find(query).limit(50); // Limit to 50 results
return NextResponse.json({ success: true, recipes }); // Respond with recipes
} catch (error) {
console.error("Error searching recipes:", error);
return NextResponse.json(
{ success: false, message: "Failed to search recipes." },
{ status: 500 } // Return a 500 status code
);
}
}
23 changes: 23 additions & 0 deletions app/components/ClientNavWrapper.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// components/ClientNavWrapper.jsx
'use client';
import { useState, useEffect } from 'react';
import React from 'react';

export default function ClientNavWrapper({ children }) {
const [navbarPosition, setNavbarPosition] = useState(0);

useEffect(() => {
const handleKeyDown = (e) => {
if (e.key === 'ArrowLeft') {
setNavbarPosition((prev) => Math.max(prev - 10, -100));
} else if (e.key === 'ArrowRight') {
setNavbarPosition((prev) => Math.min(prev + 10, 100));
}
};

window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, []);

return React.cloneElement(children, { position: navbarPosition });
}
141 changes: 141 additions & 0 deletions app/components/Footer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import { AiOutlineArrowRight } from 'react-icons/ai'; // Correct icon import for ArrowRight
import { FaUtensils, FaEnvelope, FaPhone, FaMapPin, FaTwitter, FaYoutube, FaFacebook, FaInstagram } from 'react-icons/fa'; // Correct icon imports
import Link from 'next/link'; // Corrected import for Link

const Footer = () => {
const socialLinks = [
{
icon: FaTwitter,
href: 'https://twitter.com',
color: 'hover:text-[#1DA1F2] transition-colors duration-300',
label: 'Twitter'
},
{
icon: FaYoutube,
href: 'https://youtube.com',
color: 'hover:text-[#FF0000] transition-colors duration-300',
label: 'YouTube'
},
{
icon: FaFacebook,
href: 'https://facebook.com',
color: 'hover:text-[#4267B2] transition-colors duration-300',
label: 'Facebook'
},
{
icon: FaInstagram,
href: 'https://instagram.com',
color: 'hover:text-[#E1306C] transition-colors duration-300',
label: 'Instagram'
},
];

const quickLinks = [
{ name: 'About Us', href: '/about' },
{ name: 'Contact', href: '/contact' },
{ name: 'Recipe Index', href: '/recipes' },
{ name: 'Privacy Policy', href: '/privacy' },
{ name: 'Terms of Service', href: '/terms' },
];

return (
<footer className="bg-gray-900 text-white mt-auto">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
{/* Main Footer Content */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-8 py-12">
{/* About Section */}
<div className="space-y-4">
<h3 className="text-xl font-semibold flex items-center">
<FaUtensils className="h-6 w-6 mr-2" />
RecipeApp
</h3>
<p className="text-gray-400">
Discover and share delicious recipes from around the world.
</p>
</div>

{/* Quick Links */}
<div>
<h3 className="text-xl font-semibold mb-4">Quick Links</h3>
<ul className="space-y-2">
{quickLinks.map((link) => (
<li key={link.name}>
<Link
href={link.href}
className="text-gray-400 hover:text-white flex items-center group"
>
<AiOutlineArrowRight className="h-4 w-4 mr-2 opacity-0 group-hover:opacity-100 transition-opacity duration-300" />
{link.name}
</Link>
</li>
))}
</ul>
</div>

{/* Contact Info */}
<div>
<h3 className="text-xl font-semibold mb-4">Contact Us</h3>
<ul className="space-y-2 text-gray-400">
<li className="flex items-center">
<FaEnvelope className="h-4 w-4 mr-2" />
[email protected]
</li>
<li className="flex items-center">
<FaPhone className="h-4 w-4 mr-2" />
+1 (555) 123-4567
</li>
<li className="flex items-center">
<FaMapPin className="h-4 w-4 mr-2" />
123 Recipe Street, Foodville
</li>
</ul>
</div>

{/* Newsletter */}
<div>
<h3 className="text-xl font-semibold mb-4">Newsletter</h3>
<p className="text-gray-400 mb-4">
Subscribe for new recipes and cooking tips.
</p>
<form className="space-y-2">
<input
type="email"
placeholder="Your email"
className="w-full px-4 py-2 rounded-md bg-gray-800 border border-gray-700 focus:outline-none focus:ring-2 focus:ring-purple-500"
/>
<button className="w-full px-4 py-2 bg-purple-600 hover:bg-purple-700 rounded-md transition duration-300">
Subscribe
</button>
</form>
</div>
</div>

{/* Social Links */}
<div className="border-t border-gray-800 py-8">
<div className="flex flex-col md:flex-row justify-between items-center space-y-4 md:space-y-0">
<div className="flex space-x-6">
{socialLinks.map((social) => (
<a
key={social.label}
href={social.href}
target="_blank"
rel="noopener noreferrer"
className={`text-gray-400 ${social.color}`}
aria-label={social.label}
>
<social.icon className="h-6 w-6" />
</a>
))}
</div>
<p className="text-gray-400">
&copy; {new Date().getFullYear()} RecipeApp. All rights reserved.
</p>
</div>
</div>
</div>
</footer>
);
};

export default Footer;

Loading