Skip to content

Commit

Permalink
Merge pull request #119 from she-code-africa/enquiry-p
Browse files Browse the repository at this point in the history
feat(enquiry page): build the UI for contact us page.
  • Loading branch information
Lezette authored May 6, 2024
2 parents c6b1a8d + 6fe4ce4 commit 8e45c3f
Show file tree
Hide file tree
Showing 9 changed files with 287 additions and 24 deletions.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"@fortawesome/free-regular-svg-icons": "^6.1.0",
"@fortawesome/free-solid-svg-icons": "^6.1.0",
"@fortawesome/react-fontawesome": "^0.1.18",
"@hookform/resolvers": "^3.3.4",
"@tanstack/react-query": "^4.29.25",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^12.0.0",
Expand All @@ -26,6 +27,7 @@
"react-ga4": "^2.1.0",
"react-google-recaptcha-v3": "^1.10.1",
"react-helmet-async": "^1.3.0",
"react-hook-form": "^7.51.4",
"react-lazy-load-image-component": "^1.5.6",
"react-router": "^6.2.1",
"react-router-dom": "^6.2.1",
Expand All @@ -36,7 +38,8 @@
"serve": "^14.2.1",
"slick-carousel": "^1.8.1",
"tailwindcss": "^3.0.18",
"web-vitals": "^2.1.0"
"web-vitals": "^2.1.0",
"yup": "^1.4.0"
},
"scripts": {
"start": "serve -s build",
Expand Down
6 changes: 4 additions & 2 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,11 @@ import "./styles/app.scss";
import PrivateRoutes from "./components/PrivateRoutes";
import AcademyPage from "./pages/Academy/_slug";
import LandingPage from "./pages/Academy";
import ContactUs from "./pages/ContactUs";

const queryClient = new QueryClient();

function App () {
function App() {
const { pathname } = useLocation();
React.useEffect(() => {
window.scrollTo(0, 0);
Expand All @@ -59,7 +60,7 @@ function App () {
);
}

function Routes (params) {
function Routes(params) {
return (
<Switch>
<Route path={paths.home} element={<Home />} />
Expand Down Expand Up @@ -89,6 +90,7 @@ function Routes (params) {
<Route path={paths.initiatives} element={<Initiatives />} />
<Route path={paths.hire} element={<Hire />} />
<Route path={paths.community} element={<Community />} />
<Route path={paths.contactUs} element={<ContactUs />} />
<Route path="*" element={<PageNotFound />} />
<Route path="/jobs" element={<PrivateRoutes />}>
<Route path={paths.post_job} element={<PostJob />} />
Expand Down
49 changes: 49 additions & 0 deletions src/components/ContactUs/inputs/PrimaryInput.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from "react";

const PrimaryInput = ({
label,
name,
type,
placeholder,
register,
errors,
isRequired = true,
}) => {
return (
<div className="w-full md:max-w-[455px] mb-6">
<label
htmlFor={name}
className="text-base capitalize font-medium text-[rgba(46,52,79,1)]"
>
{label}
</label>

<div
className={`w-full rounded-md border border-gains h-[50px] overflow-hidden mt-2 ${
errors && "border-primary-main-pink"
}`}
>
{isRequired ? (
<input
type={type}
placeholder={placeholder}
{...register(name)}
className="text-base w-full h-full border-0 outline-none px-3 bg-white placeholder:text-[rgba(130,130,130,1)]"
/>
) : (
<input
type={type}
placeholder={placeholder}
className="text-base w-full h-full border-0 outline-none px-3 bg-white placeholder:text-[rgba(130,130,130,1)]"
/>
)}
</div>

<p className="text-primary-main-pink text-sm">
{errors && errors?.message}
</p>
</div>
);
};

export default PrimaryInput;
21 changes: 14 additions & 7 deletions src/components/Footer/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,20 +81,21 @@ const Footer = () => {
<span>Annual Reports</span>
<FontAwesomeIcon
icon={faCaretDown}
className={`transition-transform duration-300 ${openCaret ? "rotate-180" : null
}`}
className={`transition-transform duration-300 ${
openCaret ? "rotate-180" : null
}`}
/>
</button>
{openCaret && (
<ul className="bg-white shadow-[0px_0px_8px_2px_rgba(0,0,0,0.20)] w-40 px-2 py-3 rounded absolute max-h-[120px] overflow-y-auto">
{reports.map((report) => (
<li
key={report._id}
className="hover:bg-gray-200 p-2">
<a href={report?.link}
<li key={report._id} className="hover:bg-gray-200 p-2">
<a
href={report?.link}
target="_blank"
rel="noreferrer"
className="focus:outline-none focus:ring focus:ring-tutu block">
className="focus:outline-none focus:ring focus:ring-tutu block"
>
{report.year}
</a>
</li>
Expand Down Expand Up @@ -150,6 +151,12 @@ const Footer = () => {
>
Upcoming Events
</Link>
<Link
to={paths.contactUs}
className="block mb-5 hover:text-primary-main-pink focus:outline-none focus:ring focus:ring-tutu"
>
Contact Us
</Link>
<a
href="https://bit.ly/joinshecodeafrica"
target="_blank"
Expand Down
32 changes: 19 additions & 13 deletions src/pages/CoC/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ const CodeOfConduct = () => {
<div className="code-of-conduct">
<p>
<span className="font-weight-bolder">She Code Africa (SCA)</span>{" "}
is dedicated to providing a harassment-free experience for African women and girls,
regardless of gender, gender identity and expression,
sexual orientation, disability, physical appearance, body size,
age, or religion. We do not tolerate harassment of
is dedicated to providing a harassment-free experience for African
women and girls, regardless of gender, gender identity and
expression, sexual orientation, disability, physical appearance,
body size, age, or religion. We do not tolerate harassment of
participants in any form. This code of conduct applies to all She
Code Africa spaces, including Slack, both online and off. Anyone
who violates this code of conduct may be sanctioned or expelled
Expand All @@ -69,10 +69,17 @@ const CodeOfConduct = () => {
ban from the community.
</p>
<p>
If you believe someone is violating the code of conduct, we ask that
you report it by emailing&nbsp;
If you believe someone is violating the code of conduct, we ask
that you report it by emailing&nbsp;
<strong className="font-weight-bolder">
<a href="mailto:[email protected]" target="_blank" rel="noreferrer" className="focus:outline-none focus:ring focus:ring-tutu">[email protected]</a>
<a
href="mailto:[email protected]"
target="_blank"
rel="noreferrer"
className="focus:outline-none focus:ring focus:ring-tutu"
>
[email protected]
</a>
</strong>
. For more details please see our Reporting Guidelines .
<br />
Expand All @@ -92,8 +99,8 @@ const CodeOfConduct = () => {
<li>
Offensive comments related to gender, gender identity and
expression, sexual orientation, disability, mental illness,
neuro(a)typicality, physical appearance, body size, age,
or religion.
neuro(a)typicality, physical appearance, body size, age, or
religion.
</li>
<li>
Unwelcome comments regarding a person's lifestyle choices and
Expand Down Expand Up @@ -151,8 +158,7 @@ const CodeOfConduct = () => {
</strong>
<ul className="pl-10">
<li>
“Reverse”-isms, including “reverse sexism,”
and “cisphobia.”
“Reverse”-isms, including “reverse sexism,” and “cisphobia.”
</li>
<li>
Reasonable communication of boundaries, such as “leave me
Expand All @@ -163,8 +169,8 @@ const CodeOfConduct = () => {
focusing on responding to the content or disengaging instead)
</li>
<li>
Criticizing sexist, cissexist, or otherwise oppressive
behavior or assumptions
Criticizing sexist, cissexist, or otherwise oppressive behavior
or assumptions
</li>
</ul>
<strong>
Expand Down
159 changes: 159 additions & 0 deletions src/pages/ContactUs/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import React from "react";
import { Helmet } from "react-helmet-async";
import Header from "../../components/Header";
import Footer from "../../components/Footer";
import PrimaryInput from "../../components/ContactUs/inputs/PrimaryInput";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as yup from "yup";
import { toast } from "react-toastify";
import { useMutation } from "@tanstack/react-query";
import { mutateEnquires } from "../../services";

const ContactUsPage = () => {
const schema = yup
.object({
fullName: yup.string().required("Please enter your name"),
email: yup
.string()
.email("Please enter a valid email address.")
.required("Please enter your email address."),
description: yup.string().required("Please enter your message."),
})
.required();

const {
register,
handleSubmit,
formState: { errors },
} = useForm({
resolver: yupResolver(schema),
});
const { mutate: handleContactUs } = useMutation(mutateEnquires, {
onSuccess: (data) => {
toast.success("Message sent Successfully!", {
position: toast.POSITION.TOP_RIGHT,
});
},
onError: (error, variables) => {
toast.error("An error occurred.", {
position: toast.POSITION.TOP_RIGHT,
});
},
});
const onsubmit = (data) => handleContactUs(data);
return (
<>
<Helmet>
<meta charSet="utf-8" />
<title>Contact Page</title>
<meta
name="description"
content="Get free access to events focused on empowering and getting more young girls and women into technology across cities and tertiary institutions in Africa."
/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta property="og:title" content="Events" />
<meta
property="og:description"
content="Get free access to events focused on empowering and getting more young girls and women into technology across cities and tertiary institutions in Africa."
/>
<meta name="twitter:title" content="Events" />
<meta
name="twitter:description"
content="Get free access to events focused on empowering and getting more young girls and women into technology across cities and tertiary institutions in Africa."
/>
</Helmet>
<Header />
<main className=" text-secondary-main-black">
<section className=" bg-primary-main-pink pt-16 md:pt-24 lg:pt-28">
<div className="w-90 mx-auto min-h-[541px] flex flex-col justify-center 2md:justify-between 2md:flex-row md:items-center event-hero gap-8 py-12 2md:py-0 px-3 sm:px-0 star-bg">
<div className="w-full max-w-[832px] mx-auto">
<h1 className="hero-heading capitalize font-bold text-[32px] md:text-[36px] 2md:text-[40px] text-center leading-[150%] mx-auto text-white">
contact us
</h1>

<p className="text-base md:text-lg mt-4 text-center text-white font-medium w-[85%] lg:w-full lg:max-w-[676px] mx-auto">
Thank you for your interest in She Code Africa.
</p>
<p className="text-base md:text-lg text-center text-white font-medium w-[85%] lg:w-full lg:max-w-[676px] mx-auto">
Reach out to us. Send an email to{" "}
<a href="mailto:[email protected]" className="font-bold">
[email protected]
</a>{" "}
or fill the form below and send. If you would like to support
our mission, please see our “partner with us” section.
</p>
</div>
</div>
</section>

<section className="w-[90%] max-w-[900px] mx-auto mt-10 md:mt-12">
<form className="w-full" onSubmit={handleSubmit(onsubmit)}>
<div className="flex flex-col md:flex-row gap-5 md:gap-20">
<div className="w-full md:w-[50%]">
<PrimaryInput
register={register}
label="name"
name="fullName"
placeholder="Enter your name"
type="text"
errors={errors.fullName}
/>
<PrimaryInput
register={register}
label="email address"
name="email"
placeholder="Enter your email address"
type="email"
errors={errors.email}
/>
<PrimaryInput
isRequired={false}
label="enter subject"
name="subject"
placeholder="What is the subject of this message"
type="text"
/>
</div>

<div className="w-full md:w-[50%]">
<label
htmlFor="message"
className="text-base capitalize font-medium text-[rgba(46,52,79,1)]"
>
enter message
</label>
<div
className={`w-full md:max-w-[549px] h-[290px] mt-2 rounded-md border border-gains overflow-hidden ${
errors.description?.message && "border-primary-main-pink"
}`}
>
<textarea
{...register("description")}
name="description"
placeholder="Write your message"
className="text-base w-full h-full border-0 outline-none p-3 bg-white placeholder:text-[rgba(130,130,130,1)] resize-none"
></textarea>
</div>
<p className="text-primary-main-pink text-sm">
{errors.description?.message}
</p>
</div>
</div>

<div className="flex md:justify-end w-full">
<div className="mt-5 md:mt-8 w-full max-w-[177px] rounded-[30px] h-[56px] overflow-hidden bg-primary-main-pink">
<button className="w-full h-full text-white capitalize">
send message
</button>
</div>
</div>
</form>
</section>
</main>
<Footer />
</>
);
};

export default ContactUsPage;
1 change: 1 addition & 0 deletions src/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export const paths = {
hire: "/hire",
leadChapter: "/chapters/form",
community: "/community",
contactUs: "/contact-us",
};

export const apiConstants = {
Expand Down
1 change: 1 addition & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ module.exports = {
gamboge: "#EEA30A",
veryLightGrey: "#CFCFCF",
"lavendar-blush": "#FFF7FC",
gains: "#D8D8D8",
},
fontSize: {
15: "15px",
Expand Down
Loading

0 comments on commit 8e45c3f

Please sign in to comment.