Skip to content

Commit

Permalink
Merge branch 'VaibhavArora314:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
Prabhatyadav60 authored Jul 7, 2024
2 parents 4e40c48 + 10a7e38 commit ab9187c
Show file tree
Hide file tree
Showing 24 changed files with 337 additions and 127 deletions.
60 changes: 60 additions & 0 deletions admin/src/components/CaptchaAdmin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { useState, useEffect } from 'react';
import { IoMdRefresh } from "react-icons/io";

const CaptchaAdmin = ({ onChange }: { onChange: (isValid: boolean) => void }) => {
const [captchaText, setCaptchaText] = useState('');
const [inputValue, setInputValue] = useState('');
const [isCaptchaValid, setIsCaptchaValid] = useState(false);

useEffect(() => {
generateCaptcha();
}, []);

const generateCaptcha = () => {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let text = '';
for (let i = 0; i < 6; i++) {
text += chars.charAt(Math.floor(Math.random() * chars.length));
}
setCaptchaText(text);
};

const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(e.target.value);
if (e.target.value === captchaText) {
setIsCaptchaValid(true);
onChange(true);
} else {
setIsCaptchaValid(false);
onChange(false);
}
};

return (
<div className="mb-4 rounded-lg">
<div className="flex items-center justify-between mb-4 text-[#000435] bg-gray-100 dark:text-white dark:bg-blue-950 p-2 rounded-lg border border-[#5f67de] dark:border-white">
<span className="text-xl font-semibold italic line-through">{captchaText}</span>
<button
type="button"
onClick={generateCaptcha}
className="bg-blue-500 text-white p-1 rounded-lg hover:bg-blue-600"
>
<IoMdRefresh size={23} />
</button>
</div>
<input
type="text"
className="form-input mt-1 p-2 block w-full text-[#000435] bg-white dark:text-white dark:bg-[#000453] rounded-lg border border-[#5f67de] dark:border-white"
placeholder="Enter captcha"
value={inputValue}
onChange={handleInputChange}
required
/>
{!isCaptchaValid && inputValue && (
<p className="text-sm font-semibold mt-2 text-red-600 text-center">Captcha does not match</p>
)}
</div>
);
};

export default CaptchaAdmin;
14 changes: 10 additions & 4 deletions admin/src/pages/Signin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ import { tokenState } from "../store/atoms/auth";
import { AiOutlineEyeInvisible, AiOutlineEye } from "react-icons/ai";
import toast from "react-hot-toast";
import bgHero from "../assets/bgHero.png";
import CaptchaAdmin from "../components/CaptchaAdmin";

const Signin = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [showPassword, setShowPassword] = useState(false);

const [isCaptchaValid, setIsCaptchaValid] = useState(false);
const [error, setError] = useState({
email: "",
password: "",
Expand All @@ -20,11 +21,16 @@ const Signin = () => {
const setTokenState = useSetRecoilState(tokenState);
const navigate = useNavigate();

document.title='Style Share | Login page 👋'
document.title='Style Share | Login page 👋'

const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();

if (!isCaptchaValid) {
toast.error('Captcha is not valid');
return;
}

try {
const response = await axios.post("/api/v1/admin/login", {
email,
Expand Down Expand Up @@ -99,12 +105,12 @@ const Signin = () => {
<AiOutlineEye fontSize={24} fill="#AFB2BF" />
)}
</span>
</label>

</label>
<p className="text-sm font-semibold mb-2 text-red-600">
{error.password}
</p>
</div>
<CaptchaAdmin onChange={(isValid) => setIsCaptchaValid(isValid)} />
<div className="flex justify-center">
<button
type="submit"
Expand Down
8 changes: 4 additions & 4 deletions backend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"license": "ISC",
"dependencies": {
"@google/generative-ai": "^0.13.0",
"@prisma/client": "^5.14.0",
"@prisma/client": "^5.16.1",
"@types/bcrypt": "^5.0.2",
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
Expand Down
61 changes: 61 additions & 0 deletions backend/src/helpers/mail/ContactUsMail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import nodeMailer from 'nodemailer'
export const mailing=async (email: string, message: string) =>{
let HTML=`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<main style="width: 100%;min-height: 100vh;padding: 1rem;background-color: rgb(255 255 80 / 47%);position: relative;">
<div style="margin: auto;width:90%;background-color: white;max-width: 800px;padding: 1.2rem;border-radius: 0.6rem; box-shadow: 0 1px 5px rgb(0,0,0);position: relative;justify-content: center;align-items: center;">
<h1 style="margin-top: 2rem;font-family: monospace;">Thank You for Contacting Us!</h1>
<p style="margin-top: 2rem; font-family: sans-serif;font-size: 1rem;">
<span style="margin-top: 2rem; font-family: sans-serif;font-size: 1rem;"><span style="font-weight:700;">Your Message:</span> ${message}</span><br><br>
Thank you for reaching out to Style Share! Your message is important to us, and we are grateful for your interest. Our team is currently reviewing your inquiry and will respond to you as soon as possible.
<br><br>
In the meantime, feel free to explore more about Style Share on our website. You can browse through our latest articles, explore our featured styles, or connect with us on social media for daily inspiration.
<br><br>
Your feedback is valuable to us as we strive to provide the best experience for our community of style enthusiasts. We look forward to connecting with you soon!
<br><br>
Thank you again for choosing Style Share. Stay stylish and inspired!
<br><br>
Warm regards,<br>
The Style Share Team<br><br>
</p>
<p style="font-family: monospace;font-weight: 700;">Keep connected with our site <a href="https://style-share.vercel.app/app">https://style-share.vercel.app/app</a>...🚀 for updates and more style tips!</p>
<br><br>
<p style="font-family: monospace;text-align: center;">Happy Coding :) Happy Journey :)</p>
</div>
</main>
</body>
</html>
`
const sender=nodeMailer.createTransport({
service:"Gmail",
auth:{
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASS,
},
})
const html= HTML
const receiver={
from:process.env.EMAIL_USER,
to:email,
subject:"Contact Our Team",
text:'Style Share Contact',
html:html,
}
const sendMail=async()=>{
try{
await sender.sendMail(receiver)
console.log("sended")
}catch(err){
console.log(err)
}
}

sendMail()
}
5 changes: 5 additions & 0 deletions backend/src/routes/post/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,11 @@ export const getPostsWithPagination = async (req: Request, res: Response) => {
},
tags.length > 0 ? { tags: { hasSome: tags } } : {}
]
},
orderBy: {
reactions: {
_count: "desc"
}
}
});
res.status(200).json({
Expand Down
2 changes: 1 addition & 1 deletion backend/src/routes/post/zodSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import zod from "zod";
export const createPostSchema = zod.object({
title: zod.string().min(3).max(30),
description: zod.string().min(3).max(200),
codeSnippet: zod.string().min(3).max(5000),
codeSnippet: zod.string().min(3).max(10000),
jsCodeSnippet: zod.string().min(0).max(5000).optional().default(""),
tags: zod.array(zod.string().min(2).max(20)).min(1).max(5),
});
13 changes: 8 additions & 5 deletions backend/src/routes/user/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import { UserAuthRequest } from "../../helpers/types";
import crypto from "crypto";
import { sendVerificationEmail } from "../../helpers/mail/sendOtpMail";
import { sendWelcomeEmail } from "../../helpers/mail/sendWelcomeMail";

import { date } from "zod";
import{ mailing} from "../../helpers/mail/ContactUsMail";
export const userSignupController = async (req: Request, res: Response) => {
try {
const payload = req.body;
Expand Down Expand Up @@ -371,8 +372,7 @@ export const verifyOtpController = async (
export const contactUsController = async (req: Request, res: Response) => {
try {
const payload = req.body;
const result = contactUsSchema.safeParse(payload);

const result = contactUsSchema.safeParse(payload);
if (!result.success) {
const formattedError: any = {};
result.error.errors.forEach((e) => {
Expand All @@ -392,8 +392,11 @@ export const contactUsController = async (req: Request, res: Response) => {
subject: data.subject,
message: data.message,
}
});

});
if (result.data?.email && result.data?.message) {
await mailing(result.data.email, result.data.message);
}

res.status(201).json({
message: "Your message has been received. We will get back to you shortly.",
contactMessage,
Expand Down
60 changes: 60 additions & 0 deletions frontend/src/components/CaptchaUser.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { useState, useEffect } from 'react';
import { IoMdRefresh } from "react-icons/io";

const CaptchaUser = ({ onChange }: { onChange: (isValid: boolean) => void }) => {
const [captchaText, setCaptchaText] = useState('');
const [inputValue, setInputValue] = useState('');
const [isCaptchaValid, setIsCaptchaValid] = useState(false);

useEffect(() => {
generateCaptcha();
}, []);

const generateCaptcha = () => {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let text = '';
for (let i = 0; i < 6; i++) {
text += chars.charAt(Math.floor(Math.random() * chars.length));
}
setCaptchaText(text);
};

const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(e.target.value);
if (e.target.value === captchaText) {
setIsCaptchaValid(true);
onChange(true);
} else {
setIsCaptchaValid(false);
onChange(false);
}
};

return (
<div className="mb-4 rounded-lg">
<div className="flex items-center justify-between mb-4 text-[#000435] bg-gray-100 dark:text-white dark:bg-blue-950 p-2 rounded-lg border border-[#5f67de] dark:border-white">
<span className="text-xl font-semibold italic line-through">{captchaText}</span>
<button
type="button"
onClick={generateCaptcha}
className="bg-blue-500 text-white p-1 rounded-lg hover:bg-blue-600"
>
<IoMdRefresh size={23} />
</button>
</div>
<input
type="text"
className="form-input mt-1 p-2 block w-full text-[#000435] bg-white dark:text-white dark:bg-[#000453] rounded-lg border border-[#5f67de] dark:border-white"
placeholder="Enter captcha"
value={inputValue}
onChange={handleInputChange}
required
/>
{!isCaptchaValid && inputValue && (
<p className="text-sm font-semibold mt-2 text-red-600 text-center">Captcha does not match</p>
)}
</div>
);
};

export default CaptchaUser;
7 changes: 4 additions & 3 deletions frontend/src/hooks/usePosts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const usePosts = ({ initialPage = 1, pageSize = 12 }: Props) => {
const initialTags = tagsFromParams ? tagsFromParams.split(",") : [];
setTags(initialTags);
fetchPosts(page, pageSize, searchQuery, initialTags);
}, [page, searchQuery, searchParams]);
}, [page, searchParams]);

const handlePreviousPage = () => {
if (page > 1) {
Expand Down Expand Up @@ -95,8 +95,9 @@ const usePosts = ({ initialPage = 1, pageSize = 12 }: Props) => {
removeTag,
searchQuery,
setSearchQuery,
tags
tags,
fetchPosts
};
};

export default usePosts;
export default usePosts;
2 changes: 1 addition & 1 deletion frontend/src/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@
"copy1":"Copyright ",
"copy2":"Style Share"
},
"PostHeading":"Recent Posts Added",
"PostHeading":"Popular Posts",
"allPosts":{
"Posts":"Posts",
"search":"🔍 Search anything",
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/locales/guj/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@
"copy1": "કૉપીરાઇટ ",
"copy2": "સ્ટાઇલ શેર"
},
"PostHeading": "તાજેતરના પોસ્ટ્સ ઉમેરી દીધા છે",
"PostHeading": "પ્રખ્યાત પોસ્ટ્સ",
"allPosts": {
"Posts": "પોસ્ટ્સ",
"search": "🔍 શોધો કંઈપણ",
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/locales/hi/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@
"copy1": "कॉपीराइट ",
"copy2": "स्टाइल शेयर"
},
"PostHeading": "हाल के जोड़ी गई पोस्ट",
"PostHeading": "लोकप्रिय पोस्ट",
"allPosts": {
"Posts": "पोस्ट्स",
"search": "🔍 कुछ भी खोजें",
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/locales/mh/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@
"copy1":"कॉपीराइट ",
"copy2":"स्टाइल सामायिकी"
},
"PostHeading":"नवीनतम पोस्ट्स जोडले गेले",
"PostHeading":"लोकप्रिय पोस्ट",
"allPosts":{
"Posts":"पोस्ट्स",
"search":"🔍 काहीही शोधा",
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/locales/tam/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@
"copy1": "பதிப்புரிமை ",
"copy2": "ஸ்டைல் பகிர்வு"
},
"PostHeading": "சமீபத்திய பதிவுகள் சேர்க்கப்பட்டது",
"PostHeading": "பிரபலமான பதிவுகள்",
"allPosts": {
"Posts": "பதிவுகள்",
"search": "🔍 என்னையும் தேடு",
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/locales/tel/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@
"copy1": "ప్రత్యేకస్వాధీనం ",
"copy2": "శైలి షేర్"
},
"PostHeading": "తాజా పోస్టులు చేర్చబడినవి",
"PostHeading": "ప్రముఖ పోస్టులు",
"allPosts": {
"Posts": "పోస్టులు",
"search": "🔍 ఏదైనా శోధించండి",
Expand Down
Loading

0 comments on commit ab9187c

Please sign in to comment.