Browse Source

SEO optimization

SEO
ntasicc 3 years ago
parent
commit
a424b9339f

+ 1
- 0
frontend/public/robots.txt View File

@@ -1,3 +1,4 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
Sitemap: https://www.dilig.net/sitemap.txt

+ 15
- 0
frontend/public/sitemap.txt View File

@@ -0,0 +1,15 @@
https://www.dilig.net/
https://www.dilig.net/portfolio
https://www.dilig.net/casestudybi
https://www.dilig.net/casestudystrata
https://www.dilig.net/casestudyfinancial
https://www.dilig.net/casestudyticketing
https://www.dilig.net/casestudycentralized
https://www.dilig.net/casestudyresource
https://www.dilig.net/services
https://www.dilig.net/about
https://www.dilig.net/post
https://www.dilig.net/process
https://www.dilig.net/contact
https://www.dilig.net/privacypolicy
https://www.dilig.net/openday

+ 69
- 58
frontend/src/App.js View File

@@ -1,27 +1,43 @@
import React, { useEffect } from 'react';
import React, { useEffect, lazy, Suspense } from 'react';
import './App.css';
import { Route, Routes, useLocation, useNavigate } from 'react-router-dom';
import Navigation from './components/shared/Navigation';
import Home from './pages/Home';
import Portfolio from './pages/Portfolio';
import Services from './pages/Services';
import Careers from './pages/Careers';
import About from './pages/About';
import BlogPost from './components/BlogPost';
// import Home from './pages/Home';
// import Portfolio from './pages/Portfolio';
// import Services from './pages/Services';
// import Careers from './pages/Careers';
// import About from './pages/About';
// import BlogPost from './components/BlogPost';
import Footer from './components/shared/Footer';
import { useRef, useState } from 'react';
import ProcessPage from './pages/ProcessPage';
import ContactPage from './pages/ContactPage';
import CaseStudyBI from './pages/CaseStudyBI';
import CaseStudyFinantial from './pages/CaseStudyFinantial';
import CaseStudyTicketing from './pages/CaseStudyTicketing';
import CaseStudyCentralized from './pages/CaseStudyCentralized';
import CaseStudyResource from './pages/CaseStudyResource';
import CaseStudyStrata from './pages/CaseStudyStrata';
import PrivacyPolicy from './pages/PrivacyPolicy';
import WorkWithUs from './pages/WorkWithUs';


import Loader from './components/shared/Loader';
// import ProcessPage from './pages/ProcessPage';
// import ContactPage from './pages/ContactPage';
// import CaseStudyBI from './pages/CaseStudyBI';
// import CaseStudyFinantial from './pages/CaseStudyFinantial';
// import CaseStudyTicketing from './pages/CaseStudyTicketing';
// import CaseStudyCentralized from './pages/CaseStudyCentralized';
// import CaseStudyResource from './pages/CaseStudyResource';
// import CaseStudyStrata from './pages/CaseStudyStrata';
// import PrivacyPolicy from './pages/PrivacyPolicy';
// import WorkWithUs from './pages/WorkWithUs';

const Home = lazy(() => import('./pages/Home'));
const Portfolio = lazy(() => import('./pages/Portfolio'));
const Services = lazy(() => import('./pages/Services'));
const Careers = lazy(() => import('./pages/Careers'));
const About = lazy(() => import('./pages/About'));
const BlogPost = lazy(() => import('./components/BlogPost'));
const ProcessPage = lazy(() => import('./pages/ProcessPage'));
const ContactPage = lazy(() => import('./pages/ContactPage'));
const CaseStudyBI = lazy(() => import('./pages/CaseStudyBI'));
const CaseStudyFinantial = lazy(() => import('./pages/CaseStudyFinantial'));
const CaseStudyTicketing = lazy(() => import('./pages/CaseStudyTicketing'));
const CaseStudyCentralized = lazy(() => import('./pages/CaseStudyCentralized'));
const CaseStudyResource = lazy(() => import('./pages/CaseStudyResource'));
const CaseStudyStrata = lazy(() => import('./pages/CaseStudyStrata'));
const PrivacyPolicy = lazy(() => import('./pages/PrivacyPolicy'));
const WorkWithUs = lazy(() => import('./pages/WorkWithUs'));

// Navigation Links
const links = [
@@ -58,12 +74,10 @@ const links = [
];

function App() {


//tabs for contact form
const [tab, setTab] = useState(true);
const [tabTitle, setTabTitle] = useState('Tell Us About Your Idea!');
const link = useNavigate()
const link = useNavigate();

//scroll to Contact segment
const forwardedRef = useRef(null);
@@ -73,8 +87,7 @@ function App() {
event.preventDefault();
if (forwardedRef) {
forwardedRef.current.scrollIntoView({ behavior: 'smooth' });
}
else {
} else {
link('/contact');
}
}
@@ -90,7 +103,6 @@ function App() {
}

return (

<div>
<Navigation
links={links}
@@ -98,37 +110,38 @@ function App() {
activeLinks={activeLinks}
forwardedRef={forwardedRef}
></Navigation>

<Routes>
<Route
exact
path="/"
element={
<Home
tab={tab}
tabTitle={tabTitle}
setTab={setTab}
setTabTitle={setTabTitle}
forwardedRef={forwardedRef}
/>
}
/>
<Route exact path="/portfolio" element={<Portfolio />} />
<Route exact path="/casestudybi" element={<CaseStudyBI />} />
<Route exact path="/casestudystrata" element={<CaseStudyStrata />} />
<Route exact path="/casestudyfinancial" element={<CaseStudyFinantial />} />
<Route exact path="/casestudyticketing" element={<CaseStudyTicketing />} />
<Route exact path="/casestudycentralized" element={<CaseStudyCentralized />} />
<Route exact path="/casestudyresource" element={<CaseStudyResource />} />
<Route exact path="/services" element={<Services />} />
<Route exact path="/careers" element={<Careers />} />
<Route exact path="/about" element={<About />} />
<Route exact path="/post" element={<BlogPost />} />
<Route exact path="/process" element={<ProcessPage />} />
<Route exact path="/contact" element={<ContactPage />} />
<Route exact path="/privacypolicy" element={<PrivacyPolicy />} />
<Route exact path="/workwithus" element={<WorkWithUs />} />
</Routes>
<Suspense fallback={<Loader />}>
<Routes>
<Route
exact
path="/"
element={
<Home
tab={tab}
tabTitle={tabTitle}
setTab={setTab}
setTabTitle={setTabTitle}
forwardedRef={forwardedRef}
/>
}
/>
<Route exact path="/portfolio" element={<Portfolio />} />
<Route exact path="/casestudybi" element={<CaseStudyBI />} />
<Route exact path="/casestudystrata" element={<CaseStudyStrata />} />
<Route exact path="/casestudyfinancial" element={<CaseStudyFinantial />} />
<Route exact path="/casestudyticketing" element={<CaseStudyTicketing />} />
<Route exact path="/casestudycentralized" element={<CaseStudyCentralized />} />
<Route exact path="/casestudyresource" element={<CaseStudyResource />} />
<Route exact path="/services" element={<Services />} />
<Route exact path="/careers" element={<Careers />} />
<Route exact path="/about" element={<About />} />
<Route exact path="/post" element={<BlogPost />} />
<Route exact path="/process" element={<ProcessPage />} />
<Route exact path="/contact" element={<ContactPage />} />
<Route exact path="/privacypolicy" element={<PrivacyPolicy />} />
<Route exact path="/workwithus" element={<WorkWithUs />} />
</Routes>
</Suspense>

<Footer
links={links}
@@ -136,9 +149,7 @@ function App() {
scrollToView={scrollToView}
forwardedRef={forwardedRef}
/>

</div>

);
}


+ 24
- 43
frontend/src/components/Landing.jsx View File

@@ -1,30 +1,30 @@
import React from "react";
import { motion } from "framer-motion";
import LandingSVGv2 from "./shared/graphics/LandingSVG-v2";
import HiringWidget from "./HiringWidget";
import Wrapper from "../layout/Wrapper";
import OpenDayBanner from "./OpenDayBanner";
import React from 'react';
import { motion } from 'framer-motion';
import LandingSVGv2 from './shared/graphics/LandingSVG-v2';
import HiringWidget from './HiringWidget';
import Wrapper from '../layout/Wrapper';
import OpenDayBanner from './OpenDayBanner';

const _data = {
cto: "contact us"
}
cto: 'contact us',
};
const numbers = [
{
value: 90,
static: '+',
title: 'Employees'
title: 'Employees',
},
{
value: '20',
static: '+',
title: 'Projects'
title: 'Projects',
},
{
value: '100',
static: '%',
title: 'Client-Retention'
}
]
title: 'Client-Retention',
},
];

const Landing = ({ data }) => {
return (
@@ -36,10 +36,7 @@ const Landing = ({ data }) => {
initial={{ y: 60, opacity: 0 }}
whileInView={{ y: 0, opacity: 1 }}
transition={{ duration: 0.5, ease: 'easeOut' }}

>


{/* <img src={bg_home} alt="Diligent Software's Animation" width="700" /> */}

{/* <LandingSVG /> */}
@@ -47,16 +44,9 @@ const Landing = ({ data }) => {
<HiringWidget />
<div className="mb-16 -mt-12 md:mt-5 flex flex-col lg:flex-row justify-between items-center gap-90p">
<div className="flex flex-col gap-8p">
<h6 className="subheading">
{data.subheading}
</h6>
<h1 className="heading">
Software Solutions Tailored to Each Client
</h1>
<p className="paragraph">
{data.paragraph}

</p>
<h1 className="subheading">{data.subheading}</h1>
<h2 className="heading">Software Solutions Tailored to Each Client</h2>
<p className="paragraph">{data.paragraph}</p>
</div>
<a
href="#contact"
@@ -65,7 +55,6 @@ const Landing = ({ data }) => {
{_data.cto}
</a>
</div>

</motion.section>
<motion.section
id="status-numbers"
@@ -76,25 +65,17 @@ const Landing = ({ data }) => {
>
{numbers.map((item, i) => (
<div key={i} className="flex flex-col">
<h2 className="display-number text-center">
{item.value}{item.static}
</h2>
<h3 className="number-title text-center">
{item.title}
</h3>
<p className="display-number text-center">
{item.value}
{item.static}
</p>
<h3 className="number-title text-center">{item.title}</h3>
</div>
))}






</motion.section>
</div>

</Wrapper>
)
}
);
};

export default Landing;
export default Landing;

+ 61
- 58
frontend/src/components/PortfolioSection.jsx View File

@@ -1,68 +1,71 @@
import React from 'react'
import { useNavigate } from 'react-router-dom'
import Wrapper from '../layout/Wrapper'
import PageTitle from './shared/PageTitle'
import ProcessCard from './shared/ProcessCard'
import ProcessCardsWrapper from './shared/ProcessCardWrapper'
import React from 'react';
import { useNavigate } from 'react-router-dom';
import Wrapper from '../layout/Wrapper';
import PageTitle from './shared/PageTitle';
import ProcessCard from './shared/ProcessCard';
import ProcessCardsWrapper from './shared/ProcessCardWrapper';

const _data = {
cards: [
{
id: 0,
title: 'Bi Healthcare Solution System',
imgUrl:
'https://lh6.googleusercontent.com/D7N87i3udAln4YBp5SbaSI-9r2pVnnT5K2VT6p0G3dQanVgTMC2tdgz71PWOYco-7yQ=w2400',
link: '/casestudybi',
},
{
id: 1,
title: 'Resource Planning System',
imgUrl:
'https://lh5.googleusercontent.com/HLOh5coHfcEgDuftj1pOA9f1865xiIom5vyxTWNMKqMiivxL8Lg4c9ACzbfYYUdeuqQ=w2400',
link: '/casestudyresource',
},
{
id: 2,
title: 'Ticketing System for Passengers',
imgUrl:
'https://lh5.googleusercontent.com/f_G0H0C_qLHhsU8PBj6uTkNigzKiXzd24B_pgJ6UqVmBKlU2Lyxv2r5lf6uvY9d_0PY=w2400',
link: '/casestudyticketing',
},
],
}
cards: [
{
id: 0,
title: 'Bi Healthcare Solution System',
imgUrl:
'https://lh6.googleusercontent.com/D7N87i3udAln4YBp5SbaSI-9r2pVnnT5K2VT6p0G3dQanVgTMC2tdgz71PWOYco-7yQ=w2400',
alt: 'Bi Healthcare Solution System',
link: '/casestudybi',
},
{
id: 1,
title: 'Resource Planning System',
imgUrl:
'https://lh5.googleusercontent.com/HLOh5coHfcEgDuftj1pOA9f1865xiIom5vyxTWNMKqMiivxL8Lg4c9ACzbfYYUdeuqQ=w2400',
alt: 'Resource Planning System',
link: '/casestudyresource',
},
{
id: 2,
title: 'Ticketing System for Passengers',
imgUrl:
'https://lh5.googleusercontent.com/f_G0H0C_qLHhsU8PBj6uTkNigzKiXzd24B_pgJ6UqVmBKlU2Lyxv2r5lf6uvY9d_0PY=w2400',
alt: 'Ticketing System for Passengers',
link: '/casestudyticketing',
},
],
};

function PortfolioSection() {
const linkTo = useNavigate();
const linkTo = useNavigate();

return (
<Wrapper padding={' py-90p'} bg>
<div className="py-32p">
<PageTitle left heading={'Case Studies'} subheading={'our Work'} />
</div>

return (
<Wrapper padding={" py-90p"} bg>
<div className='py-32p'>
<PageTitle left heading={"Case Studies"} subheading={"our Work"} />
</div>
<div className='flex flex-col lg:flex-row justify-center items-center lg:justify-between gap-8'>
{_data.cards.map((item,index) => (
<a className={"card max-w-780p box my-2 flex flex-col items-center"} href={item.link} key={index}>
<img src={item.imgUrl} className={'mb-12'}></img>
<div className="flex flex-col lg:flex-row justify-center items-center lg:justify-between gap-8">
{_data.cards.map((item, index) => (
<a
className={'card max-w-780p box my-2 flex flex-col items-center'}
href={item.link}
key={index}
>
<img src={item.imgUrl} alt={item.alt} className={'mb-12'}></img>
<h3 className="h3-heading">{item.title}</h3>
<button className="btn text-dg-secondary mt-4">Read More</button>
</a>
</a>
))}
</div>
<div className='flex justify-center text-center'>
<button className="btn text-dg-secondary mt-4" onClick={()=>linkTo('/portfolio')}>See More...</button>

</div>
</Wrapper>
)
</div>
<div className="flex justify-center text-center">
<button
className="btn text-dg-secondary mt-4"
onClick={() => linkTo('/portfolio')}
>
See More...
</button>
</div>
</Wrapper>
);
}

export default PortfolioSection;
export default PortfolioSection;

+ 107
- 76
frontend/src/components/Testimonials.jsx View File

@@ -1,86 +1,117 @@
import React, { Fragment, useEffect } from "react";
import useScreenDimensions from "../hooks/useScreenDimensions";
import Wrapper from "../layout/Wrapper";
import FMCarousel from "./shared/FMCarousel";
import HorizontalScroller from "./shared/HorizontalScroller";
import PageHeading from "./shared/PageHeading";
import PageTitle from "./shared/PageTitle";
import TestimonialCard from "./shared/TestimonialCard";
import Boza from "./../assets/boza.jpg"
import React, { Fragment, useEffect } from 'react';
import useScreenDimensions from '../hooks/useScreenDimensions';
import Wrapper from '../layout/Wrapper';
import FMCarousel from './shared/FMCarousel';
import HorizontalScroller from './shared/HorizontalScroller';
import PageHeading from './shared/PageHeading';
import PageTitle from './shared/PageTitle';
import TestimonialCard from './shared/TestimonialCard';
import Boza from './../assets/boza.jpg';
import Peter from './../assets/peter1.png';
import ns from './../assets/ns.png';

const _data = {
heading: "What Our Clients Said",
subheading: "Testimonials",
cards: [
{
clientName: "Peter Custer",
paragraph: "Diligent is a highly valuable resource in GBI's arsenal. Reliable, versatile and skilled. They are a true representation of their company name - following through the entire process of any task we challenged them with, meeting, and exceeding, expectations regardless of the project environment.",
clientRole: "CTO @ Gold Bullion International",
clientImg: Peter,
heading: 'What Our Clients Said',
subheading: 'Testimonials',
cards: [
{
clientName: 'Peter Custer',
paragraph:
"Diligent is a highly valuable resource in GBI's arsenal. Reliable, versatile and skilled. They are a true representation of their company name - following through the entire process of any task we challenged them with, meeting, and exceeding, expectations regardless of the project environment.",
clientRole: 'CTO @ Gold Bullion International',
clientImg: Peter,
alt: 'Peter Custer - CTO @ Gold Bullion International',
},
{
clientName: 'Božidar Ignjatović',
paragraph:
"Diligent team is my old and reliable partner. We've been working together for more than a decade. They are highly skilled professionals for any assigned job. Do not hesitate if you need support, Diligent brings additional value. They are not only tech team, they'll be partners to your business as they were for ours!",
clientRole: 'BadinSoft Co-Founder, CEO',
clientImg: Boza,
alt: 'Božidar Ignjatović - BadinSoft Co-Founder, CEO',
},
{
clientName: 'Niš Ekspres',
paragraph: `Our industry is susceptible, requiring the Information System to be reliable and flexible. Diligent helped us to build and integrate several parts of the existing Information System with multiple integration points and enabled fieldwork. Be assured that you can always count on the highest performance from Diligent, "around-the-clock" support and have a partner to your business.`,
clientRole: '',
clientImg: ns,
alt: 'Niš Ekspres',
},
],
};

},
{
clientName: "Božidar Ignjatović",
paragraph: "Diligent team is my old and reliable partner. We've been working together for more than a decade. They are highly skilled professionals for any assigned job. Do not hesitate if you need support, Diligent brings additional value. They are not only tech team, they'll be partners to your business as they were for ours!",
clientRole: "BadinSoft Co-Founder, CEO",
clientImg: Boza,
export default function Testimonials({ noTitle }) {
const screenSize = useScreenDimensions();

},
{
clientName: "Niš Ekspres",
paragraph: `Our industry is susceptible, requiring the Information System to be reliable and flexible. Diligent helped us to build and integrate several parts of the existing Information System with multiple integration points and enabled fieldwork. Be assured that you can always count on the highest performance from Diligent, "around-the-clock" support and have a partner to your business.`,
clientRole: "",
clientImg: ns,
return (
<Wrapper padding={' py-90p'}>
<div className="flex flex-col gap-32p md:gap-90p w-full">
{!noTitle && (
<div className="w-full">
<PageTitle heading={_data.heading} subheading={_data.subheading} left />
</div>
)}

},
]
}

export default function Testimonials({noTitle}) {
const screenSize = useScreenDimensions();

return (
<Wrapper padding={" py-90p"}>
<div className="flex flex-col gap-32p md:gap-90p w-full">
{!noTitle && (
<div className="w-full">
<PageTitle heading={_data.heading} subheading={_data.subheading} left />
</div>
)}

<div className="relative w-full h-[500px] overflow-hidden">
{screenSize.width > 1000 ?
<div className="relative w-full h-[500px] overflow-hidden">
{screenSize.width > 1000 ? (
<FMCarousel>
<div className="flex">
<TestimonialCard clientName={_data.cards[0].clientName} clientRole={_data.cards[0].clientRole} clientImg={_data.cards[0].clientImg} paragraph={_data.cards[0].paragraph}/>
<TestimonialCard clientName={_data.cards[1].clientName} clientRole={_data.cards[1].clientRole} clientImg={_data.cards[1].clientImg} paragraph={_data.cards[1].paragraph}/>
</div>
<div className="flex">
<TestimonialCard clientName={_data.cards[2].clientName} clientRole={_data.cards[2].clientRole} clientImg={_data.cards[2].clientImg} paragraph={_data.cards[2].paragraph}/>
</div>
{/*
<div className="flex">
<TestimonialCard
clientName={_data.cards[0].clientName}
clientRole={_data.cards[0].clientRole}
clientImg={_data.cards[0].clientImg}
imageAlt={_data.cards[0].alt}
paragraph={_data.cards[0].paragraph}
/>
<TestimonialCard
clientName={_data.cards[1].clientName}
clientRole={_data.cards[1].clientRole}
clientImg={_data.cards[1].clientImg}
imageAlt={_data.cards[1].alt}
paragraph={_data.cards[1].paragraph}
/>
</div>
<div className="flex">
<TestimonialCard
clientName={_data.cards[2].clientName}
clientRole={_data.cards[2].clientRole}
clientImg={_data.cards[2].clientImg}
imageAlt={_data.cards[2].alt}
paragraph={_data.cards[2].paragraph}
/>
</div>
{/*
<TestimonialCard/>
<TestimonialCard/>
*/}
</FMCarousel>
:
<FMCarousel>
<TestimonialCard clientName={_data.cards[0].clientName} clientRole={_data.cards[0].clientRole} clientImg={_data.cards[0].clientImg} paragraph={_data.cards[0].paragraph}/>
<TestimonialCard clientName={_data.cards[1].clientName} clientRole={_data.cards[1].clientRole} clientImg={_data.cards[1].clientImg} paragraph={_data.cards[1].paragraph}/>
<TestimonialCard clientName={_data.cards[2].clientName} clientRole={_data.cards[2].clientRole} clientImg={_data.cards[2].clientImg} paragraph={_data.cards[2].paragraph}/>
</FMCarousel>
}
</div>
</div>
</Wrapper>
)
}
*/}
</FMCarousel>
) : (
<FMCarousel>
<TestimonialCard
clientName={_data.cards[0].clientName}
clientRole={_data.cards[0].clientRole}
clientImg={_data.cards[0].clientImg}
imageAlt={_data.cards[0].alt}
paragraph={_data.cards[0].paragraph}
/>
<TestimonialCard
clientName={_data.cards[1].clientName}
clientRole={_data.cards[1].clientRole}
clientImg={_data.cards[1].clientImg}
imageAlt={_data.cards[1].alt}
paragraph={_data.cards[1].paragraph}
/>
<TestimonialCard
clientName={_data.cards[2].clientName}
clientRole={_data.cards[2].clientRole}
clientImg={_data.cards[2].clientImg}
imageAlt={_data.cards[2].alt}
paragraph={_data.cards[2].paragraph}
/>
</FMCarousel>
)}
</div>
</div>
</Wrapper>
);
}

+ 60
- 64
frontend/src/components/WhySection.jsx View File

@@ -1,74 +1,78 @@
import React from "react";
import React from 'react';

import { motion } from "framer-motion";
import OrbitOnScroll from "./shared/graphics/OrbitOnScroll";
import PageHeading from "./shared/PageHeading";
import WhyUsCard from "./WhyUsCard";
import { motion } from 'framer-motion';
import OrbitOnScroll from './shared/graphics/OrbitOnScroll';
import PageHeading from './shared/PageHeading';
import WhyUsCard from './WhyUsCard';

import why1 from './../assets/icons/why-us-1.svg';
import why2 from './../assets/icons/why-us-2.svg';
import why3 from './../assets/icons/why-us-3.svg';

import why1 from './../assets/icons/why-us-1.svg'
import why2 from './../assets/icons/why-us-2.svg'
import why3 from './../assets/icons/why-us-3.svg'

import Wrapper from '../layout/Wrapper'
import Wrapper from '../layout/Wrapper';

const api_url = process.env.REACT_APP_API_URL;


const _data = {
heading: {
subheading: "Why us",
heading:"Dedicated and Long-lasting Partnerships",
paragraph1: 'Committed and loyal we build long-lasting partnerships that go beyond technology. We believe that the key to a prosperous partnership is empathy and understanding.',
paragraph2: "We collaborate with Fortune 500 companies, innovative start-ups, and established industry leaders. We deliver specialized software solutions and services that enable businesses to expand and face tomorrow's problems by combining world-class engineering teams, sector knowledge, and technical experts.",
subheading: 'Why us',
heading: 'Dedicated and Long-lasting Partnerships',
paragraph1:
'Committed and loyal we build long-lasting partnerships that go beyond technology. We believe that the key to a prosperous partnership is empathy and understanding.',
paragraph2:
"We collaborate with Fortune 500 companies, innovative start-ups, and established industry leaders. We deliver specialized software solutions and services that enable businesses to expand and face tomorrow's problems by combining world-class engineering teams, sector knowledge, and technical experts.",
},
card_left: {
imgUrl: why1,
heading: "Innovative Solutions",
paragraph: "Technology is just one aspect of our client relationships. Enthusiasts to the core, we bring innovative and real-life solutions to each client’s problems through a deep understanding of their market, approach, and vision.",
alt: 'Innovative Solutions',
heading: 'Innovative Solutions',
paragraph:
'Technology is just one aspect of our client relationships. Enthusiasts to the core, we bring innovative and real-life solutions to each client’s problems through a deep understanding of their market, approach, and vision.',
},
card_mid: {
imgUrl: why2,
heading: "Product Discovery",
paragraph: "An idea solves a problem. We help you to create that idea, build a product and scale it to be successful in your business. We develop a roadmap to make sure the development is ready to begin constructing the MVP.",
alt: 'Product Discovery',
heading: 'Product Discovery',
paragraph:
'An idea solves a problem. We help you to create that idea, build a product and scale it to be successful in your business. We develop a roadmap to make sure the development is ready to begin constructing the MVP.',
},
card_right: {
imgUrl: why3,
heading: "End-user Engagement",
paragraph: "Our company helps clients to create a successful product. We focus on technical quality to ensure that products are up to standards and meet the needs of users. Innovation is key in developing products that are unique and valuable.",
}

}


const WhySection = ({data}) => {
alt: 'End-user Engagement',
heading: 'End-user Engagement',
paragraph:
'Our company helps clients to create a successful product. We focus on technical quality to ensure that products are up to standards and meet the needs of users. Innovation is key in developing products that are unique and valuable.',
},
};

return (
<Wrapper bg hideOverflow>
const WhySection = ({ data }) => {
return (
<Wrapper bg hideOverflow>
<div className="relative">
<div className="relative h-[1px] w-full m-auto">
<div className="absolute hidden lg:block" id="test" style={{ top: '800px', marginLeft: '-200px' }}>
<div
className="absolute hidden lg:block"
id="test"
style={{ top: '800px', marginLeft: '-200px' }}
>
<OrbitOnScroll />
</div>
</div>
</div>
<motion.section
id="why_us"
className=" flex flex-col items-center relative pt-164p pb-240p"
>


<motion.section
id="why_us"
className=" flex flex-col items-center relative pt-164p pb-240p"
>
<div className="flex flex-col justify-center items-center gap-90p">
<div className="max-w-[780px]">
<PageHeading
subheading={_data.heading.subheading}
heading={_data.heading.heading}
paragraph1={_data.heading.paragraph1}
paragraph2={_data.heading.paragraph2}
/>
<PageHeading
subheading={_data.heading.subheading}
heading={_data.heading.heading}
paragraph1={_data.heading.paragraph1}
paragraph2={_data.heading.paragraph2}
/>
</div>
<div className="flex flex-col lg:flex-row gap-32p h-fit sm:px-64p lg:px-0">
{/* Card - left */}
<motion.div
@@ -77,9 +81,8 @@ const WhySection = ({data}) => {
transition={{ delay: 0, default: { duration: 0.45 } }}
>
<WhyUsCard
image={
_data.card_left.imgUrl
}
image={_data.card_left.imgUrl}
alt={_data.card_left.alt}
heading={_data.card_left.heading}
paragraph={_data.card_left.paragraph}
/>
@@ -91,9 +94,8 @@ const WhySection = ({data}) => {
transition={{ delay: 0.27, default: { duration: 0.45 } }}
>
<WhyUsCard
image={
_data.card_mid.imgUrl
}
image={_data.card_mid.imgUrl}
alt={_data.card_mid.alt}
heading={_data.card_mid.heading}
paragraph={_data.card_mid.paragraph}
/>
@@ -105,24 +107,18 @@ const WhySection = ({data}) => {
transition={{ delay: 0.54, default: { duration: 0.45 } }}
>
<WhyUsCard
image={
_data.card_right.imgUrl
}
image={_data.card_right.imgUrl}
alt={_data.card_right.alt}
heading={_data.card_right.heading}
paragraph={_data.card_right.paragraph}
/>
</motion.div>
</div>
</div>


</motion.section>
</motion.section>
</div>
</Wrapper>

)
}
</Wrapper>
);
};

export default WhySection;
export default WhySection;

+ 3
- 2
frontend/src/components/WhyUsCard.jsx View File

@@ -5,10 +5,10 @@ export default function WhyUsCard(props) {
<div className="card-no-hover w-fit h-full flex flex-col text-center justify-between group">
<img
src={props.image}
alt="Card's Icon"
alt={props.alt}
className="ml-auto mr-auto block w-2/5 bg-baby-blue text-dark-gray rounded-full"
/>
<h3 className="mt-6 font-semibold text-title">{props.heading}</h3>
<h4 className="mt-6 font-semibold text-title">{props.heading}</h4>
<p className="mt-6 text-sm">{props.paragraph}</p>
</div>
);
@@ -16,6 +16,7 @@ export default function WhyUsCard(props) {

WhyUsCard.propTypes = {
image: propTypes.string,
alt: propTypes.string,
heading: propTypes.string,
paragraph: propTypes.string,
};

+ 41
- 29
frontend/src/components/shared/ClientForm.jsx View File

@@ -22,36 +22,45 @@ export default function ClientForm() {

const validationSchema = Yup.object({
subject: Yup.string()
.min(2, "Subject too short")
.max(50, "Subject too long")
.required('Subject is Required'),
.min(2, 'Subject too short')
.max(50, 'Subject too long')
.required('Subject is Required'),
email: Yup.string().email('Invalid email format').required('Email is Required'),
firstName: Yup.string().min(2, "First name too short")
.max(50, "First name too long").required('First Name is Required'),
lastName: Yup.string().min(2, "Last name too short")
.max(50, "Last name too long").required('Last Name is Required'),
description: Yup.string().trim().min(2, "Description too short").required('Description is Required'),
firstName: Yup.string()
.min(2, 'First name too short')
.max(50, 'First name too long')
.required('First Name is Required'),
lastName: Yup.string()
.min(2, 'Last name too short')
.max(50, 'Last name too long')
.required('Last Name is Required'),
description: Yup.string()
.trim()
.min(2, 'Description too short')
.required('Description is Required'),
});

return (
<div className="mt-10 sm:mt-0 mx-auto">
<div className="md:grid md:grid-cols-2 md:gap-6">
<motion.div className="mt-5 md:mt-0 md:col-span-1"
initial={{ x: -60, opacity: 0 }}
animate={{ x: 0, opacity: 1 }}
exit={{ x: -60, opacity: 0 }}
transition={{ duration: 0.3, ease: 'easeOut' }}>
<motion.div
className="mt-5 md:mt-0 md:col-span-1"
initial={{ x: -60, opacity: 0 }}
animate={{ x: 0, opacity: 1 }}
exit={{ x: -60, opacity: 0 }}
transition={{ duration: 0.3, ease: 'easeOut' }}
>
<Formik
initialValues={clientForm}
validationSchema={validationSchema}
onSubmit={values => {
const data = {
Tag: values.tag,
Subject: values.subject,
Email: values.email,
Firstname: values.firstName,
Lastname: values.lastName,
Description: values.description,
Tag: values.tag,
Subject: values.subject,
Email: values.email,
Firstname: values.firstName,
Lastname: values.lastName,
Description: values.description,
};

emailjs
@@ -205,10 +214,11 @@ export default function ClientForm() {
Submit
</button>
</div>
{sucMsg && <div className={'text-sm text-right text-dg-primary-900'}>
Submission Succesful! Thank you!
</div> }
{sucMsg && (
<div className={'text-sm text-right text-dg-primary-900'}>
Submission Succesful! Thank you!
</div>
)}
</div>

<div className="col-span-1 sm:col-span-1 lg:col-span-1"></div>
@@ -219,12 +229,14 @@ export default function ClientForm() {
)}
</Formik>
</motion.div>
<motion.div className="mt-5 md:mt-0 md:col-span-1 flex items-center"
initial={{ x: 60, opacity: 0 }}
animate={{ x: 0, opacity: 1 }}
exit={{ x: 60, opacity: 0 }}
transition={{ duration: 0.3, ease: 'easeOut' }}>
<img src={img} />
<motion.div
className="mt-5 md:mt-0 md:col-span-1 flex items-center"
initial={{ x: 60, opacity: 0 }}
animate={{ x: 0, opacity: 1 }}
exit={{ x: 60, opacity: 0 }}
transition={{ duration: 0.3, ease: 'easeOut' }}
>
<img src={img} alt="Our Team's image" />
</motion.div>
</div>
</div>

+ 14
- 7
frontend/src/components/shared/Footer.jsx View File

@@ -11,7 +11,6 @@ const footerText =
const copyrightText = 'Copyright © 2022. Diligent Software. All rights reserved.';

export default function Footer({ links, scrollToView, activeLinks }) {

const home = useNavigate();

function handleLogo() {
@@ -21,10 +20,8 @@ export default function Footer({ links, scrollToView, activeLinks }) {
function checkUrl(event) {
//console.log(location.pathname);

if (location.pathname === '/')
scrollToView(event);
else
home('/contact');
if (location.pathname === '/') scrollToView(event);
else home('/contact');
}

return (
@@ -35,7 +32,12 @@ export default function Footer({ links, scrollToView, activeLinks }) {
alt="Social Medias Background"
className="w-2/5 absolute opacity-50"
/>
<img src={logo} onClick={handleLogo} className=" w-16 pb-8 cursor-pointer" />
<img
src={logo}
alt="Diligent logo"
onClick={handleLogo}
className=" w-16 pb-8 cursor-pointer"
/>
<p className="text-sm text-gray-400 w-4/5 md:w-1/2 lg:w-1/3 text-center pb-8">
{footerText}
</p>
@@ -63,7 +65,12 @@ export default function Footer({ links, scrollToView, activeLinks }) {
</div>
</Popover.Group>
<SocialMediaLinks divWidth="2/5" iconSize="75" iconSizeHover="95" />
<a href="/privacypolicy" className="underline-offset-1 text-xs text-dg-primary-600 text-center cursor-pointer pt-8 z-20">Privacy Policy</a>
<a
href="/privacypolicy"
className="underline-offset-1 text-xs text-dg-primary-600 text-center cursor-pointer pt-8 z-20"
>
Privacy Policy
</a>
<p className="text-xs text-gray-400 text-center pt-8">{copyrightText}</p>
</div>
</div>

+ 20
- 13
frontend/src/components/shared/JobForm.jsx View File

@@ -55,12 +55,18 @@ export default function JobForm(props) {

const validationSchema = Yup.object({
email: Yup.string().email('Invalid email format').required('Email is Required'),
firstName: Yup.string().min(2, "First name too short")
.max(50, "First name too long").required('First Name is Required'),
lastName: Yup.string().min(2, "Last name too short")
.max(50, "Last name too long").required('Last name is Required'),
coverLetter: Yup.string().trim().min(2, "Cover Letter too short").required('Cover Letter is Required'),

firstName: Yup.string()
.min(2, 'First name too short')
.max(50, 'First name too long')
.required('First Name is Required'),
lastName: Yup.string()
.min(2, 'Last name too short')
.max(50, 'Last name too long')
.required('Last name is Required'),
coverLetter: Yup.string()
.trim()
.min(2, 'Cover Letter too short')
.required('Cover Letter is Required'),
});

return (
@@ -84,9 +90,8 @@ export default function JobForm(props) {
return null;
} else {
const base64 = await convertBase64(file);
return base64;
return base64;
}
};
const convertBase64 = file => {
//console.log(file);
@@ -120,7 +125,7 @@ export default function JobForm(props) {
Link: values.link,
File: res,
};
emailjs
.send(
process.env.REACT_APP_SERVICE_ID,
@@ -368,9 +373,11 @@ export default function JobForm(props) {
Submit
</button>
</div>
{sucMsg && <div className={'text-sm text-right text-dg-primary-900'}>
Submission Succesful! Thank you!
</div> }
{sucMsg && (
<div className={'text-sm text-right text-dg-primary-900'}>
Submission Succesful! Thank you!
</div>
)}
</div>

<div className="col-span-1 sm:col-span-1 lg:col-span-1"></div>
@@ -388,7 +395,7 @@ export default function JobForm(props) {
exit={{ x: 60, opacity: 0 }}
transition={{ duration: 0.3, ease: 'easeOut' }}
>
<img src={img} />
<img src={img} alt="Our Team's image" />
</motion.div>
</div>
</div>

+ 20
- 14
frontend/src/components/shared/Navigation.jsx View File

@@ -18,32 +18,36 @@ export default function Navigation({ links, scrollToView, activeLinks }) {
function checkUrl(event) {
//console.log(location.pathname);

if (location.pathname === '/')
scrollToView(event);
else
home('/contact');
if (location.pathname === '/') scrollToView(event);
else home('/contact');
}


return (

<Popover className="bg-white dark:bg-dg-primary-1700 fixed w-full top-0 z-50">
<Wrapper>
<div className="flex justify-between items-center border-gray-100 dark:border-dg-primary-1800 py-6 md:space-x-10">
<div className="flex justify-start lg:w-0 lg:flex-1">
<a href="#">
<span className="sr-only">Diligent</span>
<img className="h-8 w-auto sm:h-10" src={logo} alt="diligent" onClick={()=>handleLogo()} />
<img
className="h-8 w-auto sm:h-10"
src={logo}
alt="Diligent logo"
onClick={() => handleLogo()}
/>
</a>
</div>
<div className="mr-2 -my-2 md:hidden">
<Popover.Button className="bg-white rounded-md p-2 inline-flex items-center justify-center text-dg-primary-900 focus:outline-none">
<img src={menuIcon} className='h-[30px]'/>
<img src={menuIcon} alt="Menu" className="h-[30px]" />
{/*<span className="sr-only">Open menu</span>
<div className="h-6 w-6" aria-hidden="true" />*/}
</Popover.Button>
</div>
<Popover.Group as="nav" className="hidden md:flex space-x-8 lg:space-x-10 items-center">
<Popover.Group
as="nav"
className="hidden md:flex space-x-8 lg:space-x-10 items-center"
>
{links.map(item => (
<NavLink
key={item.name}
@@ -96,7 +100,12 @@ export default function Navigation({ links, scrollToView, activeLinks }) {
<div className="pt-5 pb-6 px-5">
<div className="flex items-center justify-between">
<div>
<img className="h-8 w-auto cursor-pointer" src={logo} alt="Diligent" onClick={()=>handleLogo()} />
<img
className="h-8 w-auto cursor-pointer"
src={logo}
alt="Diligent"
onClick={() => handleLogo()}
/>
</div>
<div className="-mr-2">
<Popover.Button className="bg-white rounded-md p-2 inline-flex items-center justify-center transition-all text-dg-primary-900 hover:text-white hover:transition-all hover:bg-dg-primary-900 focus:outline-none">
@@ -115,9 +124,7 @@ export default function Navigation({ links, scrollToView, activeLinks }) {
to={item.href}
className="text-p p-3 flex justify-center items-center rounded-md transition-all hover:transition-all hover:bg-dg-primary-900 hover:text-white"
>
<div
aria-hidden="true"
/>
<div aria-hidden="true" />
<span className="ml-3 text-base font-medium text-inherit">
{item.name}
</span>
@@ -131,7 +138,6 @@ export default function Navigation({ links, scrollToView, activeLinks }) {
}}
className="contact-us-link flex justify-center items-center text-p"
>

<span className="ml-3 text-base font-medium text-inherit">
Contact
</span>

+ 2
- 2
frontend/src/components/shared/PageHeading.jsx View File

@@ -3,8 +3,8 @@ import propTypes from 'prop-types';
export default function PageHeading(props) {
return (
<div className="flex flex-col gap-8p items-center justify-center">
<h6 className="subheading">{props.subheading}</h6>
<h1 className="heading text-center">{props.heading}</h1>
<h2 className="subheading">{props.subheading}</h2>
<h3 className="heading text-center">{props.heading}</h3>
<div className="flex flex-col gap-16p">
<p className="paragraph text-start">{props.paragraph1}</p>
<p className="paragraph text-start">{props.paragraph2}</p>

+ 24
- 17
frontend/src/components/shared/PageTitle.jsx View File

@@ -1,22 +1,29 @@
import React from "react";
import PropTypes from 'prop-types'
import React from 'react';
import PropTypes from 'prop-types';

const PageTitle = ({heading, subheading, left, color,pb}) => {
return (
<div className={"flex flex-col gap-8p"+ (left ? " text-left items-start":" text-center items-center") + (color ? " title-colored" : " ") + (pb ? ' pb-2' :' ')}>
<h6 className={"subheading" + (left ? " text-left":" text-center")}>{subheading}</h6>
<h1 className={"heading" + (left ? " text-left":" text-center")}>{heading}</h1>
</div>
)
}
const PageTitle = ({ heading, subheading, left, color, pb }) => {
return (
<div
className={
'flex flex-col gap-8p' +
(left ? ' text-left items-start' : ' text-center items-center') +
(color ? ' title-colored' : ' ') +
(pb ? ' pb-2' : ' ')
}
>
<h2 className={'subheading' + (left ? ' text-left' : ' text-center')}>
{subheading}
</h2>
<h3 className={'heading' + (left ? ' text-left' : ' text-center')}>{heading}</h3>
</div>
);
};

PageTitle.propTypes = {
heading: PropTypes.string,
subheading: PropTypes.string,
left: PropTypes.bool,
color: PropTypes.bool,
}
heading: PropTypes.string,
subheading: PropTypes.string,
left: PropTypes.bool,
color: PropTypes.bool,
};

export default PageTitle;



+ 37
- 47
frontend/src/components/shared/ProcessFacelessSlider.jsx View File

@@ -1,66 +1,56 @@
import React from 'react'
import PropTypes from 'prop-types'
import { Slide, SliderButton, SliderProvider, SliderTrack } from '@faceless-ui/slider'
import {ReactComponent as CircleArrow } from '../../assets/icons/CircleArrow.svg';
import React from 'react';
import PropTypes from 'prop-types';
import { Slide, SliderButton, SliderProvider, SliderTrack } from '@faceless-ui/slider';
import { ReactComponent as CircleArrow } from '../../assets/icons/CircleArrow.svg';

import ProcessSvgPart1 from './../../assets/ProcessPart1.svg';
import ProcessSvgPart2 from './../../assets/ProcessPart2.svg';
import ProcessSvgPart3 from './../../assets/ProcessPart3.svg';

const slides = [
ProcessSvgPart1, ProcessSvgPart2, ProcessSvgPart3
]

const slides = [ProcessSvgPart1, ProcessSvgPart2, ProcessSvgPart3];

const ProcessFacelessSlider = props => {

return (
<SliderProvider
slidesToShow={1}
scrollSnap
dragScroll
>
<div className={""}>
{/* <SliderButton direction="prev">
return (
<SliderProvider slidesToShow={1} scrollSnap dragScroll>
<div className={''}>
{/* <SliderButton direction="prev">
Previous
</SliderButton>
<SliderButton direction="next">
Next
</SliderButton> */}
</div>
<div className='rounded-xl overflow-hidden mt-4'>
<SliderTrack className={" track h-full mt-10 rounded-xl"}>
{slides.map((slide, index) => (
<Slide
key={index}
index={index}
className={"h-full"}
>
<img src={slide} className={'h-full mx-auto'}></img>
</Slide>
))}
</SliderTrack>
</div>
<div className='flex justify-between w-2/5 mt-8 mx-auto'>
</div>
<div className="rounded-xl overflow-hidden mt-4">
<SliderTrack className={' track h-full mt-10 rounded-xl'}>
{slides.map((slide, index) => (
<Slide key={index} index={index} className={'h-full'}>
<img
src={slide}
alt={`step ${index + 1}`}
className={'h-full mx-auto'}
></img>
</Slide>
))}
</SliderTrack>
</div>
<div className="flex justify-between w-2/5 mt-8 mx-auto">
<SliderButton direction="prev">
<CircleArrow />
</SliderButton>
<SliderButton direction="next">
<CircleArrow className='rotate-180' />
</SliderButton>
</div>
{/* <DotsNav
<CircleArrow />
</SliderButton>
<SliderButton direction="next">
<CircleArrow className="rotate-180" />
</SliderButton>
</div>
{/* <DotsNav
className={"dots"}
dotClassName={"dot"}
activeDotClassName={"dotIsActive"}
/> */}
</SliderProvider>
)
}
</SliderProvider>
);
};

ProcessFacelessSlider.propTypes = {}
ProcessFacelessSlider.propTypes = {};

export default ProcessFacelessSlider
export default ProcessFacelessSlider;

+ 36
- 24
frontend/src/components/shared/TestimonialCard/index.jsx View File

@@ -1,27 +1,39 @@
import React from "react";
import { ReactComponent as TestemonialsSVG } from "../../../assets/graphics/TestemonialsSVG.svg";
import React from 'react';
import { ReactComponent as TestemonialsSVG } from '../../../assets/graphics/TestemonialsSVG.svg';

export default function TestimonialCard({
paragraph,
clientName,
clientRole,
clientImg,
imageAlt,
}) {
const cardClassList =
'px-12 py-12 bg-white dark:bg-dg-primary-1700 text-dark-gray dark:text-white shadow-md dark:border-dg-primary-1500 dark:border-solid dark:border text-center rounded-xl';

export default function TestimonialCard({paragraph, clientName, clientRole, clientImg}) {
const cardClassList = 'px-12 py-12 bg-white dark:bg-dg-primary-1700 text-dark-gray dark:text-white shadow-md dark:border-dg-primary-1500 dark:border-solid dark:border text-center rounded-xl';
return (
<div className="relative h-fit md:mr-90p">
<div className="absolute z-20 -bottom-[120px] -right-[90px] hidden md:block">
<TestemonialsSVG />
<div className="absolute top-0 bottom-0 left-0 right-0 flex justify-center items-center">
<img src={clientImg} className='mx-auto' style={{margin: '2px 2px 40px 20px', height:64, width:64, borderRadius:'50%'}}/>
</div>
</div>
<div className={cardClassList + ' flex flex-col justify-between max-w-[460px]'}>
<p className="text-p-italic italic text-gray-500">"{paragraph}"</p>
<h4 className="text-dg-primary-900">{clientName}</h4>
<p>{clientRole}</p>
</div>
return (
<div className="relative h-fit md:mr-90p">
<div className="absolute z-20 -bottom-[120px] -right-[90px] hidden md:block">
<TestemonialsSVG />
<div className="absolute top-0 bottom-0 left-0 right-0 flex justify-center items-center">
<img
src={clientImg}
alt={imageAlt}
className="mx-auto"
style={{
margin: '2px 2px 40px 20px',
height: 64,
width: 64,
borderRadius: '50%',
}}
/>
</div>
)
}
</div>
<div className={cardClassList + ' flex flex-col justify-between max-w-[460px]'}>
<p className="text-p-italic italic text-gray-500">"{paragraph}"</p>
<h4 className="text-dg-primary-900">{clientName}</h4>
<p>{clientRole}</p>
</div>
</div>
);
}

+ 7991
- 8224
frontend/yarn.lock
File diff suppressed because it is too large
View File


Loading…
Cancel
Save