Skip to content

Commit 7f7264b

Browse files
authored
Merge branch 'master' into master
2 parents 2b65b6f + 6be7c0f commit 7f7264b

File tree

18 files changed

+761
-312
lines changed

18 files changed

+761
-312
lines changed

.github/workflows/auto-label.yml

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,41 @@
1-
name: Auto Label Issue
1+
name: Auto Label Issue/PR
22

33
on:
44
issues:
55
types: [opened, reopened, edited]
6+
pull_request:
7+
types: [opened, reopened, edited]
68

79
jobs:
8-
label_issue:
10+
label_issue_pr:
911
runs-on: ubuntu-latest
1012
permissions:
1113
issues: write
14+
pull-requests: write
1215
steps:
13-
- name: Label Issue
16+
- name: Label Issue/PR
1417
uses: actions/github-script@v6
1518
with:
1619
github-token: ${{secrets.GITHUB_TOKEN}}
1720
script: |
18-
const issue = context.payload.issue;
19-
const issueBody = issue.body ? issue.body.toLowerCase() : '';
20-
const issueTitle = issue.title.toLowerCase();
21+
const isIssue = context.payload.issue !== undefined;
22+
const item = isIssue ? context.payload.issue : context.payload.pull_request;
23+
const itemBody = item.body ? item.body.toLowerCase() : '';
24+
const itemTitle = item.title.toLowerCase();
2125
22-
// Add gssoc label to all issues
26+
// Add labels to both issues and pull requests
2327
await github.rest.issues.addLabels({
2428
owner: context.repo.owner,
2529
repo: context.repo.repo,
26-
issue_number: issue.number,
27-
labels: ['gssoc-ext','hacktoberfest-accepted']
30+
issue_number: item.number,
31+
labels: ['gssoc-ext', 'hacktoberfest-accepted']
2832
});
33+
2934
const addLabel = async (label) => {
3035
await github.rest.issues.addLabels({
3136
owner: context.repo.owner,
3237
repo: context.repo.repo,
33-
issue_number: issue.number,
38+
issue_number: item.number,
3439
labels: [label]
3540
});
3641
};

backend/Controllers/UserController.js

Lines changed: 82 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import bcrypt from "bcrypt";
22
import User from "../models/User.js";
33
import jwt from "jsonwebtoken";
4-
import dotenv from "dotenv"
4+
import dotenv from "dotenv";
55
import nodemailer from "nodemailer";
6-
dotenv.config()
6+
7+
dotenv.config();
78
/**
89
* @route {POST} /api/signup
910
* @description Create a new user
@@ -50,7 +51,7 @@ const getAllUserName = async (req, res) => {
5051
names.forEach((val) => nameArr.push(val.username));
5152
res.status(200).json({ usernames: nameArr, success: true });
5253
} catch (error) {
53-
console.log(error)
54+
console.log(error);
5455
res.status(404).json({ success: false, message: "Internal server error" });
5556
}
5657
};
@@ -84,13 +85,9 @@ const Login = async (req, res) => {
8485
.json({ success: false, message: "Incorrect Password" });
8586

8687
// If the password is correct, generate a JWT token
87-
const token = jwt.sign(
88-
{ userId: user._id },
89-
process.env.SECRET,
90-
{
91-
expiresIn: "30d",
92-
}
93-
);
88+
const token = jwt.sign({ userId: user._id }, process.env.SECRET, {
89+
expiresIn: "30d",
90+
});
9491
res.status(200).json({ success: true, user: user, token: token });
9592
} catch (error) {
9693
console.log(error);
@@ -107,23 +104,22 @@ const Login = async (req, res) => {
107104
*/
108105
const verifyUserByToken = async (req, res) => {
109106
try {
110-
const user = await User.findById(req.user.userId)
111-
return res.status(200).json({ success: true, user })
107+
const user = await User.findById(req.user.userId);
108+
return res.status(200).json({ success: true, user });
112109
} catch (error) {
113110
console.log(error);
114111
return res
115112
.status(404)
116113
.json({ success: false, message: "Internal Server Error" });
117114
}
118-
119-
}
115+
};
120116

121117
async function Sendcontactmail(req, res) {
122118
const { name, email, message, rating } = req.body; // Capture rating from the request
123119
console.log(req.body);
124120
try {
125121
const transporter = nodemailer.createTransport({
126-
service: 'gmail',
122+
service: "gmail",
127123
auth: {
128124
user: process.env.SMTP_EMAIL,
129125
pass: process.env.SMTP_PASSWORD,
@@ -132,8 +128,8 @@ async function Sendcontactmail(req, res) {
132128

133129
// Create a string of stars based on the rating, filled and unfilled stars
134130
const totalStars = 5;
135-
const filledStars = '★'.repeat(rating); // Filled stars
136-
const emptyStars = '☆'.repeat(totalStars - rating); // Empty stars
131+
const filledStars = "★".repeat(rating); // Filled stars
132+
const emptyStars = "☆".repeat(totalStars - rating); // Empty stars
137133

138134
const mailOptions = {
139135
from: email,
@@ -157,20 +153,85 @@ async function Sendcontactmail(req, res) {
157153

158154
await transporter.sendMail(mailOptions);
159155

160-
return res.status(200).json({ success: true, message: 'Message sent successfully!' });
156+
return res
157+
.status(200)
158+
.json({ success: true, message: "Message sent successfully!" });
161159
} catch (error) {
162-
console.error('Error sending email:', error);
163-
return res.status(500).json({ success: false, message: 'Error sending email' });
160+
console.error("Error sending email:", error);
161+
return res
162+
.status(500)
163+
.json({ success: false, message: "Error sending email" });
164164
}
165165
}
166+
const forgotPassword = async function (req, res) {
167+
const { email } = req.body;
168+
const user = await User.findOne({ email });
169+
try {
170+
if (!user) {
171+
return res
172+
.status(404)
173+
.json({ success: false, message: "Email doesnt exist" });
174+
} else {
175+
const token = jwt.sign({ userId: user._id }, process.env.SECRET, {
176+
expiresIn: "5m",
177+
});
178+
var transporter = nodemailer.createTransport({
179+
service: "gmail",
180+
auth: {
181+
user: process.env.SMTP_EMAIL,
182+
pass: process.env.SMTP_PASSWORD,
183+
},
184+
});
185+
var userFullName = user.firstName + " " + user.lastName;
186+
var mailOptions = {
187+
from: process.env.SMTP_EMAIL,
188+
to: email,
189+
subject: "Password Reset | TastyTrails",
190+
html: `<p>Hi <b> ${userFullName},</b><br>Use the below link to reset you password. Remember, the link will expire in 10 minutes.<br> ${process.env.FRONT_END_URL}/reset_password/${token}`,
191+
};
192+
193+
transporter.sendMail(mailOptions, function (error, info) {
194+
if (error) {
195+
return res
196+
.status(404)
197+
.json({ success: false, message: "Email not sent" });
198+
} else {
199+
return res
200+
.status(200)
201+
.json({ success: true, message: "Email sent succesfully" });
202+
}
203+
});
204+
}
205+
} catch (error) {
206+
console.log(error);
207+
}
208+
};
166209

210+
const resetPassword = async function (req, res) {
211+
const { token } = req.params;
212+
const { password } = req.body;
213+
try {
214+
const decoded = jwt.verify(token, process.env.SECRET);
215+
console.log(decoded);
216+
const id = decoded.userId;
217+
const hashPassword = await bcrypt.hash(password, 10);
218+
await User.findByIdAndUpdate({ _id: id }, { password: hashPassword });
219+
return res
220+
.status(200)
221+
.json({ success: true, message: "Password reset succesfully" });
222+
} catch (error) {
223+
return res.status(400).json({ success: false, message: "Invalid token" });
224+
}
225+
};
167226

168227
const UserController = {
169228
Signup,
170229
Login,
171230
getAllUserName,
172231
verifyUserByToken,
173-
Sendcontactmail
232+
forgotPassword,
233+
resetPassword,
234+
Sendcontactmail,
174235
};
175236

176237
export default UserController;

backend/package-lock.json

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/routes/web.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ router.post(
3131
RecipeController.addComment
3232
);
3333
router.post("/feedback", UserController.Sendcontactmail);
34+
router.post("/forgot_password", UserController.forgotPassword);
35+
router.post("/reset_password/:token", UserController.resetPassword);
3436
router.post("/recipe/like", authenticateToken, RecipeController.addRecipeLike);
3537
router.post(
3638
"/recipe/unlike",
@@ -43,5 +45,4 @@ router.delete(
4345
authenticateToken,
4446
RecipeController.deleteComment
4547
);
46-
4748
export default router;

backend/server.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,25 @@ const allowedOrigins = [
2121
/https:\/\/deploy-preview-\d+--delightful-daifuku-a9f6ea\.netlify\.app/,
2222
];
2323

24+
25+
app.use(
26+
cors({
27+
origin: function (origin, callback) {
28+
// Allow requests with no `origin` (like from Postman or server-side scripts)
29+
if (!origin || allowedOrigins.some((o) =>
30+
typeof o === "string" ? o === origin : o.test(origin)
31+
)) {
32+
callback(null, true);
33+
} else {
34+
// Provide a more informative error message if necessary
35+
callback(new Error("CORS policy: This origin is not allowed."));
36+
}
37+
},
38+
})
39+
);
40+
41+
// app.use(cors({origin:"http://localhost:5173"})) // for local use
42+
2443
app.use(
2544
cors({
2645
origin: function (origin, callback) {
@@ -42,6 +61,7 @@ app.use(
4261

4362
// app.use(cors({ origin: "http://localhost:5173" })) // for local use
4463

64+
4565
const collectDefaultMetrics = client.collectDefaultMetrics;
4666

4767
collectDefaultMetrics({ register: client.register });

frontend/.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# Not suggested modifying the backend port
22
VITE_BACKEND_URL="http://localhost:8080"
33
# Add your google client ID here
4-
VITE_GOOGLE_CLIENT_ID=""
4+
VITE_GOOGLE_CLIENT_ID=""

frontend/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@
1919
"axios": "^1.6.3",
2020
"install": "^0.13.0",
2121
"jwt-decode": "^4.0.0",
22+
"lucide-react": "^0.453.0",
2223
"react": "^18.2.0",
2324
"react-dom": "^18.2.0",
2425
"react-icons": "^5.3.0",
26+
"react-responsive": "^10.0.0",
2527
"react-router-dom": "^6.26.2",
2628
"react-toastify": "^9.1.3"
2729
},

frontend/src/App.jsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import UpdateRecipe from "./Pages/UpdateRecipe.jsx";
1919
import Contributors from "./Pages/Contributors.jsx"; // Import the Contributors component
2020
import PrivacyPolicy from "./Components/PrivacyPolicy.jsx";
2121
import NotFound from "./Pages/NotFound.jsx";
22+
import ResetPassword from "./Pages/ResetPassword.jsx";
23+
import ForgotPassword from "./Pages/ForgotPassword.jsx";
2224
import RecipeSuggestions from "./Pages/RecipeSuggestions.jsx";
2325

2426
function App() {
@@ -59,6 +61,8 @@ function App() {
5961
<Route path="/" element={<Landing />} />
6062
<Route path="/login" element={<Login />} />
6163
<Route path="/signup" element={<Signup />} />
64+
<Route path="/forgot_password" element={<ForgotPassword />} />
65+
<Route path="/reset_password/:token" element={<ResetPassword />} />
6266
<Route
6367
path="/recipes"
6468
element={<Recipes key={"recipes"} type="" />}

frontend/src/Components/Cards.jsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,9 @@ const Cards = ({ dish, setRecipes, recipes, index }) => {
130130
};
131131

132132
return (
133-
<div className="p-4">
134-
<div className="border-2 border-gray-200 border-opacity-60 rounded-lg overflow-hidden">
133+
134+
<div className="p-4 cursor-pointer" onClick={handleClick}>
135+
<div className="border-2 border-gray-200 border-opacity-60 rounded-lg overflow-hidden transform transition-transform duration-300 ease-in-out hover:scale-105 hover:shadow-lg">
135136
<img
136137
className="lg:h-48 md:h-36 w-full object-cover object-center cursor-pointer"
137138
src={dish.image}
@@ -185,7 +186,7 @@ const Cards = ({ dish, setRecipes, recipes, index }) => {
185186
};
186187

187188
Cards.propTypes = {
188-
dish: PropTypes.object.isRequired,
189+
dish: PropTypes.object.isRequired
189190
};
190191

191-
export default Cards;
192+
export default Cards;

0 commit comments

Comments
 (0)