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

Added Newsletter Service #39

Merged
merged 2 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
**/.env
**/.DS_Store
**/node_modules
16 changes: 16 additions & 0 deletions my-app/package-lock.json

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

1 change: 1 addition & 0 deletions my-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"react-carousel-minimal": "^1.3.4",
"react-dom": "^18.1.0",
"react-helmet": "^6.1.0",
"react-icons": "^5.3.0",
"react-router-dom": "^6.3.0",
"react-scripts": "5.0.1",
"react-secure-storage": "^1.2.2",
Expand Down
13 changes: 11 additions & 2 deletions my-app/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,24 @@ import Community from "./pages/Community";
import ContactForm from "./pages/Contact";
import Events from "./pages/Events";
import Base from "./layouts/Base";
import Subscribe from "./components/Subscribe";
import { useState } from "react";

export default function App() {
const [isVisible, setIsVisible] = useState(false);

const handleSetVisible = (value)=>{
setIsVisible(value);
};

return (
<div className="bg-primary">
{isVisible&&<Subscribe handle={handleSetVisible} />}
<BrowserRouter>
<Base>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about-us" element={<About />} />
<Route path="/" element={<Home handle={handleSetVisible} />} />
<Route path="/about-us" element={<About handle={handleSetVisible} />} />
<Route path="/community" element={<Community />} />
<Route path="/events" element={<Events />} />
<Route path="/contact-us" element={<ContactForm />} />
Expand Down
13 changes: 6 additions & 7 deletions my-app/src/components/Newsletter.jsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import React from "react";
import siteConfig from "../site.config";

export default function Newsletter() {
export default function Newsletter(props) {
return (
<>
<section className="py-16 lg:py-32 bg-[#0c1b38]">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="max-w-xl mx-auto text-center">
<h1 className="text-4xl tracking-tight font-extrabold text-pastel sm:text-5xl mb-8">
Join our monthly newsletter
</h1>
<a
href={siteConfig.newsletterUrl}
<button
className="w-full max-w-sm mx-auto flex items-center justify-center px-8 py-2 border border-transparent text-lg font-semibold rounded-lg text-slate-800 bg-secondary hover:scale-105 will-change-transform transition-transform md:py-4 md:text-lg md:px-10"
target="_blank"
rel="noreferrer"
onClick={()=>props.handle(true)}
>
Subscribe
</a>
</button>
</div>
</div>
</section>
</>
);
}
128 changes: 128 additions & 0 deletions my-app/src/components/Subscribe.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import React, { useState } from 'react'
import Toastify from "toastify-js";
import "toastify-js/src/toastify.css";
import { RxCross2 } from "react-icons/rx";
import {motion} from "framer-motion";
import { API_URL } from '../lib/constants';

const Subscribe = (props) => {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [reg, setReg] = useState("");

const handleSend = async () => {
if (name === "" || email === "" || reg === "") {
Toastify({
text: "Form can't be empty!",
duration: 3000,
backgroundColor: "#56ccf2",
stopOnFocus: true,
position: "right",
}).showToast();
return;
}

try {
const response = await fetch(`${API_URL}/subscribe/subscribe`, {
method: "POST",
body: JSON.stringify({
name: name,
email: email,
reg: reg,
}),
headers: {
"Content-type": "application/json; charset=UTF-8",
},
});

if (response.status === 200) {
const result = await response.json(); // Assuming the response is in JSON format
Toastify({
text: result.message || "Subscription successful!", // Adjust according to your API response
duration: 3000,
backgroundColor: "#56ccf2",
stopOnFocus: true,
position: "right",
}).showToast();
setName("");
setEmail("");
setReg("");
props.handle(false);
} else {
Toastify({
text: "Something went wrong!",
duration: 3000,
backgroundColor: "#ff0000",
stopOnFocus: true,
position: "right",
}).showToast();
}
} catch (err) {
console.error(err);
Toastify({
text: "An error occurred!",
duration: 3000,
backgroundColor: "#ff0000",
stopOnFocus: true,
position: "right",
}).showToast();
}
};


return (
<div
className='bg-black/10 backdrop-blur-xl flex justify-center align-middle text-white fixed h-screen w-screen z-50'>
<motion.div
initial={{opacity: 0, scale: 0.8}}
animate={{opacity: 1, scale: 1}}
transition={{duration: 0.2}}
className='m-auto w-5/6 md:w-full'>
<div className='flex justify-end md:w-1/2 mx-auto'>
<RxCross2 onClick={()=> props.handle(false)} size={32} className="cursor-pointer hover:scale-[1.2] a" />
</div>
<h1 className='text-4xl text-center my-4'>Subscribe to Our Newsletter</h1>
<div className="grid grid-cols-1 gap-6 lg:w-1/2 mx-auto">
<label className="block">
<span className="text-slate-400">Full name</span>
<input
type="text"
className="mt-1 block w-full rounded-md border-secondary text-pastel shadow-sm focus:border-secondary focus:ring focus:ring-secondary focus:ring-opacity-50 bg-primary"
placeholder="John Doe"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</label>
<label className="block">
<span className="text-slate-400">Email address</span>
<input
type="email"
className="mt-1 block w-full rounded-md border-secondary shadow-sm text-pastel focus:border-secondary focus:ring focus:ring-secondary focus:ring-opacity-50 bg-primary"
placeholder="john@google.com"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</label>
<label className="block">
<span className="text-slate-400">Registration Number</span>
<input
type="text"
className="mt-1 block w-full rounded-md border-secondary shadow-sm text-pastel focus:border-secondary focus:ring focus:ring-secondary focus:ring-opacity-50 bg-primary"
placeholder="214100****"
value={reg}
onChange={(e) => setReg(e.target.value)}
/>
</label>
<button
onClick={handleSend}
className="w-full mx-auto flex items-center justify-center px-8 py-2 border border-transparent text-lg font-semibold rounded-lg text-slate-800 bg-secondary hover:scale-105 will-change-transform transition-transform md:py-3 md:text-lg md:px-10"
>
Subscribe
</button>
</div>
</motion.div>
</div>
)
}

export default Subscribe
17 changes: 17 additions & 0 deletions my-app/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,23 @@ body{
background-color: #0d1026
}

.a{
transition: all 0.4s;
}

html {
overflow: scroll;
overflow-x: hidden;
}
::-webkit-scrollbar {
width: 0; /* Remove scrollbar space */
background: transparent; /* Optional: just make scrollbar invisible */
}
/* Optional: show position indicator in red */
::-webkit-scrollbar-thumb {
background: #131313;
}

@tailwind components;
@tailwind utilities;

11 changes: 4 additions & 7 deletions my-app/src/pages/About.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React from "react";
import GroupMembers from "../assets/images/about2.png";
import siteConfig from "../site.config";

const About = () => {
const About = (props) => {
return (
<section className="pb-12">
<div className="flex items-center justify-center">
Expand Down Expand Up @@ -30,14 +29,12 @@ const About = () => {
<h2 className="mb-6 text-3xl text-center tracking-tight font-bold sm:text-4xl text-white mt-28">
Join our monthly newsletter
</h2>
<a
href={siteConfig.newsletterUrl}
<button
onClick={()=>props.handle(true)}
className="w-full max-w-xs mx-auto flex items-center justify-center px-8 py-2 border border-transparent text-lg font-semibold rounded-lg text-slate-800 bg-secondary hover:scale-105 will-change-transform transition-transform md:py-3 md:text-lg md:px-4"
target="_blank"
rel="noreferrer"
>
Subscribe
</a>
</button>
</div>
</div>
</section>
Expand Down
4 changes: 2 additions & 2 deletions my-app/src/pages/Home.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import Newsletter from "../components/Newsletter";
import Statistics from "../components/Statistics";
import Testimonial from "../components/Testimonial";

const Home = () => {
const Home = (props) => {
return (
<>
<Hero />
<Statistics />
<Testimonial />
<Newsletter />
<Newsletter handle={props.handle} />
</>
);
};
Expand Down
6 changes: 3 additions & 3 deletions my-app/src/site.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ const siteConfig = {
titleTemplate: "%s - Codex",
description: shared.description,
stats: {
members: 100,
commits: 2.1,
projects: 35,
members: 120,
commits: 2.3,
projects: 38,
workshops: 18,
},
newsletterUrl: "https://docs.google.com/forms/d/e/1FAIpQLSdOp_wsPsjwFvxhSRECAxBsUGeL2s4cjJ1SghNLgNPg7f8bHQ/viewform",
Expand Down
54 changes: 54 additions & 0 deletions package-lock.json

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

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"react-icons": "^5.3.0"
}
}