| @@ -1,4 +1,4 @@ | |||
| import React, { useEffect, lazy, Suspense, useRef, useState } from 'react'; | |||
| import React, { useEffect, lazy, Suspense, useRef, useState, useContext } from 'react'; | |||
| import './App.css'; | |||
| import { Route, Routes, useNavigate } from 'react-router-dom'; | |||
| import Navigation from './components/shared/Navigation'; | |||
| @@ -9,6 +9,7 @@ import ScrollToTop from './components/root/ScrollToTop'; | |||
| import ReactGA from 'react-ga4'; | |||
| import { useCookies } from 'react-cookie'; | |||
| import routes from './routes'; | |||
| import UIContextProvider from './context/UIContextProvider'; | |||
| const Home = lazy(() => import('./pages/Home')); | |||
| const Portfolio = lazy(() => import('./pages/Portfolio')); | |||
| @@ -45,6 +46,7 @@ function App() { | |||
| //scroll to Contact segment | |||
| const forwardedRef = useRef(null); | |||
| useEffect(() => { | |||
| if (diligentCookie === 'true') { | |||
| ReactGA.initialize(process.env.REACT_APP_MEASUREMENT_ID); | |||
| @@ -84,45 +86,51 @@ function App() { | |||
| return ( | |||
| <div> | |||
| <ScrollToTop /> | |||
| <Navigation | |||
| links={links} | |||
| scrollToView={scrollToView} | |||
| activeLinks={activeLinks} | |||
| forwardedRef={forwardedRef} | |||
| ></Navigation> | |||
| {diligentCookie === undefined && ( | |||
| <CookieBanner handleAccept={handleAccept} handleDecline={handleDecline} /> | |||
| )} | |||
| <Suspense fallback={<Loader />}> | |||
| <Routes> | |||
| <Route path="*" element={<NotFoundPage />}/> | |||
| <Route exact path="/" element={<Home forwardedRef={forwardedRef} />} /> | |||
| <Route exact path="/workwithus" element={<WorkWithUs />} /> | |||
| <Route exact path="/portfolio" element={<Portfolio />} /> | |||
| <Route exact path="/case-studies/:id" element={<CaseStudyPage />} /> | |||
| <Route exact path="/process" element={<ProcessPage />} /> | |||
| <Route exact path="/careers" element={<Careers />}/> | |||
| <Route exact path="/culture" element={<Culture />}/> | |||
| <Route exact path="/about" element={<About />}/> | |||
| {/* <Route exact path="/blog" element={<Blog />}/> */} | |||
| {/* <Route exact path="/articles/:slug" element={<ArticlePage />} /> */} | |||
| <Route exact path="/contact" element={<ContactPage />}/> | |||
| <Route exact path="/casestudybi" element={<CaseStudyBI />}/> | |||
| <Route exact path="/casestudystrata" element={<CaseStudyStrata />}/> | |||
| <Route exact path="/casestudyfinancial" element={<CaseStudyFinantial />}/> | |||
| <Route exact path="/casestudycentralized" element={<CaseStudyCentralized />}/> | |||
| <Route exact path="/casestudyresource" element={<CaseStudyResource />}/> | |||
| <Route exact path="/casestudyticketing" element={<CaseStudyTicketing />}/> | |||
| <Route exact path="/privacypolicy" element={<PrivacyPolicy />}/> | |||
| </Routes> | |||
| </Suspense> | |||
| <UIContextProvider> | |||
| <Navigation | |||
| links={links} | |||
| scrollToView={scrollToView} | |||
| activeLinks={activeLinks} | |||
| forwardedRef={forwardedRef} | |||
| ></Navigation> | |||
| {diligentCookie === undefined && ( | |||
| <CookieBanner handleAccept={handleAccept} handleDecline={handleDecline} /> | |||
| )} | |||
| <Suspense fallback={<Loader />}> | |||
| <Routes> | |||
| <Route path="*" element={<NotFoundPage />} /> | |||
| <Route exact path="/" element={<Home forwardedRef={forwardedRef} />} /> | |||
| <Route exact path="/workwithus" element={<WorkWithUs />} /> | |||
| <Route exact path="/portfolio" element={<Portfolio />} /> | |||
| <Route exact path="/case-studies/:id" element={<CaseStudyPage />} /> | |||
| <Route exact path="/process" element={<ProcessPage />} /> | |||
| <Route exact path="/careers" element={<Careers />} /> | |||
| <Route exact path="/culture" element={<Culture />} /> | |||
| <Route exact path="/about" element={<About />} /> | |||
| {/* <Route exact path="/blog" element={<Blog />}/> */} | |||
| {/* <Route exact path="/articles/:slug" element={<ArticlePage />} /> */} | |||
| <Route exact path="/contact" element={<ContactPage />} /> | |||
| <Route exact path="/casestudybi" element={<CaseStudyBI />} /> | |||
| <Route exact path="/casestudystrata" element={<CaseStudyStrata />} /> | |||
| <Route exact path="/casestudyfinancial" element={<CaseStudyFinantial />} /> | |||
| <Route | |||
| exact | |||
| path="/casestudycentralized" | |||
| element={<CaseStudyCentralized />} | |||
| /> | |||
| <Route exact path="/casestudyresource" element={<CaseStudyResource />} /> | |||
| <Route exact path="/casestudyticketing" element={<CaseStudyTicketing />} /> | |||
| <Route exact path="/privacypolicy" element={<PrivacyPolicy />} /> | |||
| </Routes> | |||
| </Suspense> | |||
| <Footer | |||
| links={links} | |||
| activeLinks={activeLinks} | |||
| scrollToView={scrollToView} | |||
| forwardedRef={forwardedRef} | |||
| /> | |||
| <Footer | |||
| links={links} | |||
| activeLinks={activeLinks} | |||
| scrollToView={scrollToView} | |||
| forwardedRef={forwardedRef} | |||
| /> | |||
| </UIContextProvider> | |||
| </div> | |||
| ); | |||
| } | |||
| @@ -1,4 +1,4 @@ | |||
| import React from 'react'; | |||
| import React, { useEffect } from 'react'; | |||
| import TriangleButton from '../shared/TriangleButton'; | |||
| import { useNavigate } from 'react-router-dom'; | |||
| import net from './../../assets/icons/net.svg'; | |||
| @@ -6,11 +6,25 @@ import net from './../../assets/icons/net.svg'; | |||
| const ExpandedCard = ({ card, setExpanded, setExpandedCard, forwarderdRef }) => { | |||
| const ExpandedCard = ({ card, setExpanded, setExpandedCard, forwarderdRef, setJobForm, jobForm }) => { | |||
| const linkTo = useNavigate(); | |||
| const changeContext = (value) => { | |||
| setJobForm({ | |||
| ...jobForm, | |||
| position: value, | |||
| }); | |||
| } | |||
| useEffect(() => { | |||
| console.log(jobForm) | |||
| },[jobForm]); | |||
| const handleNavigate = (tab, position) => { | |||
| linkTo('/contact', { tab: { tab }, position: { position } }); | |||
| changeContext(card.nugget); | |||
| linkTo('/contact', { tab: { tab } }); | |||
| //card.tag | |||
| //console.log(card.nugget); | |||
| }; | |||
| @@ -84,9 +98,9 @@ const ExpandedCard = ({ card, setExpanded, setExpandedCard, forwarderdRef }) => | |||
| <br /> | |||
| <div className="flex flex-row w-full items-center justify-end"> | |||
| <a | |||
| href="/contact" | |||
| href="#" | |||
| className="btn btn_primary mt-8 transition-all hover:transition-all" | |||
| onClick={handleNavigate(false, card.nugget)} | |||
| onClick={()=>handleNavigate(false, card.nugget)} | |||
| > | |||
| Apply | |||
| </a> | |||
| @@ -155,9 +169,9 @@ const ExpandedCard = ({ card, setExpanded, setExpandedCard, forwarderdRef }) => | |||
| <br /> | |||
| <div className="flex flex-row w-full items-center justify-end"> | |||
| <a | |||
| href="/contact" | |||
| href="#" | |||
| className="btn btn_primary mt-8 transition-all hover:transition-all" | |||
| onClick={handleNavigate(false, '.Net')} | |||
| onClick={()=>handleNavigate(false, card.nugget)} | |||
| > | |||
| Apply | |||
| </a> | |||
| @@ -3,8 +3,12 @@ import CareerCard from './CareerCard'; | |||
| import { useState } from 'react'; | |||
| import useComponentVisible from './../../hooks/useClickOutside'; | |||
| import ExpandedCard from './ExpandedCard'; | |||
| import { useContext } from 'react'; | |||
| import { UIContext } from './../../context/UIContextProvider'; | |||
| const JobCardsWrapper = ({ data }) => { | |||
| const { jobForm, setJobForm } = useContext(UIContext); | |||
| const [expandedCard, setExpandedCard] = useState({}); | |||
| const { ref, isComponentVisible, setIsComponentVisible } = useComponentVisible(false); | |||
| @@ -18,6 +22,8 @@ const JobCardsWrapper = ({ data }) => { | |||
| setExpanded={setIsComponentVisible} | |||
| setExpandedCard={setExpandedCard} | |||
| forwarderdRef={ref} | |||
| jobForm={jobForm} | |||
| setJobForm={setJobForm} | |||
| ></ExpandedCard> | |||
| ) : ( | |||
| <div className="flex flex-col md:flex-row justify-center items-center w-full gap-8"> | |||
| @@ -34,7 +40,7 @@ const JobCardsWrapper = ({ data }) => { | |||
| ))} | |||
| </div> | |||
| )} | |||
| </div> | |||
| </div> | |||
| </section> | |||
| ); | |||
| }; | |||
| @@ -0,0 +1,194 @@ | |||
| import React from 'react'; | |||
| const RadioBoxesGroup = () => { | |||
| return ( | |||
| <div> | |||
| {' '} | |||
| <form className="w-full max-w-screen-md mx-auto"> | |||
| <fieldset className="space-y-6"> | |||
| <div className="grid sm:grid-cols-4 gap-6"> | |||
| <label | |||
| htmlFor="plan-hobby" | |||
| className="relative flex flex-col bg-white p-5 rounded-lg shadow-md cursor-pointer" | |||
| > | |||
| <span className="font-semibold text-gray-500 leading-tight uppercase mb-3"> | |||
| Hobby | |||
| </span> | |||
| <span className="font-bold text-gray-900"> | |||
| <span className="text-4xl">1</span> | |||
| <span className="text-2xl uppercase">GB</span> | |||
| </span> | |||
| <span> | |||
| <span className="text-xl font-bold text-gray-500">$</span> | |||
| <span className="text-xl font-bold text-gray-900 -ml-1">5</span> | |||
| <span className="text-xl font-semibold text-gray-500">/</span> | |||
| <span className="text-lg font-semibold text-gray-500">mo</span> | |||
| </span> | |||
| <input | |||
| type="radio" | |||
| name="plan" | |||
| id="plan-hobby" | |||
| value="hobby" | |||
| className="absolute h-0 w-0 appearance-none" | |||
| /> | |||
| <span | |||
| aria-hidden="true" | |||
| className="hidden absolute inset-0 border-2 border-green-500 bg-green-200 bg-opacity-10 rounded-lg" | |||
| > | |||
| <span className="absolute top-4 right-4 h-6 w-6 inline-flex items-center justify-center rounded-full bg-green-200"> | |||
| <svg | |||
| xmlns="http://www.w3.org/2000/svg" | |||
| viewBox="0 0 20 20" | |||
| fill="currentColor" | |||
| className="h-5 w-5 text-green-600" | |||
| > | |||
| <path | |||
| fillRule="evenodd" | |||
| d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" | |||
| clipRule="evenodd" | |||
| /> | |||
| </svg> | |||
| </span> | |||
| </span> | |||
| </label> | |||
| <label | |||
| htmlFor="plan-growth" | |||
| className="relative flex flex-col bg-white p-5 rounded-lg shadow-md cursor-pointer" | |||
| > | |||
| <span className="font-semibold text-gray-500 leading-tight uppercase mb-3"> | |||
| Growth | |||
| </span> | |||
| <span className="font-bold text-gray-900"> | |||
| <span className="text-4xl">5</span> | |||
| <span className="text-2xl uppercase">GB</span> | |||
| </span> | |||
| <span> | |||
| <span className="text-xl font-bold text-gray-500">$</span> | |||
| <span className="text-xl font-bold text-gray-900 -ml-1">10</span> | |||
| <span className="text-xl font-semibold text-gray-500">/</span> | |||
| <span className="text-lg font-semibold text-gray-500">mo</span> | |||
| </span> | |||
| <input | |||
| type="radio" | |||
| name="plan" | |||
| id="plan-growth" | |||
| value="growth" | |||
| className="absolute h-0 w-0 appearance-none" | |||
| checked | |||
| /> | |||
| <span | |||
| aria-hidden="true" | |||
| className="hidden absolute inset-0 border-2 border-green-500 bg-green-200 bg-opacity-10 rounded-lg" | |||
| > | |||
| <span className="absolute top-4 right-4 h-6 w-6 inline-flex items-center justify-center rounded-full bg-green-200"> | |||
| <svg | |||
| xmlns="http://www.w3.org/2000/svg" | |||
| viewBox="0 0 20 20" | |||
| fill="currentColor" | |||
| className="h-5 w-5 text-green-600" | |||
| > | |||
| <path | |||
| fillRule="evenodd" | |||
| d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" | |||
| clipRule="evenodd" | |||
| /> | |||
| </svg> | |||
| </span> | |||
| </span> | |||
| </label> | |||
| <label | |||
| htmlFor="plan-business" | |||
| className="relative flex flex-col bg-white p-5 rounded-lg shadow-md cursor-pointer" | |||
| > | |||
| <span className="font-semibold text-gray-500 leading-tight uppercase mb-3"> | |||
| Business | |||
| </span> | |||
| <span className="font-bold text-gray-900"> | |||
| <span className="text-4xl">10</span> | |||
| <span className="text-2xl uppercase">GB</span> | |||
| </span> | |||
| <span> | |||
| <span className="text-xl font-bold text-gray-500">$</span> | |||
| <span className="text-xl font-bold text-gray-900 -ml-1">15</span> | |||
| <span className="text-xl font-semibold text-gray-500">/</span> | |||
| <span className="text-lg font-semibold text-gray-500">mo</span> | |||
| </span> | |||
| <input | |||
| type="radio" | |||
| name="plan" | |||
| id="plan-business" | |||
| value="business" | |||
| className="absolute h-0 w-0 appearance-none" | |||
| /> | |||
| <span | |||
| aria-hidden="true" | |||
| className="hidden absolute inset-0 border-2 border-green-500 bg-green-200 bg-opacity-10 rounded-lg" | |||
| > | |||
| <span className="absolute top-4 right-4 h-6 w-6 inline-flex items-center justify-center rounded-full bg-green-200"> | |||
| <svg | |||
| xmlns="http://www.w3.org/2000/svg" | |||
| viewBox="0 0 20 20" | |||
| fill="currentColor" | |||
| className="h-5 w-5 text-green-600" | |||
| > | |||
| <path | |||
| fillRule="evenodd" | |||
| d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" | |||
| clipRule="evenodd" | |||
| /> | |||
| </svg> | |||
| </span> | |||
| </span> | |||
| </label> | |||
| <label | |||
| htmlFor="plan-enterprise" | |||
| className="relative flex flex-col bg-white p-5 rounded-lg shadow-md cursor-pointer" | |||
| > | |||
| <span className="font-semibold text-gray-500 leading-tight uppercase mb-3"> | |||
| Enterprise | |||
| </span> | |||
| <span className="font-bold text-gray-900"> | |||
| <span className="text-4xl">20</span> | |||
| <span className="text-2xl uppercase">GB</span> | |||
| </span> | |||
| <span> | |||
| <span className="text-xl font-bold text-gray-500">$</span> | |||
| <span className="text-xl font-bold text-gray-900 -ml-1">20</span> | |||
| <span className="text-xl font-semibold text-gray-500">/</span> | |||
| <span className="text-lg font-semibold text-gray-500">mo</span> | |||
| </span> | |||
| <input | |||
| type="radio" | |||
| name="plan" | |||
| id="plan-enterprise" | |||
| value="enterprise" | |||
| className="absolute h-0 w-0 appearance-none" | |||
| /> | |||
| <span | |||
| aria-hidden="true" | |||
| className="hidden absolute inset-0 border-2 border-green-500 bg-green-200 bg-opacity-10 rounded-lg" | |||
| > | |||
| <span className="absolute top-4 right-4 h-6 w-6 inline-flex items-center justify-center rounded-full bg-green-200"> | |||
| <svg | |||
| xmlns="http://www.w3.org/2000/svg" | |||
| viewBox="0 0 20 20" | |||
| fill="currentColor" | |||
| className="h-5 w-5 text-green-600" | |||
| > | |||
| <path | |||
| fillRule="evenodd" | |||
| d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" | |||
| clipRule="evenodd" | |||
| /> | |||
| </svg> | |||
| </span> | |||
| </span> | |||
| </label> | |||
| </div> | |||
| </fieldset> | |||
| </form> | |||
| </div> | |||
| ); | |||
| }; | |||
| export default RadioBoxesGroup; | |||
| @@ -17,7 +17,7 @@ import Wrapper from '../../layout/Wrapper'; | |||
| import Mailgun from 'mailgun.js'; | |||
| import FormData from 'form-data'; | |||
| import { UIContext } from '../../context/UIProvider'; | |||
| import { UIContext } from '../../context/UIContextProvider'; | |||
| const mailgun = new Mailgun(FormData); | |||
| const mg = mailgun.client({ | |||
| @@ -26,7 +26,7 @@ const mg = mailgun.client({ | |||
| url: 'https://api.eu.mailgun.net', | |||
| }); | |||
| export default function Contact({activeTab, position, job, business}) { | |||
| export default function Contact({ activeTab, position, job, business }) { | |||
| const [tab, setTab] = useState(activeTab); | |||
| const [tabTitle, setTabTitle] = useState(business.title); | |||
| @@ -40,7 +40,6 @@ export default function Contact({activeTab, position, job, business}) { | |||
| } | |||
| const { uiContext, setUiContext } = useContext(UIContext); | |||
| const clientContext = useContext(ClientFormContext); | |||
| const jobContext = useContext(JobFormContext); | |||
| function classNames(...classes) { | |||
| return classes.filter(Boolean).join(' '); | |||
| @@ -64,20 +63,10 @@ export default function Contact({activeTab, position, job, business}) { | |||
| email: '', | |||
| description: '', | |||
| }; | |||
| const initialJobValues = jobContext ?? { | |||
| position: '', | |||
| other: '', | |||
| firstName: '', | |||
| lastName: '', | |||
| email: '', | |||
| description: '', | |||
| files: [], | |||
| }; | |||
| const api_url = process.env.REACT_APP_API_URL; | |||
| const [clientForm, setClientForm] = useState(initialClientValues); | |||
| const [jobForm, setJobForm] = useState(initialJobValues); | |||
| const [cntCareers, setCntCareers] = useState(''); | |||
| const [isLoaded, setIsLoaded] = useState(''); | |||
| @@ -98,7 +87,6 @@ export default function Contact({activeTab, position, job, business}) { | |||
| }); | |||
| }, []); | |||
| if (!isLoaded) { | |||
| return ( | |||
| <div className="z-50 w-full h-screen bg-white dark:bg-dg-primary-1700 dark:text-white flex items-center justify-center text-3xl font-semibold"> | |||
| @@ -117,20 +105,13 @@ export default function Contact({activeTab, position, job, business}) { | |||
| </div> | |||
| <div className="py-16 relative"> | |||
| <div className="flex justify-end flex-col"> | |||
| <Tab.Group | |||
| defaultIndex={tab ? 0 : 1} | |||
| onChange={index => handleTab(index)} | |||
| > | |||
| <Tab.Group defaultIndex={tab ? 0 : 1} onChange={index => handleTab(index)}> | |||
| <div | |||
| className="flex flex-col md:flex-row items-start md:items-baseline md:justify-between" | |||
| onMouseDown={handleTabClick} | |||
| > | |||
| {tab ? ( | |||
| <PageTitle | |||
| left | |||
| heading={business.title} | |||
| subheading={business.subtitle} | |||
| /> | |||
| <PageTitle left heading={business.title} subheading={business.subtitle} /> | |||
| ) : ( | |||
| <PageTitle left heading={job.title} subheading={job.title} /> | |||
| )} | |||
| @@ -168,20 +149,11 @@ export default function Contact({activeTab, position, job, business}) { | |||
| <Tab.Panels className="w-full mt-2 mx-auto"> | |||
| <Tab.Panel className={classNames('py-3', 'outline-none')}> | |||
| <ClientFormContext.Provider value={{ clientForm, setClientForm }}> | |||
| <ClientForm mg={mg} | |||
| cta={business.cta} | |||
| img={business.image} /> | |||
| <ClientForm mg={mg} cta={business.cta} img={business.image} /> | |||
| </ClientFormContext.Provider> | |||
| </Tab.Panel> | |||
| <Tab.Panel className={classNames('py-3', 'outline-none')}> | |||
| <JobFormContext.Provider value={{ jobForm, setJobForm }}> | |||
| <JobForm | |||
| cta={job.cta} | |||
| img={job.image} | |||
| cntCareers={cntCareers} | |||
| mg={mg} | |||
| /> | |||
| </JobFormContext.Provider> | |||
| <JobForm cta={job.cta} img={job.image} cntCareers={cntCareers} mg={mg} /> | |||
| </Tab.Panel> | |||
| </Tab.Panels> | |||
| </Tab.Group> | |||
| @@ -1,41 +1,30 @@ | |||
| import { useState } from 'react'; | |||
| import { useEffect, useState } from 'react'; | |||
| import { RadioGroup } from '@headlessui/react'; | |||
| import propTypes from 'prop-types'; | |||
| const _data = { | |||
| job: [{ | |||
| id:1, | |||
| position: ".Net" | |||
| }, | |||
| { | |||
| id:2, | |||
| position: "Legal" | |||
| }, | |||
| ] | |||
| } | |||
| job: [ | |||
| { | |||
| id: 1, | |||
| position: '.Net', | |||
| }, | |||
| { | |||
| id: 2, | |||
| position: 'Legal', | |||
| }, | |||
| ], | |||
| }; | |||
| export default function HashPositions(props) { | |||
| let defaultPositionSelection = props.defaultPositionSelection; | |||
| //let defaultPositionSelection = '#dotNet'; | |||
| //const cntCareersJobs = props.cntCareers; | |||
| let [selected, setSelected] = useState(''); | |||
| //console.log(props.selectedPosition); | |||
| function handleChange(event) { | |||
| setSelected(event.target.innerText); | |||
| //console.log(event.target.innerText); | |||
| props.setSelectedPosition(event.target.innerText); | |||
| //console.log(selected) | |||
| props.setSelectedPosition(event.target.value) | |||
| } | |||
| return ( | |||
| <RadioGroup | |||
| value={ | |||
| defaultPositionSelection != null && defaultPositionSelection != '' | |||
| ? defaultPositionSelection | |||
| : selected | |||
| } | |||
| onChange={setSelected} | |||
| value={props.selectedPosition} | |||
| onChange={props.setSelectedPosition} | |||
| className="flex flex-col items-start justify-center" | |||
| > | |||
| <RadioGroup.Label className="block text-sm font-medium text-gray-700 dark:text-gray-400 mr-4"> | |||
| @@ -43,14 +32,13 @@ export default function HashPositions(props) { | |||
| </RadioGroup.Label> | |||
| <div className="mt-1 mb-4 flex flex-row items-center justify-start"> | |||
| {_data.job.map(job => ( | |||
| <RadioGroup.Option key={job.id} value={'#' + job.position}> | |||
| <RadioGroup.Option key={job.id} value={job.position}> | |||
| {({ checked }) => ( | |||
| <span | |||
| onClick={() => { | |||
| props.setOtherInputState(true); | |||
| defaultPositionSelection = '#dotNet'; | |||
| handleChange(event); | |||
| props.hashToFormData(selected); | |||
| props.hashToFormData(props.selectedPosition); | |||
| }} | |||
| className={ | |||
| checked | |||
| @@ -69,9 +57,8 @@ export default function HashPositions(props) { | |||
| <span | |||
| onClick={() => { | |||
| props.setOtherInputState(false); | |||
| defaultPositionSelection = ''; | |||
| props.setSelectedPosition('#Other'); | |||
| props.hashToFormData(selected); | |||
| props.setSelectedPosition(''); | |||
| props.hashToFormData(props.selected); | |||
| }} | |||
| className={ | |||
| checked | |||
| @@ -12,7 +12,7 @@ import MyDropzone from './MyDropzone'; | |||
| import HashPositions from './HashPositions'; | |||
| import ReCAPTCHA from 'react-google-recaptcha'; | |||
| import axios from 'axios'; | |||
| import { UIContext } from '../../context/UIProvider'; | |||
| import { UIContext } from '../../context/UIContextProvider'; | |||
| const api_url = process.env.REACT_APP_API_URL; | |||
| @@ -23,45 +23,50 @@ export default function JobForm(props) { | |||
| const [msgText, setMsgText] = useState(''); | |||
| const cntCareersJobs = props.cntCareers; | |||
| let defaultPositionSelection = props.defaultPositionSelection; | |||
| //search context for prevous entry TODO | |||
| const { jobForm, setJobForm } = useContext(JobFormContext); | |||
| const { jobForm, setJobForm } = useContext(UIContext); | |||
| const [otherInputState, setOtherInputState] = useState(true); | |||
| const [selectedPosition, setSelectedPosition] = useState(''); | |||
| const [selectedPosition, setSelectedPosition] = useState(jobForm.position); | |||
| //console.log(selectedPosition); | |||
| const [errorMsg, setErrorMsg] = useState(''); | |||
| const [errorMsgPosition, setErrorMsgPosition] = useState(''); | |||
| const fileInput = useRef(); | |||
| function changeFormHandler(event) { | |||
| //console.log(event.target); | |||
| const { name, value } = event.target; | |||
| setJobForm({ | |||
| ...jobForm, | |||
| setJobForm(prevState => ({ | |||
| ...prevState, | |||
| [name]: value, | |||
| }); | |||
| //console.log(jobForm.position); | |||
| })); | |||
| } | |||
| function dropzoneToFormData(files) { | |||
| setJobForm({ | |||
| ...jobForm, | |||
| setJobForm(prevState => ({ | |||
| ...prevState, | |||
| file: files, | |||
| }); | |||
| })); | |||
| } | |||
| function hashToFormData(selected, other) { | |||
| console.log(selected) | |||
| setJobForm({ | |||
| ...jobForm, | |||
| position: selected, | |||
| other: other, | |||
| }); | |||
| console.log(jobForm.position); | |||
| setJobForm(prevState => ({ | |||
| ...prevState, | |||
| position: selected, | |||
| other: other, | |||
| })); | |||
| } | |||
| useEffect(() => { | |||
| setJobForm(prevState => ({ | |||
| ...prevState, | |||
| position: selectedPosition, | |||
| })); | |||
| },[selectedPosition]) | |||
| useEffect(() => { | |||
| setBtnText(props.cta); | |||
| },[props.cta]) | |||
| }, [props.cta]); | |||
| useEffect(() => { | |||
| if (jobForm.file !== '') { | |||
| @@ -130,7 +135,7 @@ export default function JobForm(props) { | |||
| ) | |||
| setErrorMsgPosition('Position is Required'); | |||
| else { | |||
| setSelectedPosition(jobForm.position) | |||
| setSelectedPosition(jobForm.position); | |||
| setErrorMsgPosition(''); | |||
| if (jobForm.file === '') { | |||
| setErrorMsg('CV is Required'); | |||
| @@ -159,6 +164,8 @@ export default function JobForm(props) { | |||
| if (res.data.data.success) { | |||
| setMsgText('Submission Succesful! Thank you!'); | |||
| values.position = jobForm.position; | |||
| // props.mg.messages.create('dilig.net', { | |||
| // from: `${values.firstName} ${values.lastName} <${values.email}>`, | |||
| // to: ['hr@dilig.net'], | |||
| @@ -167,6 +174,7 @@ export default function JobForm(props) { | |||
| // html: `<p>Email: ${values.email}</p><p>Position: ${selectedPosition} ${values.other}</p><p>Cover letter: ${values.coverLetter}</p><p>Link (optional): ${values.link}</p>`, | |||
| // attachment: file, | |||
| // }); | |||
| console.log(jobForm); | |||
| } else | |||
| setMsgText('Please fill reCAPTCHA and try again. Thank you!'); | |||
| }) | |||
| @@ -189,7 +197,7 @@ export default function JobForm(props) { | |||
| <div className="py-2 sm:py-6"> | |||
| <div className=""> | |||
| <div className="col-span-1 sm:col-span-1"> | |||
| <div className="py-1 hidden"> | |||
| <div className="hidden py-1"> | |||
| <label | |||
| htmlFor="first-name" | |||
| className="block text-sm font-medium text-gray-700 dark:text-gray-400" | |||
| @@ -200,9 +208,9 @@ export default function JobForm(props) { | |||
| type="text" | |||
| name="position" | |||
| id="position" | |||
| //onBlur={changeFormHandler} | |||
| value={jobForm.position} | |||
| //onChange={props.handleChange} | |||
| onBlur={changeFormHandler} | |||
| value={selectedPosition} | |||
| onChange={props.handleChange} | |||
| autoComplete="given-name" | |||
| className="mt-1 disabled:bg-gray-100 disabled:border-gray-300 focus:ring-dg-primary-600 focus:border-dg-primary-900 block w-full shadow-sm sm:text-sm border-dg-primary-600 rounded-md transition duration-200" | |||
| /> | |||
| @@ -214,13 +222,15 @@ export default function JobForm(props) { | |||
| /> | |||
| </div> | |||
| </div> | |||
| {/* <RadioBoxesGroup/> */} | |||
| <HashPositions | |||
| changeFormHandler={changeFormHandler} | |||
| hashToFormData={hashToFormData} | |||
| cntCareers={cntCareersJobs} | |||
| otherInputState={otherInputState} | |||
| hashToFormData={hashToFormData} | |||
| setOtherInputState={setOtherInputState} | |||
| defaultPositionSelection={defaultPositionSelection} | |||
| selectedPosition={selectedPosition} | |||
| setSelectedPosition={setSelectedPosition} | |||
| /> | |||
| <div className="py-1"> | |||
| @@ -413,8 +423,7 @@ export default function JobForm(props) { | |||
| className="btn btn_primary transition-all inline-flex justify-center py-4 px-14 border border-transparent shadow-md text-sm font-semibold rounded-xl text-white bg-dg-primary-600 hover:bg-dg-primary-900 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-dg-primary-600" | |||
| > | |||
| {btnText} | |||
| </button> | |||
| </button> | |||
| </div> | |||
| {sucMsg && ( | |||
| <div className={'text-sm text-right text-dg-primary-900'}> | |||
| @@ -423,7 +432,15 @@ export default function JobForm(props) { | |||
| )} | |||
| </div> | |||
| <div className="col-span-1 sm:col-span-1 lg:col-span-1 mt-8">Or contact us directly via email <a className='text-semibodld text-dg-primary-600' href="mailto:hr@dilig.net">hr@dilig.net</a></div> | |||
| <div className="col-span-1 sm:col-span-1 lg:col-span-1 mt-8"> | |||
| Or contact us directly via email{' '} | |||
| <a | |||
| className="text-semibodld text-dg-primary-600" | |||
| href="mailto:hr@dilig.net" | |||
| > | |||
| hr@dilig.net | |||
| </a> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -438,7 +455,10 @@ export default function JobForm(props) { | |||
| exit={{ x: 60, opacity: 0 }} | |||
| transition={{ duration: 0.3, ease: 'easeOut' }} | |||
| > | |||
| <img src={api_url + props.img.data.attributes.url} alt={props.img.data.attributes.alternativeText} /> | |||
| <img | |||
| src={api_url + props.img.data.attributes.url} | |||
| alt={props.img.data.attributes.alternativeText} | |||
| /> | |||
| </motion.div> | |||
| </div> | |||
| </div> | |||
| @@ -0,0 +1,49 @@ | |||
| import React, { createContext, useState } from 'react'; | |||
| import { useContext } from 'react'; | |||
| export const UIContext = createContext({ | |||
| jobForm: { | |||
| tag: '', | |||
| subject: '', | |||
| firstName: '', | |||
| lastName: '', | |||
| email: '', | |||
| description: '', | |||
| position: '', | |||
| }, | |||
| setJobForm: () => {}, | |||
| tab: true, | |||
| setTab: () => {}, | |||
| }); | |||
| const UIContextProvider = ({ children }) => { | |||
| const uiContext = useContext(UIContext); | |||
| const [jobForm, setJobForm] = useState(uiContext.jobForm); | |||
| const [tab, setTab] = useState(uiContext); | |||
| const values = { | |||
| jobForm, | |||
| setJobForm, | |||
| tab, | |||
| setTab, | |||
| }; | |||
| // const changeUI = (object,prop,value) => { | |||
| // if (value) { | |||
| // setUi(prevState => ({ | |||
| // ...prevState, | |||
| // [object]: { | |||
| // [prop]: value, | |||
| // }, | |||
| // })); | |||
| // }}; | |||
| return ( | |||
| <> | |||
| <UIContext.Provider value={values}>{children}</UIContext.Provider> | |||
| </> | |||
| ); | |||
| }; | |||
| export default UIContextProvider; | |||
| @@ -1,29 +0,0 @@ | |||
| import React, { createContext, useState } from 'react'; | |||
| export const UIContext = createContext({ | |||
| tab: true, | |||
| contactRef: '', | |||
| position: '', | |||
| }); | |||
| const UIProvider = ({ children }) => { | |||
| const [ui, setUi] = useState({}); | |||
| const changeUI = (value) => { | |||
| if (value) { | |||
| setUi(prevState => ({ | |||
| ...prevState, | |||
| position: value, | |||
| })); | |||
| }}; | |||
| return ( | |||
| <> | |||
| <UIContext.Provider value={{ ui, changeUI }}> | |||
| {children} | |||
| </UIContext.Provider> | |||
| </> | |||
| ); | |||
| }; | |||
| export default UIProvider; | |||
| @@ -6,7 +6,6 @@ import reportWebVitals from './reportWebVitals'; | |||
| import { CookiesProvider } from 'react-cookie'; | |||
| import { BrowserRouter } from 'react-router-dom'; | |||
| import { HelmetProvider } from 'react-helmet-async'; | |||
| import UIProvider from './context/UIProvider'; | |||
| if (module.hot) module.hot.accept(); | |||
| @@ -15,9 +14,7 @@ ReactDOM.render( | |||
| <BrowserRouter> | |||
| <CookiesProvider> | |||
| <HelmetProvider> | |||
| <UIProvider> | |||
| <App /> | |||
| </UIProvider> | |||
| <App /> | |||
| </HelmetProvider> | |||
| </CookiesProvider> | |||
| </BrowserRouter> | |||
| @@ -107,7 +107,7 @@ const _data = { | |||
| id: 2, | |||
| templateFlag: 1, | |||
| role: 'Legal Assistant', | |||
| nugget: 'LegalAssistant', | |||
| nugget: 'Legal', | |||
| icon: legal, | |||
| shortDetails: | |||
| '+1 Years of Experience', | |||