Skip to content
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
5 changes: 4 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import ContactForm from "./pages/Contact";
import { DefaultCarousel } from "./components/Carousel/Carousel";
import UserList from "./pages/Users";
import { PostDetailsCard } from "./components/PostDetailsCard";

import ConfirmUnsubscribePage from './pages/UnsubscribePage';
import EmailVerificationPage from "./pages/EmailPage";
function App() {
return (
<div className="bg-cover bg-gray-200 h-screen w-screen overflow-y-scroll">
Expand All @@ -26,6 +27,8 @@ function App() {
<Route path="/contact" exact element={<ContactForm />} />
<Route path="/post/:id" exact element={<PostDetailsCard />} />
<Route path="/subscription" exact element={<SubscriptionPage />} />
<Route path="/confirm-unsubscribe" element={<ConfirmUnsubscribePage />} />
<Route path="/email" element={<EmailVerificationPage />} />
{/* Private routes */}
<Route element={<RequiresAuth allowedRoles={["moderator"]} />}>
<Route path="/admin" exact element={<HomePage />} />
Expand Down
1 change: 1 addition & 0 deletions src/components/Navbar/Location.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ export const useRouteVariables = () => {
isSubscribePage: location.pathname === "/subscription",
isDetailPage: location.pathname.startsWith("/post/"),
hideHomeLink: location.pathname.startsWith("/posts/"),
isEmailPage: location.pathname==="/email",
};
};
4 changes: 3 additions & 1 deletion src/components/Navbar/Navbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const Navbar = () => {
isSubscribePage,
isHomePage,
isContactPage,
isEmailPage,
} = useRouteVariables();
const { setAuth } = useAuth();

Expand Down Expand Up @@ -115,7 +116,8 @@ const Navbar = () => {
!isAdminPage &&
!isSubscribePage &&
location.pathname !== "/contact" &&
!isDetailPage && (
!isDetailPage &&
!isEmailPage && (
<Link
to="/admin"
className="px-4 py-2 mt-2 text-sm font-semibold bg-transparent rounded-lg dark-mode:bg-transparent dark-mode:hover:bg-gray-600 dark-mode:focus:bg-gray-600 dark-mode:focus:text-white dark-mode:hover:text-white dark-mode:text-gray-200 md:mt-0 md:ml-4 hover:text-gray-900 focus:text-gray-900 hover:bg-gray-200 focus:bg-gray-200 focus:outline-none focus:shadow-outline hover:underline"
Expand Down
18 changes: 18 additions & 0 deletions src/pages/EmailPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';

const EmailVerificationPage = () => {
return (
<div className="flex items-center justify-center h-screen bg-black">
<div className="bg-white p-8 rounded-lg shadow-md text-center">
<span className="text-5xl" role="img" aria-label="Emoji feliz">
📧
</span>
<h1 className="text-2xl font-semibold mb-2">¡Verify your email!</h1>
<p className="text-lg text-gray-700 mb-4">We have sent you a verification link.</p>
<p className="text-gray-600">Please check your inbox and click the link to continue.</p>
</div>
</div>
);
};

export default EmailVerificationPage;
31 changes: 23 additions & 8 deletions src/pages/SubscribePage.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
import React, { useState } from "react";
import React, { useState, useEffect } from "react";
import axios from "axios";
import { toast } from "react-hot-toast";
import { Link } from "react-router-dom";
import Cookies from "js-cookie";
import { useNavigate } from "react-router-dom";

export const SubscriptionPage = () => {
const [email, setEmail] = useState("");
const navigate = useNavigate();

useEffect(() => {
const storedEmail = Cookies.get("email");
if (storedEmail) {
setEmail(storedEmail);
}
}, []);
const handleSubscribe = async (e) => {
e.preventDefault();

Expand All @@ -24,7 +33,10 @@ export const SubscriptionPage = () => {

if (response.status === 200) {
toast.success("Subscription successful!");
setEmail("");
} else if (response.status === 202) {
toast("I know you are excited but you are already subscribed!", {
icon: "😃",
});
} else {
toast.error("Failed to subscribe");
}
Expand All @@ -47,15 +59,18 @@ export const SubscriptionPage = () => {

try {
const response = await axios.post(
"http://localhost:4000/api/users/unsubscribe",
"http://localhost:4000/api/users/email-unsubscribe",
{
email: email,
}
);

if (response.status === 200) {
toast.success("Unsubscribe successful!");
setEmail("");
navigate("/email");
} else if (response.status === 202) {
toast("You are no longer subscribed, please stop trying.", {
icon: "🤷‍♂️",
});
} else {
toast.error("Failed to unsubscribe");
}
Expand Down Expand Up @@ -87,9 +102,8 @@ export const SubscriptionPage = () => {
Do you want to receive notifications when there is a new post?
</div>
<p className="text-sm md:text-base">
Enter your email address to which you wish to receive notifications
from us. If you are already subscribed and want to unsubscribe,
enter your email and click on the unsubscribe button.
If you subscribe and then want to unsubscribe you have to verify
your email (you can only subscribe your email in session)
</p>
</div>
<div className="flex flex-col mt-8">
Expand All @@ -100,6 +114,7 @@ export const SubscriptionPage = () => {
required
value={email}
onChange={(e) => setEmail(e.target.value)}
readOnly={true}
className="bg-transparent border-2 rounded-full py-4 px-6 text-[16px] leading-[22.4px] font-light placeholder:text-white text-white"
placeholder="E-mail Address"
/>
Expand Down
34 changes: 34 additions & 0 deletions src/pages/UnsubscribePage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React, { useEffect } from "react";
import axios from "axios";
import toast from "react-hot-toast";
const UnsubscribeSuccessPage = () => {
useEffect(() => {
const params = new URLSearchParams(window.location.search);
const email = params.get("email");

axios
.post("http://localhost:4000/api/users/unsubscribe", { email })
.then((response) => {})
.catch((error) => {
toast.error(error);
});
}, []);

return (
<div className="flex items-center justify-center h-screen bg-black dark:bg-gray-900">
<div className="w-full md:max-w-[510px] mx-auto px-4">
<div className="text-white text-center mt-4">
<div className="font-semibold text-2xl pb-4">
Unsubscribe Successful
</div>

<p className="text-sm md:text-base">
You have been unsubscribed successfully.
</p>
</div>
</div>
</div>
);
};

export default UnsubscribeSuccessPage;