Pavle Golubovic 3 лет назад
Родитель
Сommit
64319d2187
100 измененных файлов: 5957 добавлений и 1855 удалений
  1. 2
    0
      frontend/.env
  2. 2
    2
      frontend/package-lock.json
  3. 1
    1
      frontend/package.json
  4. 0
    0
      frontend/public/DiligentCompanyOverview.pdf
  5. 11
    0
      frontend/public/index.html
  6. 1
    0
      frontend/public/robots.txt
  7. 15
    0
      frontend/public/sitemap.txt
  8. 49
    82
      frontend/src/App.js
  9. 0
    0
      frontend/src/assets/docs/DiligentCompanyOverview.pdf
  10. 6
    0
      frontend/src/assets/download-icon.svg
  11. 7
    0
      frontend/src/assets/icons/workwithus/bus.svg
  12. 8
    0
      frontend/src/assets/icons/workwithus/empty-wallet-tick.svg
  13. 7
    0
      frontend/src/assets/icons/workwithus/hospital.svg
  14. 5
    0
      frontend/src/assets/icons/workwithus/teacher.svg
  15. 28
    23
      frontend/src/components/CardsGrid.jsx
  16. 23
    22
      frontend/src/components/CareerCard.jsx
  17. 21
    33
      frontend/src/components/Landing.jsx
  18. 10
    10
      frontend/src/components/OpenDayBanner.jsx
  19. 17
    19
      frontend/src/components/PortfolioCard.jsx
  20. 61
    58
      frontend/src/components/PortfolioSection.jsx
  21. 1
    1
      frontend/src/components/ProcessSection.jsx
  22. 107
    73
      frontend/src/components/Testimonials.jsx
  23. 23
    20
      frontend/src/components/TimelineCard.jsx
  24. 60
    64
      frontend/src/components/WhySection.jsx
  25. 3
    2
      frontend/src/components/WhyUsCard.jsx
  26. 22
    0
      frontend/src/components/root/CustomLink.jsx
  27. 9
    0
      frontend/src/components/root/TertiaryButton.jsx
  28. 8
    8
      frontend/src/components/shared/CardLife.jsx
  29. 30
    19
      frontend/src/components/shared/ClientForm.jsx
  30. 27
    33
      frontend/src/components/shared/FacelessSlider/FacelessSlider.jsx
  31. 20
    12
      frontend/src/components/shared/Footer.jsx
  32. 19
    12
      frontend/src/components/shared/JobForm.jsx
  33. 35
    28
      frontend/src/components/shared/Navigation.jsx
  34. 2
    2
      frontend/src/components/shared/PageHeading.jsx
  35. 1
    1
      frontend/src/components/shared/PageTitle.jsx
  36. 31
    18
      frontend/src/components/shared/ProcessCard.jsx
  37. 37
    47
      frontend/src/components/shared/ProcessFacelessSlider.jsx
  38. 0
    6
      frontend/src/components/shared/SocialMediaLinks.jsx
  39. 2
    2
      frontend/src/components/shared/TechNuggets.jsx
  40. 36
    24
      frontend/src/components/shared/TestimonialCard/index.jsx
  41. 16
    0
      frontend/src/hooks/useAnalytics.js
  42. 0
    1
      frontend/src/hooks/useWindowSize.js
  43. 0
    2
      frontend/src/index.js
  44. 210
    201
      frontend/src/pages/About.jsx
  45. 58
    30
      frontend/src/pages/Careers.jsx
  46. 8
    0
      frontend/src/pages/CaseStudy.jsx
  47. 135
    134
      frontend/src/pages/CaseStudyBI.jsx
  48. 39
    38
      frontend/src/pages/CaseStudyCentralized.jsx
  49. 135
    135
      frontend/src/pages/CaseStudyFinantial.jsx
  50. 132
    134
      frontend/src/pages/CaseStudyResource.jsx
  51. 142
    147
      frontend/src/pages/CaseStudyStrata.jsx
  52. 135
    131
      frontend/src/pages/CaseStudyTicketing.jsx
  53. 5
    12
      frontend/src/pages/ContactPage.jsx
  54. 34
    111
      frontend/src/pages/Portfolio.jsx
  55. 3
    0
      frontend/src/pages/PrivacyPolicy.jsx
  56. 123
    137
      frontend/src/pages/ProcessPage.jsx
  57. 219
    0
      frontend/src/pages/WorkWithUs.jsx
  58. 109
    0
      frontend/src/routes.js
  59. 18
    19
      frontend/src/styles/text.css
  60. 6
    1
      frontend/tailwind.config.js
  61. 12
    0
      node_modules/.bin/loose-envify
  62. 17
    0
      node_modules/.bin/loose-envify.cmd
  63. 28
    0
      node_modules/.bin/loose-envify.ps1
  64. 72
    0
      node_modules/.package-lock.json
  65. 151
    0
      node_modules/js-tokens/CHANGELOG.md
  66. 21
    0
      node_modules/js-tokens/LICENSE
  67. 240
    0
      node_modules/js-tokens/README.md
  68. 23
    0
      node_modules/js-tokens/index.js
  69. 30
    0
      node_modules/js-tokens/package.json
  70. 21
    0
      node_modules/loose-envify/LICENSE
  71. 45
    0
      node_modules/loose-envify/README.md
  72. 16
    0
      node_modules/loose-envify/cli.js
  73. 4
    0
      node_modules/loose-envify/custom.js
  74. 3
    0
      node_modules/loose-envify/index.js
  75. 36
    0
      node_modules/loose-envify/loose-envify.js
  76. 36
    0
      node_modules/loose-envify/package.json
  77. 65
    0
      node_modules/loose-envify/replace.js
  78. 90
    0
      node_modules/object-assign/index.js
  79. 21
    0
      node_modules/object-assign/license
  80. 42
    0
      node_modules/object-assign/package.json
  81. 61
    0
      node_modules/object-assign/readme.md
  82. 21
    0
      node_modules/prop-types/LICENSE
  83. 302
    0
      node_modules/prop-types/README.md
  84. 103
    0
      node_modules/prop-types/checkPropTypes.js
  85. 19
    0
      node_modules/prop-types/factory.js
  86. 65
    0
      node_modules/prop-types/factoryWithThrowingShims.js
  87. 610
    0
      node_modules/prop-types/factoryWithTypeCheckers.js
  88. 19
    0
      node_modules/prop-types/index.js
  89. 12
    0
      node_modules/prop-types/lib/ReactPropTypesSecret.js
  90. 1
    0
      node_modules/prop-types/lib/has.js
  91. 60
    0
      node_modules/prop-types/package.json
  92. 1315
    0
      node_modules/prop-types/prop-types.js
  93. 1
    0
      node_modules/prop-types/prop-types.min.js
  94. 6
    0
      node_modules/react-ga/.eslintignore
  95. 58
    0
      node_modules/react-ga/.eslintrc.js
  96. 23
    0
      node_modules/react-ga/.github/workflows/release.yml
  97. 26
    0
      node_modules/react-ga/.github/workflows/tests.yml
  98. 4
    0
      node_modules/react-ga/.husky/commit-msg
  99. 4
    0
      node_modules/react-ga/.husky/pre-commit
  100. 0
    0
      node_modules/react-ga/.lintstagedrc.js

+ 2
- 0
frontend/.env Просмотреть файл

@@ -1,3 +1,4 @@
PUBLIC_URL = "https://dilig.net"
FAST_REFRESH=false
CHOKIDAR_USEPOLLING=true
REACT_APP_SERVICE_ID = service_petbzsz
@@ -7,3 +8,4 @@ REACT_APP_USER_ID = 27spvSZ2Lsf2j8RKw
REACT_APP_API_URL = "https://websitediligentapi.azurewebsites.net"
//http://localhost:1337
MAILCHIMP_FORM_URL = http://eepurl.com/iaRrv1
GOOGLE_TRACKING_ID = "G-PTZC3WLTZ1"

+ 2
- 2
frontend/package-lock.json Просмотреть файл

@@ -1,12 +1,12 @@
{
"name": "frontend",
"version": "1.0.6",
"version": "1.0.20",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "frontend",
"version": "1.0.6",
"version": "1.0.20",
"dependencies": {
"@faceless-ui/slider": "^1.1.14",
"@faceless-ui/window-info": "^2.1.1",

+ 1
- 1
frontend/package.json Просмотреть файл

@@ -1,6 +1,6 @@
{
"name": "frontend",
"version": "1.0.6",
"version": "1.1.0",
"private": true,
"dependencies": {
"@faceless-ui/slider": "^1.1.14",

+ 0
- 0
frontend/public/DiligentCompanyOverview.pdf Просмотреть файл


+ 11
- 0
frontend/public/index.html Просмотреть файл

@@ -25,6 +25,17 @@
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>Diligent Software</title>

<!-- Google tag (gtag.js) -->
<!-- <script async src='https://www.googletagmanager.com/gtag/js?id=G-PTZC3WLTZ1'></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
gtag('js', new Date());
gtag('config', 'G-PTZC3WLTZ1');
</script> -->

</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>

+ 1
- 0
frontend/public/robots.txt Просмотреть файл

@@ -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 Просмотреть файл

@@ -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

+ 49
- 82
frontend/src/App.js Просмотреть файл

@@ -1,73 +1,54 @@
import React, { useEffect } from 'react';
import React, { useEffect, lazy, Suspense, useRef, useState } 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 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 Loader from './components/shared/Loader';
import ScrollToTop from './components/root/ScrollToTop';

import routes from './routes';


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 = [
{
name: 'Case Studies',
description: '',
href: '/portfolio',
icon: '',
},
{
name: 'Process',
description: '',
href: '/process',
icon: '',
},
{
name: 'Careers',
description: '',
href: '/careers',
icon: '',
},
{
name: 'About us',
description: '',
href: '/about',
icon: '',
},
];
const links = routes.filter(item => item.nav === true);

function App() {


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);

//initialize analytics page tracking
//usePageTracking();

//scroll to Contact fn
function scrollToView(event) {
event.preventDefault();
if (forwardedRef) {
forwardedRef.current.scrollIntoView({ behavior: 'smooth' });
}
else {
} else {
link('/contact');
}
}
@@ -83,44 +64,32 @@ function App() {
}

return (

<div>
<ScrollToTop />
<Navigation
links={links}
scrollToView={scrollToView}
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 />} />
</Routes>
<Suspense fallback={<Loader />}>
<Routes>
<Route exact path="/" element={<Home />}/>
<Route exact path="/workwithus" element={<WorkWithUs />}/>
<Route exact path="/portfolio" element={<Portfolio />}/>
<Route exact path="/process" element={<ProcessPage />}/>
<Route exact path="/careers" element={<Careers />}/>
<Route exact path="/about" element={<About />}/>
<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}
@@ -128,9 +97,7 @@ function App() {
scrollToView={scrollToView}
forwardedRef={forwardedRef}
/>

</div>

);
}


+ 0
- 0
frontend/src/assets/docs/DiligentCompanyOverview.pdf Просмотреть файл


+ 6
- 0
frontend/src/assets/download-icon.svg Просмотреть файл

@@ -0,0 +1,6 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9 22H15C20 22 22 20 22 15V9C22 4 20 2 15 2H9C4 2 2 4 2 9V15C2 20 4 22 9 22Z" stroke="#FAFAFA" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M9 11.5098L12 14.5098L15 11.5098" stroke="#FAFAFA" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 14.5098V6.50977" stroke="#FAFAFA" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6 16.5098C9.89 17.8098 14.11 17.8098 18 16.5098" stroke="#FAFAFA" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

+ 7
- 0
frontend/src/assets/icons/workwithus/bus.svg Просмотреть файл

@@ -0,0 +1,7 @@
<svg width="80" height="81" viewBox="0 0 80 81" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M56.334 73.8327H23.6673C18.0007 73.8327 13.334 69.1993 13.334 63.4993V17.4994C13.334 11.8327 17.9673 7.16602 23.6673 7.16602H56.334C62.0006 7.16602 66.6673 11.7994 66.6673 17.4994V63.4993C66.6673 69.1993 62.034 73.8327 56.334 73.8327Z" stroke="#902890" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M61.6673 43.8327H18.334C15.5673 43.8327 13.334 41.5993 13.334 38.8327V32.166C13.334 29.3993 15.5673 27.166 18.334 27.166H61.6673C64.434 27.166 66.6673 29.3993 66.6673 32.166V38.8327C66.6673 41.5993 64.434 43.8327 61.6673 43.8327Z" stroke="#902890" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M28.3144 59.5007H28.3443" stroke="#902890" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M51.6484 59.5007H51.6783" stroke="#902890" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M31.666 17.166H48.3327" stroke="#902890" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

+ 8
- 0
frontend/src/assets/icons/workwithus/empty-wallet-tick.svg Просмотреть файл

@@ -0,0 +1,8 @@
<svg width="80" height="81" viewBox="0 0 80 81" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M60.134 45.6673C58.734 47.0339 57.934 49.0006 58.134 51.1006C58.434 54.7006 61.734 57.3339 65.334 57.3339H71.6673V61.3006C71.6673 68.2006 66.034 73.834 59.134 73.834H25.434C26.4673 72.9673 27.3673 71.9006 28.0673 70.7006C29.3006 68.7006 30.0007 66.334 30.0007 63.834C30.0007 56.4673 24.034 50.5007 16.6673 50.5007C13.534 50.5007 10.634 51.6007 8.33398 53.434V38.8673C8.33398 31.9674 13.9673 26.334 20.8673 26.334H59.134C66.034 26.334 71.6673 31.9674 71.6673 38.8673V43.6674H64.934C63.0673 43.6674 61.3673 44.4006 60.134 45.6673Z" stroke="#902890" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8.33398 41.8663V26.6332C8.33398 22.6665 10.7673 19.133 14.4673 17.733L40.934 7.73305C45.0673 6.16638 49.5007 9.23314 49.5007 13.6665V26.3331" stroke="#902890" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M75.1967 47.0678V53.9347C75.1967 55.768 73.73 57.2679 71.8633 57.3346H65.33C61.73 57.3346 58.43 54.7012 58.13 51.1012C57.93 49.0012 58.73 47.0346 60.13 45.6679C61.3633 44.4012 63.0633 43.668 64.93 43.668H71.8633C73.73 43.7346 75.1967 45.2345 75.1967 47.0678Z" stroke="#902890" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M23.334 40.5H46.6673" stroke="#902890" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M30.0007 63.8333C30.0007 66.3333 29.3006 68.7 28.0673 70.7C27.3673 71.9 26.4673 72.9667 25.434 73.8333C23.1007 75.9333 20.034 77.1667 16.6673 77.1667C11.8007 77.1667 7.56732 74.5667 5.26732 70.7C4.03399 68.7 3.33398 66.3333 3.33398 63.8333C3.33398 59.6333 5.26732 55.8667 8.33398 53.4333C10.634 51.6 13.534 50.5 16.6673 50.5C24.034 50.5 30.0007 56.4667 30.0007 63.8333Z" stroke="#902890" stroke-width="4" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11.4727 63.8311L14.7726 67.131L21.8726 60.5645" stroke="#902890" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

+ 7
- 0
frontend/src/assets/icons/workwithus/hospital.svg Просмотреть файл

@@ -0,0 +1,7 @@
<svg width="80" height="81" viewBox="0 0 80 81" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.66602 73.834H73.3326" stroke="#902890" stroke-width="4" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M56.6667 7.16602H23.3333C13.3333 7.16602 10 13.1327 10 20.4993V73.8326H70V20.4993C70 13.1327 66.6667 7.16602 56.6667 7.16602Z" stroke="#902890" stroke-width="4" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M46.8668 50.5H33.1001C31.4001 50.5 29.9668 51.9 29.9668 53.6333V73.8333H49.9668V53.6333C50.0001 51.9 48.6001 50.5 46.8668 50.5Z" stroke="#902890" stroke-width="4" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M40 20.5V37.1667" stroke="#902890" stroke-width="4" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M31.666 28.834H48.3327" stroke="#902890" stroke-width="4" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

+ 5
- 0
frontend/src/assets/icons/workwithus/teacher.svg Просмотреть файл

@@ -0,0 +1,5 @@
<svg width="80" height="81" viewBox="0 0 80 81" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M33.4991 8.93296L13.4324 22.033C6.99909 26.233 6.99909 35.633 13.4324 39.833L33.4991 52.933C37.0991 55.2996 43.0324 55.2996 46.6324 52.933L66.5991 39.833C72.9991 35.633 72.9991 26.2663 66.5991 22.0663L46.6324 8.9663C43.0324 6.5663 37.0991 6.5663 33.4991 8.93296Z" stroke="#902890" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M18.7658 44.0996L18.7324 59.7329C18.7324 63.9663 21.9991 68.4996 25.9991 69.8329L36.6324 73.3663C38.4658 73.9663 41.4991 73.9663 43.3658 73.3663L53.9991 69.8329C57.9991 68.4996 61.2658 63.9663 61.2658 59.7329V44.2663" stroke="#902890" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M71.334 50.5V30.5" stroke="#902890" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

+ 28
- 23
frontend/src/components/CardsGrid.jsx Просмотреть файл

@@ -1,28 +1,33 @@
import React, { useEffect, useState } from "react";
import Grid from "../layout/Grid";
import PortfolioCard from "./PortfolioCard";
import React, { useEffect, useState } from 'react';
import Grid from '../layout/Grid';
import PortfolioCard from './PortfolioCard';

const api_url = process.env.REACT_APP_API_URL;

const CardsGrid = ({data}) => {
const [state, setState] = useState(data);
const CardsGrid = ({ data }) => {
const [state, setState] = useState(data);

useEffect(() => {
setState(data);
}, [data]);

useEffect(() => {
setState(data);
}, [data]);

return (
<div className="grid overflow-visible grid-cols-1 md:grid-cols-2 lg:grid-cols-3 auto-rows-auto gap-8">
{ state &&
state.length > 0 &&
state.map ((item, index) => (
// item.attributes.img.data != null &&
// <PortfolioCard key={index} title={item.attributes.heading} img={api_url + item.attributes.img.data.attributes.formats.small.url} isLarge={item.attributes.IsLarge} />
<PortfolioCard key={index} title={item.title} isLarge={false} link={item.link} img={item.imgUrl} />
))
}
</div>
)
}
export default CardsGrid;
return (
<div className="grid overflow-visible grid-cols-1 md:grid-cols-2 lg:grid-cols-3 auto-rows-auto gap-8">
{state &&
state.length > 0 &&
state.map((item, index) => (
// item.attributes.img.data != null &&
// <PortfolioCard key={index} title={item.attributes.heading} img={api_url + item.attributes.img.data.attributes.formats.small.url} isLarge={item.attributes.IsLarge} />
<PortfolioCard
key={index}
title={item.title}
alt={item.alt}
isLarge={false}
link={item.link}
img={item.imgUrl}
/>
))}
</div>
);
};
export default CardsGrid;

+ 23
- 22
frontend/src/components/CareerCard.jsx Просмотреть файл

@@ -1,41 +1,42 @@
import React from 'react'
import PropTypes from 'prop-types'
import React from 'react';
import PropTypes from 'prop-types';
import net from './../assets/icons/net.svg';

const _card = {
role: ".Net Developer",
shortDetails: "All levels of experience",
}
role: '.Net Developer',
shortDetails: 'All levels of experience',
};

const CareerCard = ({card ,setExpanded, setExpandedCard}) => {
const CareerCard = ({ card, setExpanded, setExpandedCard }) => {
return (
<div onClick={() => {setExpanded(true);setExpandedCard(card)}} className={'card max-w-[360px]'}>
<div
onClick={() => {
setExpanded(true);
setExpandedCard(card);
}}
className={'card max-w-[360px]'}
>
<img
src={net}
className={
'ml-auto mr-auto block w-[70px] bg-baby-blue text-dark-gray'
}
alt=".NET"
className={'ml-auto mr-auto block w-[70px] bg-baby-blue text-dark-gray'}
/>
<h3 className={'mt-6 font-semibold text-2xl'}>
{card.role}
</h3>
<h3 className={'mt-6 font-semibold text-2xl'}>{card.role}</h3>
<p className={'mt-6 text-sm'}>{_card.shortDetails}</p>
<a
href={'#'}
className={'min-w-max btn btn_primary mt-8 opacity-0 transition-all group-hover:opacity-100 group-hover:transition-all'
className={
'min-w-max btn btn_primary mt-8 opacity-0 transition-all group-hover:opacity-100 group-hover:transition-all'
}
>
Read More
</a>
</div>
)
}
);
};

CareerCard.propTypes = {
card: PropTypes.object,
}
card: PropTypes.object,
};

export default CareerCard
export default CareerCard;

+ 21
- 33
frontend/src/components/Landing.jsx Просмотреть файл

@@ -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 /> */}
@@ -65,7 +62,6 @@ const Landing = ({ data }) => {
{_data.cto}
</a>
</div>

</motion.section>
<motion.section
id="status-numbers"
@@ -76,25 +72,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;

+ 10
- 10
frontend/src/components/OpenDayBanner.jsx Просмотреть файл

@@ -3,19 +3,19 @@ import './../App.css'


export default function OpenDayBanner() {
const [isHover,setHover] = useState(false);
const [isHover, setHover] = useState(false);

return (
<a href="/openday">
<div className={"bg-[#7274AB] size-07 absolute left-[-25px] top-[-50px] rounded-full md:top-[-15px] md:left-0 transition-all px-6 py-2 b-50"+(isHover ? " md:scale-125" : "")} onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}>
<div className={"relative flex justify-center items-center"}>
<h2 className={"uppercase text-sm z-10 text-white transition-all"}>Open Day - October 26 !</h2>
</div>
<div className={"bg-[#7274AB] size-07 absolute left-[-25px] top-[-50px] rounded-full md:top-[-15px] md:left-0 transition-all px-6 py-2 b-50" + (isHover ? " md:scale-125" : "")} onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}>
<div className={"relative flex justify-center items-center"}>
<h2 className={"uppercase text-sm z-10 text-white transition-all"}>Open Day - October 26 !</h2>
</div>
</div>
</a>
</a>
)
}

+ 17
- 19
frontend/src/components/PortfolioCard.jsx Просмотреть файл

@@ -1,25 +1,23 @@
import React, { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";

import React, { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';

const api_url = process.env.REACT_APP_API_URL;

const PortfolioCard = ({title, isLarge, link, img}) => {

const linkTo = useNavigate();
const PortfolioCard = ({ title, isLarge, link, img, alt }) => {
const linkTo = useNavigate();

useEffect(() => {
//console.log(isLarge);
})
useEffect(() => {
//console.log(isLarge);
});

return (
// <div className={"card box" + (isLarge ? ' col-span-2' : '')}>
<a className={"card box my-2 flex- flex-col items-center"} href={link}>
<img src={img} className={'mb-12 mx-auto self-center'}></img>
<h3 className="h3-heading">{title}</h3>
<button className="btn text-dg-secondary mt-4">Read More</button>
</a>
)
}
return (
// <div className={"card box" + (isLarge ? ' col-span-2' : '')}>
<a className={'card box my-2 flex- flex-col items-center'} href={link}>
<img src={img} alt={alt} className={'mb-12 mx-auto self-center'}></img>
<h3 className="h3-heading">{title}</h3>
<button className="btn text-dg-secondary mt-4">Read More</button>
</a>
);
};

export default PortfolioCard;
export default PortfolioCard;

+ 61
- 58
frontend/src/components/PortfolioSection.jsx Просмотреть файл

@@ -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;

+ 1
- 1
frontend/src/components/ProcessSection.jsx Просмотреть файл

@@ -22,7 +22,7 @@ const ProcessSection = () => {
const windowInfo = useWindowSize();

useEffect(() => {
console.log(windowInfo.width);
//console.log(windowInfo.width);
if (windowInfo.width < 1000)
setIsMobile(true);
else

+ 107
- 73
frontend/src/components/Testimonials.jsx Просмотреть файл

@@ -1,83 +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() {
const screenSize = useScreenDimensions();

return (
<Wrapper padding={" py-90p"}>
<div className="flex flex-col gap-32p md:gap-90p w-full">
<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>
);
}

+ 23
- 20
frontend/src/components/TimelineCard.jsx Просмотреть файл

@@ -1,24 +1,27 @@
import React from 'react'
import PropTypes from 'prop-types'
import {ReactComponent as BrakLine} from './../assets/BreakLine.svg';
import React from 'react';
import PropTypes from 'prop-types';
import { ReactComponent as BrakLine } from './../assets/BreakLine.svg';

const TimelineCard = ({title, subtitle, paragraph, id}) => {
const TimelineCard = ({ title, subtitle, paragraph, id }) => {
const left = id % 2 === 0;

const left = (id) % 2 === 0;
return (
<div
className={
'max-w-[450px] rounded-[32px] card-no-hover relative self-center' +
(left ? ' lg:self-start' : ' lg:self-end')
}
>
<div className="flex flex-col justify-start text-left gap-8p">
<h4 className="subtitle-card-italic-gray">{subtitle}</h4>
<h3 className="title-card capitalize text-dg-primary-900">{title}</h3>
<BrakLine className="my-[28px]" />
<p className="paragraph">{paragraph}</p>
</div>
</div>
);
};

return (
<div className={"max-w-[450px] rounded-[32px] card-no-hover relative self-center" + (left ? " lg:self-start" : " lg:self-end")}>
<div className="flex flex-col justify-start text-left gap-8p">
<h5 className="subtitle-card-italic-gray">{subtitle}</h5>
<h3 className="title-card capitalize text-dg-primary-900">{title}</h3>
<BrakLine className='my-[28px]'/>
<p className="paragraph">{paragraph}</p>
</div>
</div>
)
}
TimelineCard.propTypes = {};

TimelineCard.propTypes = {}

export default TimelineCard
export default TimelineCard;

+ 60
- 64
frontend/src/components/WhySection.jsx Просмотреть файл

@@ -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 think that our success is directly related to the success of our clients, so we are committed to assisting them in achieving their business goals. After over 15 years of software development, we are convinced that solution is there. With our purpose, everyone at Diligent has a clear and shared understanding of why we do business and what influence we intend to make as a company on business and society.',
},
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 Просмотреть файл

@@ -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,
};

+ 22
- 0
frontend/src/components/root/CustomLink.jsx Просмотреть файл

@@ -0,0 +1,22 @@
import React from 'react'
import {Link} from 'react-router-dom';

const CustomLink = ({href, downloadFile, bg, txt, children}) => {


return (
// <a href={href} {...(downloadFile && { download="My_File.pdf" })} (downloadFile download="My_File.pdf")>
// {context}
// </a>
<Link {...{
className: 'flex gap-2 items-center px-[16px] py-[12px] text-p font-medium bg-[#8568BF] text-white rounded-full' ,
to: href,
target: '_blank',
...(downloadFile && {download: downloadFile}),
}}>
{children}
</Link>
)
}

export default CustomLink

+ 9
- 0
frontend/src/components/root/TertiaryButton.jsx Просмотреть файл

@@ -0,0 +1,9 @@
import React from 'react'

const TertiaryButton = ({action, icon}) => {
return (
<button onClick={() => action()}></button>
)
}

export default TertiaryButton

+ 8
- 8
frontend/src/components/shared/CardLife.jsx Просмотреть файл

@@ -1,15 +1,15 @@
import PropTypes from 'prop-types';
import Hex from './../../assets/icons/life/hexLife.svg';

export default function CardLife({heading, paragraph, number}) {
export default function CardLife({ heading, paragraph, number }) {
return (
<div className="relative flex flex-col items-start text-left card-plain w-full">
<div className='absolute top-8 left-2 z-10'>
<img src={Hex} />
</div>
<div className='absolute top-10 left-6 z-20'>
<p className='paragraph text-white'>{number}.</p>
</div>
<div className="absolute top-8 left-2 z-10">
<img src={Hex} alt="Purple hex backgorund" />
</div>
<div className="absolute top-10 left-6 z-20">
<p className="paragraph text-white">{number}.</p>
</div>
<div className="flex flex-row justify-start items-start">
<h2 className="text-xl font-semibold dark:text-white ml-2">{heading}</h2>
</div>
@@ -22,4 +22,4 @@ CardLife.propTypes = {
heading: PropTypes.string,
paragraph: PropTypes.string,
number: PropTypes.number,
};
};

+ 30
- 19
frontend/src/components/shared/ClientForm.jsx Просмотреть файл

@@ -29,25 +29,34 @@ 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}
@@ -278,12 +287,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>

+ 27
- 33
frontend/src/components/shared/FacelessSlider/FacelessSlider.jsx Просмотреть файл

@@ -1,5 +1,11 @@
import React from 'react'
import { SliderProvider, SliderTrack, Slide, SliderButton, DotsNav } from '@faceless-ui/slider'
import React from 'react';
import {
SliderProvider,
SliderTrack,
Slide,
SliderButton,
DotsNav,
} from '@faceless-ui/slider';
import img1 from './../../../assets/images/Slider/1.png';
import img2 from './../../../assets/images/Slider/2.png';
import img3 from './../../../assets/images/Slider/3.png';
@@ -12,48 +18,36 @@ import img9 from './../../../assets/images/Slider/9.png';
import img10 from './../../../assets/images/Slider/10.png';
import './index.css';

const slides = [
img1, img2, img3, img4, img5, img6, img7, img8, img9, img10
]

const slides = [img1, img2, img3, img4, img5, img6, img7, img8, img9, img10];

const FacelessSlider = () => {
return (
<SliderProvider
slidesToShow={3}
autoPlay
scrollSnap
dragScroll
>
<div className={""}>
{/* <SliderButton direction="prev">
<SliderProvider slidesToShow={3} autoPlay 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={'w-full'}></img>
</Slide>
))}
</SliderTrack>
</div>
{/* <DotsNav
</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="Our Team's image" className={'w-full'}></img>
</Slide>
))}
</SliderTrack>
</div>

{/* <DotsNav
className={"dots"}
dotClassName={"dot"}
activeDotClassName={"dotIsActive"}
/> */}
</SliderProvider>
)
}
</SliderProvider>
);
};

export default FacelessSlider;

+ 20
- 12
frontend/src/components/shared/Footer.jsx Просмотреть файл

@@ -3,7 +3,7 @@ import logo from '../../assets/logos/LogoColumn.svg';
import bg_socials from '../../assets/logos/socials_bg.png';
import SocialMediaLinks from './SocialMediaLinks';
import { Popover } from '@headlessui/react';
import { NavLink, useNavigate } from 'react-router-dom';
import { NavLink, useLocation, useNavigate } from 'react-router-dom';

const footerText =
'Custom software solutions for variety of industries with the emphasis on reliability, innovation and top quality.';
@@ -11,8 +11,8 @@ const footerText =
const copyrightText = 'Copyright © 2022. Diligent Software. All rights reserved.';

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

const home = useNavigate();
const location = useLocation();

function handleLogo() {
home('/');
@@ -21,10 +21,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,15 +33,20 @@ 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>
<Popover.Group as="nav" className="hidden md:flex space-x-10 z-10">
{links.map(item => (
{links.map((item,index) => (
<NavLink
key={item.name}
to={item.href}
key={index}
to={item.path}
className={({ isActive }) => {
return `text-base font-medium hover:text-dg-primary-900 focus:text-dg-primary-900 active:text-dg-primary-900 capitalize ${activeLinks(
isActive,
@@ -51,7 +54,7 @@ export default function Footer({ links, scrollToView, activeLinks }) {
)}`;
}}
>
{item.name}
{item.title}
</NavLink>
))}
{/* React Router Link does not support Anchor tags */}
@@ -63,7 +66,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>

+ 19
- 12
frontend/src/components/shared/JobForm.jsx Просмотреть файл

@@ -61,12 +61,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 (
@@ -94,9 +100,8 @@ export default function JobForm(props) {
return null;
} else {
const base64 = await convertBase64(file);
return base64;
return base64;
}
};
//convert file
const convertBase64 = file => {
@@ -424,9 +429,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>
@@ -444,7 +451,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>

+ 35
- 28
frontend/src/components/shared/Navigation.jsx Просмотреть файл

@@ -15,46 +15,51 @@ export default function Navigation({ links, scrollToView, activeLinks }) {
home('/');
}

function checkUrl(event) {
//console.log(location.pathname);

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

// Check if you are on HomePage to scroll to Contact us, or open a sepperate Contact us Page
function checkUrl(event) {
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">
{links.map(item => (
<Popover.Group
as="nav"
className="hidden md:flex space-x-8 lg:space-x-10 items-center"
>
{links.map((item,index) => (
<NavLink
key={item.name}
to={item.href}
key={index}
to={item.path}
className={({ isActive }) => {
return `text-base font-medium dark:text-white hover:text-dg-primary-900 focus:text-dg-primary-900 active:text-dg-primary-900 capitalize ${activeLinks(
return `text-p font-medium dark:text-white hover:text-dg-primary-900 focus:text-dg-primary-900 active:text-dg-primary-900 capitalize ${activeLinks(
isActive,
)}`;
}}
>
{item.name}
{item.title}
</NavLink>
))}
{/* React Router Link does not support Anchor tags */}
@@ -62,7 +67,7 @@ export default function Navigation({ links, scrollToView, activeLinks }) {
// onClick={event => scrollToView(event)}
onClick={event => checkUrl(event)}
href="#contact"
className="contact-us-link"
className="contact-us-link text-p"
>
Contact
</div>
@@ -96,7 +101,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">
@@ -108,18 +118,16 @@ export default function Navigation({ links, scrollToView, activeLinks }) {
</div>
<div className="mt-6">
<nav className="grid gap-y-8">
{links.map(item => (
{links.map((item,index) => (
<NavLink
onClick={() => close()}
key={item.name}
to={item.href}
className="p-3 flex justify-center items-center rounded-md transition-all hover:transition-all hover:bg-dg-primary-900 hover:text-white"
key={index}
to={item.path}
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}
{item.title}
</span>
</NavLink>
))}
@@ -129,9 +137,8 @@ export default function Navigation({ links, scrollToView, activeLinks }) {
close();
checkUrl(event);
}}
className="contact-us-link flex justify-center items-center"
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 Просмотреть файл

@@ -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>

+ 1
- 1
frontend/src/components/shared/PageTitle.jsx Просмотреть файл

@@ -3,7 +3,7 @@ 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`)}>
<div className={"flex flex-col gap-8p"+ (left ? " text-left items-start":" text-center items-center") + (color ? " text-[#9B32CE]" : " ") + (pb ? ' pb-2' :' ')}>
<h6 className={"subheading" + (left ? " text-left":" text-center")}>{subheading}</h6>
<h1 className={"heading" + (left ? " text-left":" text-center")}>{heading}</h1>
</div>

+ 31
- 18
frontend/src/components/shared/ProcessCard.jsx Просмотреть файл

@@ -1,22 +1,35 @@
import React, { useEffect, useState } from "react";
import React, { useEffect, useState } from 'react';

const ProcessCard = ({numeric, id, title, subtitle, text}) => {
const [paragraphs, setParagraphs] = useState([]);
const left = (id-1) % 2 === 0;
const ProcessCard = ({ numeric, id, title, subtitle, text }) => {
const [paragraphs, setParagraphs] = useState([]);
const left = (id - 1) % 2 === 0;

useEffect(() => {
setParagraphs(text);
},[text]);
return (
<div className={"max-w-[700px] rounded-[32px] card-no-hover relative overflow-hidden" + (left ? " self-start" : " self-end")}>
{numeric && <div className="absolute top-0 left-0 py-3 px-6 bg-dg-primary-900 text-white leaf">{id}</div>}
<div className="flex flex-col justify-start text-left gap-8p">
<h3 className="title-card">{title}</h3>
<h5 className="subtitle-card-italic">{subtitle}</h5>
{paragraphs && paragraphs.map((item, index) => <p className="paragraph" key={index}>{item.paragraph}</p>)}
</div>
useEffect(() => {
setParagraphs(text);
}, [text]);
return (
<div
className={
'max-w-[700px] rounded-[32px] card-no-hover relative overflow-hidden' +
(left ? ' self-start' : ' self-end')
}
>
{numeric && (
<div className="absolute top-0 left-0 py-3 px-6 bg-dg-primary-900 text-white leaf">
{id}
</div>
)
}
)}
<div className="flex flex-col justify-start text-left gap-8p">
<h3 className="title-card">{title}</h3>
<h4 className="subtitle-card-italic">{subtitle}</h4>
{paragraphs &&
paragraphs.map((item, index) => (
<p className="paragraph" key={index}>
{item.paragraph}
</p>
))}
</div>
</div>
);
};
export default ProcessCard;

+ 37
- 47
frontend/src/components/shared/ProcessFacelessSlider.jsx Просмотреть файл

@@ -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;

+ 0
- 6
frontend/src/components/shared/SocialMediaLinks.jsx Просмотреть файл

@@ -55,9 +55,3 @@ export default function SocialMediaLinks(props) {
</div>
);
}

SocialMediaLinks.propTypes = {
divWidth: PropTypes.string,
iconSize: PropTypes.string,
iconSizeHover: PropTypes.string,
};

+ 2
- 2
frontend/src/components/shared/TechNuggets.jsx Просмотреть файл

@@ -2,9 +2,9 @@ import React from 'react';

const TechNuggets = ({ tech }) => {
return (
<div className="flex gap-2 mt-2">
<div className="flex gap-2 mt-2 flex-wrap">
{tech.map((item, index) => (
<div className="px-4 py-2 text-white text-title-24 font-medium bg-[#9FA2DD] rounded-lg" key={index}>{item}</div>
<div className="px-4 py-1 text-white text-p whitespace-nowrap font-medium bg-[#9FA2DD] rounded-lg" key={index}>{item}</div>
))}
</div>
);

+ 36
- 24
frontend/src/components/shared/TestimonialCard/index.jsx Просмотреть файл

@@ -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>
);
}

+ 16
- 0
frontend/src/hooks/useAnalytics.js Просмотреть файл

@@ -0,0 +1,16 @@
import React, { useEffect } from "react";
import { useLocation } from "react-router-dom";

const useAnalytics = () => {
const location = useLocation();

useEffect(() => {
window.gtag('event', 'page_view', {
page_title: document.title,
page_path: location.pathname + location.search,
page_location: window.location.href
})
}, [location]);
}

export default useAnalytics;

+ 0
- 1
frontend/src/hooks/useWindowSize.js Просмотреть файл

@@ -3,7 +3,6 @@ import React, {useState, useEffect} from "react";

const useWindowSize = () => {
// Initialize state with undefined width/height so server and client renders match
// Learn more here: https://joshwcomeau.com/react/the-perils-of-rehydration/
const [windowSize, setWindowSize] = useState({
width: undefined,
height: undefined,

+ 0
- 2
frontend/src/index.js Просмотреть файл

@@ -5,7 +5,6 @@ import App from './App';
import reportWebVitals from './reportWebVitals';

import { BrowserRouter } from 'react-router-dom';
import ScrollToTop from './components/root/ScrollToTop';

if (module.hot) module.hot.accept()

@@ -13,7 +12,6 @@ if (module.hot) module.hot.accept()
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
{/* <ScrollToTop /> */}
<App />
</BrowserRouter>
</React.StrictMode>,

+ 210
- 201
frontend/src/pages/About.jsx Просмотреть файл

@@ -14,7 +14,7 @@ import Ideas from './../assets/icons/values/ideas.svg';

import NisExpress from '../assets/NE_large_logo.png';

import Djole from './../'
import Djole from './../';
import valuesBG from './../assets/ValuesBG.svg';
import TimelineCardsWrapper from '../components/TimelineWrapper';
import TimelineCard from '../components/TimelineCard';
@@ -23,193 +23,211 @@ import Wrapper from '../layout/Wrapper';
import TimelineCardsWrapper2 from '../components/TimelineWrapper2';
import TimelineLogo from '../components/TimelineLogo';
import PageLayout from '../layout/PageLayout';
//import useAnalytics from '../hooks/useAnalytics';
const _data = {
heading: {
subheading: "About Us",
heading: "Who We Are",
imgUrl: 'https://lh6.googleusercontent.com/nCX_ne2JiqAAQqxF2ObEIA6EmP_cl6BciWQUqGaIzrgvv83Eo4nhzcqyZw_pYNxnByo=w2400',
paragraph: "When ten enthusiasts came together in 2020 with the same vision and impactful goals our journey officially began. We believed that taking small steps could result in meaningful changes and help us succeed in areas of a global pandemic and rapid social changes."
subheading: 'About Us',
heading: 'Who We Are',
imgUrl:
'https://lh4.googleusercontent.com/4AxnSLGq46gLcFyYdz1508l45FIeIhlsrb02v-AnNenATYLG15qFgIl3pbBfjHVg1nY=w2400',
paragraph:
'When ten enthusiasts came together in 2020 with the same vision and impactful goals our journey officially began. We believed that taking small steps could result in meaningful changes and help us succeed in areas of a global pandemic and rapid social changes.',
},
segment1: {
paragraph: "Diligent Software is a collaborative software development team that delivers high-quality custom software solutions while also cultivating a work environment that promotes community, family, learning, and mentoring.",
imgUrl: "https://lh5.googleusercontent.com/YD0JCH9v2hZ2_M42T7QD4U1CbTPolaelasj0SJF8kDQQiuRFmO9lLukjxfBqg5dxHsY=w2400",
paragraph:
'Diligent Software is a collaborative software development team that delivers high-quality custom software solutions while also cultivating a work environment that promotes community, family, learning, and mentoring.',
imgUrl:
'https://lh5.googleusercontent.com/YD0JCH9v2hZ2_M42T7QD4U1CbTPolaelasj0SJF8kDQQiuRFmO9lLukjxfBqg5dxHsY=w2400',
},
segment2: {
paragraph: "By utilizing cutting-edge technologies, our agile, multi-disciplinary teams provide a combination of product & technology strategies, intelligent experiences, and world-class engineering to help our clients become more engaging, responsive, and efficient.",
imgUrl: "https://lh6.googleusercontent.com/WEoQNbjwT9EpeG2kM4pvdeJM4MwFoEnSj2Dn0e3vPM54iN6P911_Y0wAXvSsbspd3Lg=w2400",
paragraph:
'By utilizing cutting-edge technologies, our agile, multi-disciplinary teams provide a combination of product & technology strategies, intelligent experiences, and world-class engineering to help our clients become more engaging, responsive, and efficient.',
imgUrl:
'https://lh6.googleusercontent.com/WEoQNbjwT9EpeG2kM4pvdeJM4MwFoEnSj2Dn0e3vPM54iN6P911_Y0wAXvSsbspd3Lg=w2400',
},
subtitle: "Diligent has close to 100 employees located throughout Serbia.",
subtitleImgUrl: "https://lh5.googleusercontent.com/Nk7pWU1H028YvdMkXvH6CECmQVWtTuKpKQuTUTKzUVXfhCF1JAjXThy1585YnXYdWio=w2400",
italicParagraph: "We understand that investing in long-term customer relationships is essential, but we also recognize the importance of providing rewarding and challenging careers for our employees.",
subtitle: 'Diligent has close to 100 employees located throughout Serbia.',
subtitleImgUrl:
'https://lh5.googleusercontent.com/Nk7pWU1H028YvdMkXvH6CECmQVWtTuKpKQuTUTKzUVXfhCF1JAjXThy1585YnXYdWio=w2400',
italicParagraph:
'We understand that investing in long-term customer relationships is essential, but we also recognize the importance of providing rewarding and challenging careers for our employees.',
segment3: {
mission: {
title: "Our Vision",
imgUrl:"https://lh5.googleusercontent.com/IdGSbzSZ8fRwwkP43Lkzm3fQBRGqywFNpfi2Qe2bkstNXunQGM1zVFrdX4blaiSGuEM=w2400",
title: 'Our Vision',
imgUrl:
'https://lh5.googleusercontent.com/IdGSbzSZ8fRwwkP43Lkzm3fQBRGqywFNpfi2Qe2bkstNXunQGM1zVFrdX4blaiSGuEM=w2400',
paragraphs: [
{
paragraph: "Our vision is to be a leading software solutions company for a variety of industries. We believe that our growth is directly related to the success of our customers, so we are dedicated to helping them achieve their business goals. "
paragraph:
'Our vision is to be a leading software solutions company for a variety of industries. We believe that our growth is directly related to the success of our customers, so we are dedicated to helping them achieve their business goals. ',
},
{
paragraph: "We want to be known as a reliable, innovative, and top-quality software service provider in the IT industry. We are constantly striving to exceed the expectations of our customers and to be the best in our field. "
}
paragraph:
'We want to be known as a reliable, innovative, and top-quality software service provider in the IT industry. We are constantly striving to exceed the expectations of our customers and to be the best in our field. ',
},
],
},
vision: {
title: "Our Mission",
imgUrl: "https://lh3.googleusercontent.com/gqO6y406jsrU5mt2c2rcbZS-2Z6Q9rg2zxHQ576LExMo1ptRx-SVZj2iAkR1wg2lNF0=w2400",
title: 'Our Mission',
imgUrl:
'https://lh3.googleusercontent.com/gqO6y406jsrU5mt2c2rcbZS-2Z6Q9rg2zxHQ576LExMo1ptRx-SVZj2iAkR1wg2lNF0=w2400',
paragraphs: [
{
paragraph: "Our mission is to help our customers grow their businesses through creative design and development solutions. We strive to deliver market-defining high-quality solutions that create value and competitive advantage for our customers around the world."
paragraph:
'Our mission is to help our customers grow their businesses through creative design and development solutions. We strive to deliver market-defining high-quality solutions that create value and competitive advantage for our customers around the world.',
},
{
paragraph: "We are dedicated to providing our clients with the best possible service and continually improving our processes and capabilities to better meet their needs. "
}
paragraph:
'We are dedicated to providing our clients with the best possible service and continually improving our processes and capabilities to better meet their needs. ',
},
],
}
},
},
values: {
heading: "Values",
cards: [
heading: 'Values',
cards: [
{
id:0,
id: 0,
iconUrl: Care,
title:"Care",
paragraph: "We believe that by working together and being kind to one another, we can make a difference. We care about work colleagues, ourselves, partnerships, but also the planet. We constantly strive to be helpful, kind, and inclusive in everything we do and looking for ways to be more sustainable. "
title: 'Care',
paragraph:
'We believe that by working together and being kind to one another, we can make a difference. We care about work colleagues, ourselves, partnerships, but also the planet. We constantly strive to be helpful, kind, and inclusive in everything we do and looking for ways to be more sustainable. ',
},
{
id:1,
id: 1,
iconUrl: Culture,
title:"Culture",
paragraph: "Our people love what they do. We provide a fun and supportive environment that empowers our staff to grow, learn, and thrive. We are consistent and transparent in our actions and committed to our clients and colleagues. We believe that together we can achieve more."
title: 'Culture',
paragraph:
'Our people love what they do. We provide a fun and supportive environment that empowers our staff to grow, learn, and thrive. We are consistent and transparent in our actions and committed to our clients and colleagues. We believe that together we can achieve more.',
},
{
id:2,
id: 2,
iconUrl: Doing,
title:"Learn by Doing",
paragraph: "Our legacy is our impact on the people around us. By being kind and helping others, we can make a positive difference and leave a lasting impression. We grow as individuals, as well as we grow as a team."
title: 'Learn by Doing',
paragraph:
'Our legacy is our impact on the people around us. By being kind and helping others, we can make a positive difference and leave a lasting impression. We grow as individuals, as well as we grow as a team.',
},
{
id:3,
id: 3,
iconUrl: Ideas,
title:"Ideas Over Hierarchy",
paragraph: "We believe that the best ideas can come from anywhere, both inside and outside our company. Our job is to seek out those ideas, shape and improve them through candid debate, and take them from concept to action."
}
title: 'Ideas Over Hierarchy',
paragraph:
'We believe that the best ideas can come from anywhere, both inside and outside our company. Our job is to seek out those ideas, shape and improve them through candid debate, and take them from concept to action.',
},
],
},
partners: {
title: "Partners",
paragraph: "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.",
title: 'Partners',
paragraph:
"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.",
icons: [
"https://lh4.googleusercontent.com/e5Zf5H4bL-6N4R7TOJIlB7hAPzzIk41dnWlCvJDZKAWyyjbJ_kWmONzHqddi11rb_SA=w2400",
"https://lh6.googleusercontent.com/4QxTBdL0JdRHjbujuHSEO9ysyQL7N64bykQm4DutzoAB0MOIYBODgShJ9uSChiI1kHo=w2400",
'https://lh4.googleusercontent.com/e5Zf5H4bL-6N4R7TOJIlB7hAPzzIk41dnWlCvJDZKAWyyjbJ_kWmONzHqddi11rb_SA=w2400',
'https://lh6.googleusercontent.com/4QxTBdL0JdRHjbujuHSEO9ysyQL7N64bykQm4DutzoAB0MOIYBODgShJ9uSChiI1kHo=w2400',
NisExpress,
"https://lh6.googleusercontent.com/8TrErMJ6QyxdwhmM57Oiy-41Db7thyvaHmGfb4teaFiYKWFVDd3reL1Ok1T88nAgvaE=w2400",
"https://lh4.googleusercontent.com/D05_HBhHcJf8Rpbxf7Uc4ix_J4advqIFM6Rwe-Vd9huTQCt2JKocAKqAf_AwszThr2Y=w2400",
]
'https://lh6.googleusercontent.com/8TrErMJ6QyxdwhmM57Oiy-41Db7thyvaHmGfb4teaFiYKWFVDd3reL1Ok1T88nAgvaE=w2400',
'https://lh4.googleusercontent.com/D05_HBhHcJf8Rpbxf7Uc4ix_J4advqIFM6Rwe-Vd9huTQCt2JKocAKqAf_AwszThr2Y=w2400',
],
},
industries: {
title:"Industries",
title: 'Industries',
industries: [
{
title: "Fintech",
paragraph: "We help fintech startups and financial institutions to manage risk and stay ahead of the curve by developing financial software solutions and integrating them with third-party systems while ensuring the stable operation of financial systems.",
imgUrl: 'https://lh6.googleusercontent.com/hNzi8UOWwAYzL9ZFR5bPnhge1RCIPgaFDwvZ-Cz7jaIRzKOySxZi2duV5-plTpGczLE=w2400',
},
{
title: "Healthcare",
paragraph: "We provide the healthcare sector with seamless transitions from an offline business to a tailored digital platform. All with the assistance of cutting-edge technology to enhance the user experience and improve health care delivery.",
imgUrl: 'https://lh4.googleusercontent.com/8xQPhJ2FZrTFamSUf2EkpL_vsvjAFymUEEX4PWF-R4Mhznt6vo2kkYCHY4gZCF5XjYs=w2400',
},
],
{
title: 'Fintech',
paragraph:
'We help fintech startups and financial institutions to manage risk and stay ahead of the curve by developing financial software solutions and integrating them with third-party systems while ensuring the stable operation of financial systems.',
imgUrl:
'https://lh6.googleusercontent.com/hNzi8UOWwAYzL9ZFR5bPnhge1RCIPgaFDwvZ-Cz7jaIRzKOySxZi2duV5-plTpGczLE=w2400',
},
{
title: 'Healthcare',
paragraph:
'We provide the healthcare sector with seamless transitions from an offline business to a tailored digital platform. All with the assistance of cutting-edge technology to enhance the user experience and improve health care delivery.',
imgUrl:
'https://lh4.googleusercontent.com/8xQPhJ2FZrTFamSUf2EkpL_vsvjAFymUEEX4PWF-R4Mhznt6vo2kkYCHY4gZCF5XjYs=w2400',
},
],
},
timeline: {
subtitle: "our journey",
title: "Timeline of Our Growth",
subtitle: 'our journey',
title: 'Timeline of Our Growth',
cards: [
{
subtitle: "1st Step",
title: "First Year of Our Work",
paragraph: "Our journey began two years ago when a group of ten tech enthusiasts made the decision to put their ideas into practice and accomplish their goals. With more than ten years of technology experience in a variety of industries, including fintech, transportation, and healthcare, they created a modern company that can deliver solutions tailored to each client. "
subtitle: '1st Step',
title: 'First Year of Our Work',
paragraph:
'Our journey began two years ago when a group of ten tech enthusiasts made the decision to put their ideas into practice and accomplish their goals. With more than ten years of technology experience in a variety of industries, including fintech, transportation, and healthcare, they created a modern company that can deliver solutions tailored to each client. ',
},
{
subtitle: "2nd Step",
title: "Choosing our clients",
paragraph: "We strive to build strong partnerships with our clients. We can proudly say that our biggest value is a long-lasting partnership with our very first clients. Good impressions and commitment lead us to the first clients. Furthermore, we continue to build long-term partnerships. "
subtitle: '2nd Step',
title: 'Choosing our clients',
paragraph:
'We strive to build strong partnerships with our clients. We can proudly say that our biggest value is a long-lasting partnership with our very first clients. Good impressions and commitment lead us to the first clients. Furthermore, we continue to build long-term partnerships. ',
},
{
subtitle: "3rd Step",
title: "Overcoming hard times",
paragraph: "As the COVID-19 pandemic was taking off, we were extremely impressed by how well our team adapted to the changing circumstances. Diligent’s greatest strengths have always been our team of highly qualified and experienced professionals. Diligent team increased from 35 employees to 67 technology experts."
subtitle: '3rd Step',
title: 'Overcoming hard times',
paragraph:
'As the COVID-19 pandemic was taking off, we were extremely impressed by how well our team adapted to the changing circumstances. Diligent’s greatest strengths have always been our team of highly qualified and experienced professionals. Diligent team increased from 35 employees to 67 technology experts.',
},
{
subtitle: "4th Step",
title: "Where We Are Today",
paragraph: "We are constantly growing, coding the vision of the future! Today we are about to have 100 employees who diligently work on more than 50 projects, trying to give cutting-edge solutions to the most common and modern problems. Our partnerships with the clients are based on trust and commitment."
subtitle: '4th Step',
title: 'Where We Are Today',
paragraph:
'We are constantly growing, coding the vision of the future! Today we are about to have 100 employees who diligently work on more than 50 projects, trying to give cutting-edge solutions to the most common and modern problems. Our partnerships with the clients are based on trust and commitment.',
},
{
subtitle: "5th Step",
title: "road to future success",
paragraph: "Professional and personal growth and development of our employees are crucial for strengthening our team. We strive hard to offer high-quality education, mentoring, and an inspiring environment where everyone may reach their full potential. This will enable us to progress as a team and achieve our long-term goals."
}
]
}



}
subtitle: '5th Step',
title: 'road to future success',
paragraph:
'Professional and personal growth and development of our employees are crucial for strengthening our team. We strive hard to offer high-quality education, mentoring, and an inspiring environment where everyone may reach their full potential. This will enable us to progress as a team and achieve our long-term goals.',
},
],
},
};

export default function About() {

useEffect(() => {
document.title = 'About Us';
},[]);
}, []);

//useAnalytics();

return (
<PageLayout>
<div className="bg-white dark:bg-dg-primary-1700 w-full pt-32">
{/* Heading Section */}
<section
id="heading"
className="flex flex-col items-center justify-center max-w-custom m-auto"
>
<div className="mb-8 flex flex-col md:flex-row justify-start items-start w-full px-8 xl:px-0">
id="heading"
className="flex flex-col items-center justify-center max-w-custom m-auto"
>
<div className="mb-8 flex flex-col md:flex-row gap-4 lg-gap-0 justify-start items-start w-full px-8 xl:px-0">
<div className="w-full md:w-1/2 md:pr-16">
<h6 className="subheading">
{_data.heading.subheading}
</h6>
<h1 className="heading text-dg-secondary mt-2">
{_data.heading.heading}
</h1>
<p className="paragraph mt-4">
{_data.heading.paragraph}
</p>
<h6 className="subheading">{_data.heading.subheading}</h6>
<h1 className="heading text-dg-secondary mt-2">{_data.heading.heading}</h1>
<p className="paragraph mt-4">{_data.heading.paragraph}</p>
</div>
<img
src={_data.heading.imgUrl}
alt="Our Team's image"
className="w-full md:w-1/2 text-center"
/>
src={_data.heading.imgUrl}
alt="Our Team's image"
className="w-full md:w-1/2 text-center -ml-2 lg-ml-0"
/>
</div>
</section>

{/* The After Heading pt.1 Section */}
<section
id="after_heading"
className="bg-white dark:bg-dg-primary-1700 flex items-center justify-center px-2"
>
id="after_heading"
className="bg-white dark:bg-dg-primary-1700 flex items-center justify-center px-2"
>
<div className="my-8 flex flex-col-reverse md:flex-row justify-center items-center max-w-custom m-auto w-full px-8 xl:px-0">
<img
src={_data.segment1.imgUrl}
alt="Our Team's image"
className="w-full md:w-1/2 text-center mt-8 md:mt-0"
/>
src={_data.segment1.imgUrl}
alt="Our Team's image"
className="w-full md:w-1/2 text-center mt-8 md:mt-0"
/>
<div className="w-full md:w-1/2 md:pl-16">
<p className="paragraph mt-4">
{_data.segment1.paragraph}
</p>
<p className="paragraph mt-4">{_data.segment1.paragraph}</p>
</div>
</div>
</section>
@@ -218,20 +236,21 @@ export default function About() {
<section id="after_heading" className="flex flex-col items-center justify-center">
<div className="my-8 flex flex-col md:flex-row justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2 md:pr-16">
<p className="paragraph mt-4">
{_data.segment2.paragraph}
</p>
<p className="paragraph mt-4">{_data.segment2.paragraph}</p>
</div>
<img
src={_data.segment2.imgUrl}
alt="Office's image"
className="w-full md:w-1/2 text-center"
/>
src={_data.segment2.imgUrl}
alt="Office's image"
className="w-full md:w-1/2 text-center"
/>
</div>
</section>

{/* Highlighted Text Section */}
<section id="highlight" className="flex flex-col items-center justify-center mt-16">
<section
id="highlight"
className="flex flex-col items-center justify-center mt-16"
>
<HighlighedText text={_data.subtitle} />
</section>

@@ -239,10 +258,10 @@ export default function About() {
<section id="info" className="flex flex-col items-center justify-center mt-16">
<div className="flex flex-col items-center justify-center w-full">
<img
src={_data.subtitleImgUrl}
alt="Info image"
className="max-w-[660px] w-full"
/>
src={_data.subtitleImgUrl}
alt="Info image"
className="max-w-[660px] w-full"
/>
<p className="text-sm font-medium italic text-gray-500 dark:text-white w-2/3 lg:w-1/3 mt-4">
{_data.italicParagraph}
</p>
@@ -251,149 +270,139 @@ export default function About() {

{/* Our Mission & Our Vision Section */}
<section
id="mission_vision"
className="bg-baby-blue dark:bg-dg-primary-1600 flex flex-col items-center justify-center mt-16"
>
id="mission_vision"
className="bg-baby-blue dark:bg-dg-primary-1600 flex flex-col items-center justify-center mt-16"
>
<div className="my-8 flex flex-col md:flex-row justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2 md:pr-16">
<h1 className="heading text-dg-secondary">{_data.segment3.vision.title}</h1>
{_data.segment3.vision.paragraphs.map((item,index) => (
<h2 className="heading text-dg-secondary">{_data.segment3.vision.title}</h2>
{_data.segment3.vision.paragraphs.map((item, index) => (
<p key={index} className="paragraph mt-4">
{item.paragraph}
</p>
)
)}
))}
</div>
<img
src={_data.segment3.mission.imgUrl}
alt="Our mission image"
className="text-center w-full md:w-1/2"
/>
src={_data.segment3.mission.imgUrl}
alt="Our mission image"
className="text-center w-full md:w-1/2"
/>
</div>
<div className="my-8 flex flex-col-reverse md:flex-row justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<img
src={_data.segment3.vision.imgUrl}
alt="Our vision image"
className="text-center w-full md:w-1/2 mt-8 md:mt-0"
/>
src={_data.segment3.vision.imgUrl}
alt="Our vision image"
className="text-center w-full md:w-1/2 mt-8 md:mt-0"
/>
<div className="w-full md:w-1/2 md:pl-16">
<h1 className="heading text-dg-secondary">{_data.segment3.mission.title}</h1>
{_data.segment3.mission.paragraphs.map((item,index) => (
<h2 className="heading text-dg-secondary">
{_data.segment3.mission.title}
</h2>
{_data.segment3.mission.paragraphs.map((item, index) => (
<p key={index} className="paragraph mt-4">
{item.paragraph}
</p>
)
)}
))}
</div>
</div>
</section>

{/* Values Section */}
<section
id="values"
className="bg-white dark:bg-dg-primary-1700 flex flex-row items-center justify-center mt-16"
>
id="values"
className="bg-white dark:bg-dg-primary-1700 flex flex-row items-center justify-center mt-16"
>
<div className="my-8 flex flex-col justify-center items-start w-full max-w-custom m-auto px-8 xl:px-0">
<h1 className="heading text-dg-secondary">{_data.values.heading}</h1>
<h2 className="heading text-dg-secondary">{_data.values.heading}</h2>
<div className="absolute justify-center md:flex hidden self-center">
<img src={valuesBG}/>
<img src={valuesBG} alt="Values background" />
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-16 w-full mt-8">
{_data.values.cards.map((item,index) => (
{_data.values.cards.map((item, index) => (
<CardValues
key={index}
image={item.iconUrl}
heading={item.title}
paragraph={item.paragraph}
/>
))}
key={index}
image={item.iconUrl}
heading={item.title}
paragraph={item.paragraph}
/>
))}
</div>
</div>
</section>

{/* Partners Section */}
<section
id="partners"
className="bg-baby-blue dark:bg-dg-primary-1600 flex flex-col items-center justify-center mt-16"
>
id="partners"
className="bg-baby-blue dark:bg-dg-primary-1600 flex flex-col items-center justify-center mt-16"
>
<div className="my-16 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-2/3">
<h1 className="text-center heading text-dg-secondary">
<h2 className="text-center heading text-dg-secondary">
{_data.partners.title}
</h1>
<p className="text-left paragraph mt-4">
{_data.partners.paragraph}
</p>
</h2>
<p className="text-left paragraph mt-4">{_data.partners.paragraph}</p>
</div>
<div className="flex flex-row justify-between items-center w-full mt-16">
{_data.partners.icons.map((item,index) => (
{_data.partners.icons.map((item, index) => (
<img
key={index}
src={item}
alt="Partner's image"
className="w-16 md:w-20 lg:w-24"
/>
))}
key={index}
src={item}
alt="Partner's image"
className="w-16 md:w-20 lg:w-24"
/>
))}
</div>
</div>
</section>

{/* Industries Section */}
<section
id="industries"
className="bg-white dark:bg-dg-primary-1700 flex flex-col items-center justify-center mt-16"
>
id="industries"
className="bg-white dark:bg-dg-primary-1700 flex flex-col items-center justify-center mt-16"
>
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h1 className="heading text-dg-secondary">{_data.industries.title}</h1>
<h2 className="heading text-dg-secondary">{_data.industries.title}</h2>
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-32 w-full mt-8">
{_data.industries.industries.map((industry,index) => (
{_data.industries.industries.map((industry, index) => (
<div key={index}>
<h3 className="h3-heading">
{industry.title}
</h3>
<p className="paragraph mt-2">
{industry.paragraph}
</p>
<img
src={industry.imgUrl}
alt="Industries images"
className="m-auto"
/>
<h3 className="h3-heading">{industry.title}</h3>
<p className="paragraph mt-2">{industry.paragraph}</p>
<img src={industry.imgUrl} alt="Industries images" className="m-auto" />
</div>
))}
))}
</div>
</div>
</section>

<Wrapper bg padding={' py-90p'}>
<PageTitle heading={_data.timeline.title} subheading={_data.timeline.subtitle} left />
<PageTitle
heading={_data.timeline.title}
subheading={_data.timeline.subtitle}
left
/>

<div className="my-90p">
<div className="w-full relative ">
<div className="md:absolute top-[5%] left-0 w-full h-full hidden md:block">
<TimelineLogo/>
<TimelineLogo />
</div>
<TimelineCardsWrapper2>
{_data.timeline.cards.map((item, index) => (
<TimelineCard
key={index}
id={index}
title={item.title}
subtitle={item.subtitle}
paragraph={item.paragraph}
/>
))}
key={index}
id={index}
title={item.title}
subtitle={item.subtitle}
paragraph={item.paragraph}
/>
))}
</TimelineCardsWrapper2>
</div>
</div>
</Wrapper>

</div>
</PageLayout>
);

+ 58
- 30
frontend/src/pages/Careers.jsx Просмотреть файл

@@ -15,6 +15,7 @@ import AboutUsSlider from '../components/shared/AboutUsSlider';
import CardCareers2 from '../components/CardCareers2';
import OrbitOnScroll from '../components/shared/graphics/OrbitOnScroll';
import PageLayout from '../layout/PageLayout';
//import useAnalytics from '../hooks/useAnalytics';

// eslint-disable-next-line no-underscore-dangle
const _data = {
@@ -27,7 +28,8 @@ const _data = {
{
nugget: '.Net',
role: '.Net Developer',
shortDetails: 'An idea solves a problem. We help you to create that idea, build a product and scale it to be successful in your business.',
shortDetails:
'An idea solves a problem. We help you to create that idea, build a product and scale it to be successful in your business.',
},
],
},
@@ -36,48 +38,52 @@ const _data = {
subheading: 'Diligent life',
italic: {
heading: 'Life At diligent',
paragraph: 'From the start, you can expect to be challenged and supported. We provide a encouraged atmosphere with knowledgeable mentors to help you advance in your career. To create an inspiring work life, we collaborate as a team both inside and outside of the office.',
paragraph:
'From the start, you can expect to be challenged and supported. We provide a encouraged atmosphere with knowledgeable mentors to help you advance in your career. To create an inspiring work life, we collaborate as a team both inside and outside of the office.',
heading2: 'What It Means to Work With Us',
},
cards: [
{
id: 1,
title: 'Shape the Future',
paragraph: 'We collaborate with business leaders and entrepreneurs to disrupt and push their industries forward. From startup ideas to enterprise-level product & software development, we work together as a team to transform our clients’ ideas into reality.',
paragraph:
'We collaborate with business leaders and entrepreneurs to disrupt and push their industries forward. From startup ideas to enterprise-level product & software development, we work together as a team to transform our clients’ ideas into reality.',
},
{
id: 2,
title: 'Life-Long Learning',
paragraph: 'We believe that learning is a journey that never ends. With us, you will have the opportunity to continuously learn in an environment surrounded by other highly skilled professionals with decades of experience. Also, there are several chances for you to develop through the use of various technologies, involvement in the product definition process, conference attendance, and more.',
paragraph:
'We believe that learning is a journey that never ends. With us, you will have the opportunity to continuously learn in an environment surrounded by other highly skilled professionals with decades of experience. Also, there are several chances for you to develop through the use of various technologies, involvement in the product definition process, conference attendance, and more.',
},
{
id: 3,
title: 'A Unique Culture',
paragraph: 'Everyone talks about a work-life balance, we do it - for two reasons. Firstly, we believe in an environment of happy people. Secondly, even if you’re highly productive, the only way to maintain productivity long-term is by taking time for the things that make you happy.',
paragraph:
'Everyone talks about a work-life balance, we do it - for two reasons. Firstly, we believe in an environment of happy people. Secondly, even if you’re highly productive, the only way to maintain productivity long-term is by taking time for the things that make you happy.',
},
{
id: 4,
title: 'Make the Impossible Better',
paragraph: 'If you have a mindset that is continuously focused on pushing through and beyond your boundaries, conquering a whole new challenge every day in an atmosphere where you constantly learn and improve, this is the place for you. We\'d love to learn more about you.',
paragraph:
"If you have a mindset that is continuously focused on pushing through and beyond your boundaries, conquering a whole new challenge every day in an atmosphere where you constantly learn and improve, this is the place for you. We'd love to learn more about you.",
},
],
},
connect: {
heading: 'Connect and Grow With Us',
paragraph: 'At Diligent, we are passionately proud of our culture and feel that everyone, including those who are not yet on the team, should have the opportunity to experience it. Because of this, we participate in Open Doors. Our coworkers are actively involved in the local tech communities. We take satisfaction in giving back as well, assisting college students or seasoned professionals who want to start a career in IT.',
paragraph:
'At Diligent, we are passionately proud of our culture and feel that everyone, including those who are not yet on the team, should have the opportunity to experience it. Because of this, we participate in Open Doors. Our coworkers are actively involved in the local tech communities. We take satisfaction in giving back as well, assisting college students or seasoned professionals who want to start a career in IT.',
subtitle: 'Check out how we have fun together!',
sliderImages: [

],
sliderImages: [],
},
ActionCard: {
heading: 'Contact Us and Step up Your Career!',
paragraph: 'We are continuously on the lookout for talented people to grow our business.',
paragraph2: 'Don\'t be shy - Apply!',
paragraph:
'We are continuously on the lookout for talented people to grow our business.',
paragraph2: "Don't be shy - Apply!",
primaryBtn: 'Apply',
secondaryBtn: 'About Us',
},

};

export default function Careers({ forwardedRef }) {
@@ -85,13 +91,16 @@ export default function Careers({ forwardedRef }) {
const [cntCareers, setCntCareers] = useState('');
const [isLoaded, setIsLoaded] = useState('');


const api_url = process.env.REACT_APP_API_URL;


useEffect(() => {
document.title = 'Careers';
}, []);

//useAnalytics();

useEffect(async () => {
var vid = document.getElementById('animation');
vid.playbackRate = 2;
@@ -125,14 +134,22 @@ export default function Careers({ forwardedRef }) {
<PageLayout>
<div className="bg-white dark:bg-dg-primary-1700 w-full pt-90p overflow-hidden">
<Wrapper padding={' py-90p'}>
<PageTitle heading={_data.heading.heading} subheading={_data.heading.subheading} left color />

<h1 className="hidden">Careers - Join our Team</h1>
<PageTitle
heading={_data.heading.heading}
subheading={_data.heading.subheading}
left
color
/>
</Wrapper>
<Wrapper padding={' py-90p'}>
<div className="absolute hidden -ml-64 md:block">
<OrbitOnScroll />
</div>
<section id="jobs" className="flex items-center justify-center max-w-custom m-auto">
<section
id="jobs"
className="flex items-center justify-center max-w-custom m-auto"
>
<div className="w-full">
{/* {cntCareers.job.map(job => (
<div key={job.id}>
@@ -157,17 +174,25 @@ export default function Careers({ forwardedRef }) {
</section>
</Wrapper>
<Wrapper bg padding={' py-90p'}>
<PageTitle left heading={_data.life.heading} subheading={_data.life.subheading} />
<PageTitle
left
heading={_data.life.heading}
subheading={_data.life.subheading}
/>

<div className="my-90p">
<div className="my-90p">
<h3 className="title-italic">{_data.life.italic.heading}</h3>
<p className="paragraph">
{_data.life.italic.paragraph}
</p>
<div className='w-full py-90p'>
<iframe className='m-auto w-[300px] h-[180px] md:w-[500px] md:h-[400px] lg:w-[800px] lg:h-[560px]' src="https://www.youtube.com/embed/PFHIqqHRS4s?controls=0" title="YouTube video player" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen></iframe>

<p className="paragraph">{_data.life.italic.paragraph}</p>
<div className="w-full py-90p">
<iframe
className="m-auto w-[300px] h-[180px] md:w-[500px] md:h-[400px] lg:w-[800px] lg:h-[560px]"
src="https://www.youtube.com/embed/PFHIqqHRS4s?controls=0"
title="YouTube video player"
frameBorder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
</div>
<h3 className="title-italic">{_data.life.italic.heading2}</h3>
@@ -191,13 +216,11 @@ export default function Careers({ forwardedRef }) {
</div>
</div>
</section>

</div>
</Wrapper>
<Wrapper padding={' py-90p'}>
<PageTitle heading={_data.connect.heading} color />
<p className="paragraph my-32p">{_data.connect.paragraph}</p>

</Wrapper>
<Wrapper>
<section id="highlight" className="flex flex-col items-center justify-center">
@@ -209,13 +232,18 @@ export default function Careers({ forwardedRef }) {
</Wrapper>
<Wrapper>
<div className="my-90p">
<ActionCard title={_data.ActionCard.heading} text={_data.ActionCard.paragraph} btn1={_data.ActionCard.primaryBtn} btn2={_data.ActionCard.secondaryBtn} link1={'/contact'} link2={'/about'} text2={_data.ActionCard.paragraph2} />
<ActionCard
title={_data.ActionCard.heading}
text={_data.ActionCard.paragraph}
btn1={_data.ActionCard.primaryBtn}
btn2={_data.ActionCard.secondaryBtn}
link1={'/contact'}
link2={'/about'}
text2={_data.ActionCard.paragraph2}
/>
</div>
</Wrapper>

</div>
</PageLayout>


);
}

+ 8
- 0
frontend/src/pages/CaseStudy.jsx Просмотреть файл

@@ -1,5 +1,7 @@
import ActionCard from '../components/shared/ActionCard';
//import useAnalytics from '../hooks/useAnalytics';
import PageLayout from '../layout/PageLayout';
import { useEffect } from 'react';

const technologies = [
{
@@ -37,6 +39,12 @@ const technologies = [
];

export default function CaseStudy() {
useEffect(() => {
document.title = 'Case Studies';
},[]);

//useAnalytics();
return (
<PageLayout>
<div className="bg-baby-blue dark:bg-dg-primary-1700 w-full pt-20 md:pt-24">

+ 135
- 134
frontend/src/pages/CaseStudyBI.jsx Просмотреть файл

@@ -9,30 +9,31 @@ import dataFactory from './../assets/icons/caseStudy/data-factory.svg';
import { useEffect } from 'react';
import Wrapper from '../layout/Wrapper';
import TechNuggets from '../components/shared/TechNuggets';
import {motion} from 'framer-motion';
import { motion } from 'framer-motion';
//import useAnalytics from '../hooks/useAnalytics';

const numbers = [
{
value: 7,
static: '+',
title: 'Team Members'
title: 'Team Members',
},
{
value: 100,
static: '+',
title: 'Users'
title: 'Users',
},
{
value: 100,
value: '1,6m',
static: '+',
title: 'Transactions per Year'
}
]
title: 'Transactions per Year',
},
];

const _data = {
heading: {
subheading: 'Case Study',
heading: 'Bi Healthcare Solution',
heading: 'BI Healthcare Solution',
imgUrl:
'https://lh3.googleusercontent.com/QkLcHNOGmWIB2t3fwZd69ZwJpHOYcTTAPmPs4zbjErDbp9nXbTw0vhktPCuCM2EWZUU=w2400',
paragraph:
@@ -116,153 +117,153 @@ const _data = {
};

export default function CaseStudyBI() {
useEffect(() => {
document.title = 'Case Study: BI Healthcare Solution';
},[]);
}, []);

//useAnalytics();

return (
<PageLayout>
<div className="bg-baby-blue dark:bg-dg-primary-1700 w-full pt-20 md:pt-24">
{/* Heading Section */}
<section
id="heading"
className="flex flex-col items-center justify-center m-auto py-16 md:py-32 bg-[url('https://lh3.googleusercontent.com/QkLcHNOGmWIB2t3fwZd69ZwJpHOYcTTAPmPs4zbjErDbp9nXbTw0vhktPCuCM2EWZUU=w2400')] bg-cover"
>
<div className="my-8 flex flex-col md:flex-row justify-start items-center w-full max-w-custom px-8 xl:px-0">
<div className="w-full">
<h6 className="subheading">{_data.heading.subheading}</h6>
<h1 className="heading text-dg-secondary mt-2">{_data.heading.heading}</h1>
<p className="paragraph mt-4">{_data.heading.paragraph}</p>
</div>
</div>
</section>

<Wrapper padding={' py-90p'}>
<motion.section
id="status-numbers"
className="flex flex-col md:flex-row items-start justify-between w-full gap-90p px-90p"
initial={{ y: 60, opacity: 0 }}
whileInView={{ y: 0, opacity: 1 }}
transition={{ duration: 0.5, ease: 'easeOut' }}
<div className="bg-baby-blue dark:bg-dg-primary-1700 w-full pt-20 md:pt-24">
{/* Heading Section */}
<section
id="heading"
className="flex flex-col items-center justify-center m-auto py-16 md:py-32 bg-[url('https://lh3.googleusercontent.com/QkLcHNOGmWIB2t3fwZd69ZwJpHOYcTTAPmPs4zbjErDbp9nXbTw0vhktPCuCM2EWZUU=w2400')] bg-cover"
>
{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>
<div className="my-8 flex flex-col md:flex-row justify-start items-center w-full max-w-custom px-8 xl:px-0">
<div className="w-full">
<h6 className="subheading">{_data.heading.subheading}</h6>
<h1 className="heading text-dg-secondary mt-2">{_data.heading.heading}</h1>
<p className="paragraph mt-4">{_data.heading.paragraph}</p>
</div>
))}
</motion.section>
</Wrapper>

{/* About the Client Section */}
<section id="client" className="flex flex-col items-center justify-center">
<div className="my-8 flex flex-col md:flex-row justify-center items-start w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2">
<h3 className="h3-heading text-teal-600">{_data.about.heading}</h3>
<p className="paragraph mt-4">{_data.about.paragraph}</p>
</div>
<div className="w-full md:w-1/2 grid grid-cols-2 md:grid-cols-3 gap-16 mt-8 md:mt-0">
<div className="hidden md:inline-block"></div>
<div className="float-left md:float-right text-left md:text-right">
<h5 className="text-teal-600 font-semibold">
{_data.about.country_heading}
</h5>
<p className="mt-4">{_data.about.country_name}</p>
</section>

<Wrapper padding={' py-90p'}>
<motion.section
id="status-numbers"
className="flex flex-col md:flex-row items-start justify-between w-full gap-90p px-90p"
initial={{ y: 60, opacity: 0 }}
whileInView={{ y: 0, opacity: 1 }}
transition={{ duration: 0.5, ease: 'easeOut' }}
>
{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>
</div>
))}
</motion.section>
</Wrapper>

{/* About the Client Section */}
<section id="client" className="flex flex-col items-center justify-center">
<div className="my-8 flex flex-col md:flex-row justify-center items-start w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2">
<h3 className="h3-heading text-teal-600">{_data.about.heading}</h3>
<p className="paragraph mt-4">{_data.about.paragraph}</p>
</div>
<div className="float-left md:float-right text-left md:text-right">
<h5 className="text-teal-600 font-semibold">
{_data.about.industry_heading}
</h5>
<p className="mt-4">{_data.about.industry_name}</p>
<div className="w-full md:w-1/2 grid grid-cols-2 md:grid-cols-3 gap-16 mt-8 md:mt-0">
<div className="hidden md:inline-block"></div>
<div className="float-left md:float-right text-left md:text-right">
<h4 className="text-teal-600 font-semibold">
{_data.about.country_heading}
</h4>
<p className="mt-4">{_data.about.country_name}</p>
</div>
<div className="float-left md:float-right text-left md:text-right">
<h4 className="text-teal-600 font-semibold">
{_data.about.industry_heading}
</h4>
<p className="mt-4">{_data.about.industry_name}</p>
</div>
</div>
</div>
</div>
</section>
</section>

{/* Domain Section */}
<section id="domain" className="flex flex-col items-center justify-center mt-16">
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading">{_data.domain.heading}</h3>
<p className="paragraph mt-4">{_data.domain.paragraph}</p>
{/* Domain Section */}
<section id="domain" className="flex flex-col items-center justify-center mt-16">
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading">{_data.domain.heading}</h3>
<p className="paragraph mt-4">{_data.domain.paragraph}</p>
</div>
</div>
</div>
</section>
</section>

{/* Challanges, Solution Section */}
<section
id="challanges_solution"
className="flex flex-col items-center justify-center mt-16"
>
<div className="my-8 flex flex-col md:flex-row justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2 md:pr-16">
<div>
<h3 className="h3-heading">{_data.challanges.heading}</h3>
<p className="text-sm text-dark-gray dark:text-white mt-4">
{_data.challanges.paragraph}
</p>
</div>
<div className="mt-8">
<h3 className="h3-heading">{_data.solution.heading}</h3>
<p className="text-sm text-dark-gray dark:text-white mt-4">
{_data.solution.paragraph}
</p>
{/* Challanges, Solution Section */}
<section
id="challanges_solution"
className="flex flex-col items-center justify-center mt-16"
>
<div className="my-8 flex flex-col md:flex-row justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2 md:pr-16">
<div>
<h3 className="h3-heading">{_data.challanges.heading}</h3>
<p className="text-sm text-dark-gray dark:text-white mt-4">
{_data.challanges.paragraph}
</p>
</div>
<div className="mt-8">
<h3 className="h3-heading">{_data.solution.heading}</h3>
<p className="text-sm text-dark-gray dark:text-white mt-4">
{_data.solution.paragraph}
</p>
</div>
</div>
<img
src={_data.solution.imgUrl}
alt="Case Study main image"
className="text-center w-full md:w-1/2"
/>
</div>
<img
src={_data.solution.imgUrl}
alt="Case Study main image"
className="text-center w-full md:w-1/2"
/>
</div>
</section>
</section>

{/* Results Section */}
<section id="results" className="flex flex-col items-center justify-center mt-16">
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading text-dg-secondary">{_data.results.heading}</h3>
<ul className="list-disc paragraph mt-2 pl-8">
{_data.results.list.map(item => (
<li key={item.id}>{item.text}</li>
))}
</ul>
{/* Results Section */}
<section id="results" className="flex flex-col items-center justify-center mt-16">
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading text-dg-secondary">{_data.results.heading}</h3>
<ul className="list-disc paragraph mt-2 pl-8">
{_data.results.list.map(item => (
<li key={item.id}>{item.text}</li>
))}
</ul>
</div>
</div>
</div>
</section>
</section>

{/* Technologies Section */}
<section
id="technologies"
className="flex flex-col justify-center mt-16"
>
<div className="my-8 flex flex-col justify-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading">Technologies</h3>
{/* Technologies Section */}
<section id="technologies" className="flex flex-col justify-center mt-16">
<div className="my-8 flex flex-col w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading">Technologies</h3>
</div>
<TechNuggets
tech={['Azure Data Factory','Azure SQL Server', 'Microsoft Power BI', '.Net Core', 'Azure App Services', 'Microsoft Power Automate','Azure Logic Apps','Azure Active Directory']}
/>
</div>
<TechNuggets tech={['.Net','Power BI','Power Automate','MSSQL','Data Factory']}/>
</div>
</section>
</section>

{/* CTA Section */}
<section id="cta" className="flex flex-col items-center justify-center mt-16">
<div className="px-8 mt-8 mb-32 w-full max-w-custom">
<ActionCard
title="Let's Work Together!"
text="Business Intelligence portal which enhouses series of web applications & reporting tools used for in-depth analysis on product pricing, money flow, resources, employees, etc. Applications provide administrative users overview, as well as detail look scaled down to individual product."
btn1="More Projects"
btn2="Contact Us"
link1={'/portfolio'}
link2={'/contact'}
/>
</div>
</section>
</div>
{/* CTA Section */}
<section id="cta" className="flex flex-col items-center justify-center mt-16">
<div className="px-8 mt-8 mb-32 w-full max-w-custom">
<ActionCard
title="Let's Work Together!"
text="Business Intelligence portal which enhouses series of web applications & reporting tools used for in-depth analysis on product pricing, money flow, resources, employees, etc. Applications provide administrative users overview, as well as detail look scaled down to individual product."
btn1="More Projects"
btn2="Contact Us"
link1={'/portfolio'}
link2={'/contact'}
/>
</div>
</section>
</div>
</PageLayout>
);
}

+ 39
- 38
frontend/src/pages/CaseStudyCentralized.jsx Просмотреть файл

@@ -8,8 +8,9 @@ import mssql from './../assets/icons/caseStudy/MSSQL.svg';
import dataFactory from './../assets/icons/caseStudy/data-factory.svg';
import { useEffect } from 'react';
import Wrapper from '../layout/Wrapper';
import {motion} from 'framer-motion';
import { motion } from 'framer-motion';
import TechNuggets from '../components/shared/TechNuggets';
//import useAnalytics from '../hooks/useAnalytics';

const numbers = [
{
@@ -35,8 +36,7 @@ const _data = {
heading: 'Centralized Monitoring System',
imgUrl:
'https://lh4.googleusercontent.com/P93dPcW2bzA11uz2IhXYmSfEUQRzXjmeIH0HXv88s-dUmHQdtPtNonxeR-h0wqoPeMU=w2400',
paragraph:
'Development of a centralized monitoring system for healthcare tools',
paragraph: 'Development of a centralized monitoring system for healthcare tools',
},

about: {
@@ -58,7 +58,7 @@ const _data = {
challanges: {
heading: 'Challanges',
paragraph:
'Some of them didn\'t even have open API-s, some of them required an extra set of rules, and some of them were still in development. This made integration difficult and time-consuming. However, we were eventually able to overcome these challenges and provide our users with a seamless experience.',
"Some of them didn't even have open API-s, some of them required an extra set of rules, and some of them were still in development. This made integration difficult and time-consuming. However, we were eventually able to overcome these challenges and provide our users with a seamless experience.",
},

solution: {
@@ -120,19 +120,23 @@ const _data = {
};

export default function CaseStudyCentralized() {
useEffect(() => {
document.title = 'Case Study: Centralized Monitoring System';
},[]);
}, []);

//useAnalytics();

return (
<PageLayout>
<div className="bg-baby-blue dark:bg-dg-primary-1700 w-full pt-20 md:pt-24">
{/* Heading Section */}
<section
id="heading"
className={'flex flex-col items-center justify-center m-auto py-16 md:py-32 relative bg-cover bg-[url(\'https://lh4.googleusercontent.com/P93dPcW2bzA11uz2IhXYmSfEUQRzXjmeIH0HXv88s-dUmHQdtPtNonxeR-h0wqoPeMU=w2400\')] bg-no-repeat'}
>
id="heading"
className={
"flex flex-col items-center justify-center m-auto py-16 md:py-32 relative bg-cover bg-[url('https://lh4.googleusercontent.com/P93dPcW2bzA11uz2IhXYmSfEUQRzXjmeIH0HXv88s-dUmHQdtPtNonxeR-h0wqoPeMU=w2400')] bg-no-repeat"
}
>
<div className="my-8 flex flex-col md:flex-row justify-start items-center w-full max-w-custom px-8 xl:px-0">
<div className="w-full">
<h6 className="subheading">{_data.heading.subheading}</h6>
@@ -142,7 +146,7 @@ export default function CaseStudyCentralized() {
</div>
</section>

{/* <Wrapper padding={' py-90p'}>
<Wrapper padding={' py-90p'}>
<motion.section
id="status-numbers"
className="flex flex-col md:flex-row items-start justify-between w-full gap-90p px-90p"
@@ -161,27 +165,27 @@ export default function CaseStudyCentralized() {
</div>
))}
</motion.section>
</Wrapper> */}
</Wrapper>

{/* About the Client Section */}
<section id="client" className="flex flex-col items-center justify-center mt-16">
<div className="my-8 flex flex-col md:flex-row justify-center items-start w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2">
<h3 className="h3-heading text-teal-600">{_data.about.heading}</h3>
<h2 className="h3-heading text-teal-600">{_data.about.heading}</h2>
<p className="paragraph mt-4">{_data.about.paragraph}</p>
</div>
<div className="w-full md:w-1/2 grid grid-cols-2 md:grid-cols-3 gap-16 mt-8 md:mt-0">
<div className="hidden md:inline-block"></div>
<div className="float-left md:float-right text-left md:text-right">
<h5 className="text-teal-600 font-semibold">
<h3 className="text-teal-600 font-semibold">
{_data.about.country_heading}
</h5>
</h3>
<p className="mt-4">{_data.about.country_name}</p>
</div>
<div className="float-left md:float-right text-left md:text-right">
<h5 className="text-teal-600 font-semibold">
<h3 className="text-teal-600 font-semibold">
{_data.about.industry_heading}
</h5>
</h3>
<p className="mt-4">{_data.about.industry_name}</p>
</div>
</div>
@@ -200,9 +204,9 @@ export default function CaseStudyCentralized() {

{/* Challanges, Solution Section */}
<section
id="challanges_solution"
className="flex flex-col items-center justify-center mt-16"
>
id="challanges_solution"
className="flex flex-col items-center justify-center mt-16"
>
<div className="my-8 flex flex-col md:flex-row justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2 md:pr-16">
<div>
@@ -219,10 +223,10 @@ export default function CaseStudyCentralized() {
</div>
</div>
<img
src={_data.solution.imgUrl}
alt="Case Study main image"
className="text-center w-full md:w-1/2"
/>
src={_data.solution.imgUrl}
alt="Case Study main image"
className="text-center w-full md:w-1/2"
/>
</div>
</section>

@@ -234,22 +238,19 @@ export default function CaseStudyCentralized() {
<ul className="list-disc paragraph mt-2 pl-8">
{_data.results.list.map(item => (
<li key={item.id}>{item.text}</li>
))}
))}
</ul>
</div>
</div>
</section>

{/* Technologies Section */}
<section
id="technologies"
className="flex flex-col items-center mt-16"
>
<div className="my-8 flex flex-col items-center w-full max-w-custom m-auto px-8 xl:px-0">
{/*Technologies Section */}
<section id="technologies" className="flex flex-col mt-16">
<div className="my-8 flex flex-col w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading">Technologies</h3>
</div>
<TechNuggets tech={['.Net']}/>
<TechNuggets tech={['.Net','MS SQL Server','JQuery','Power BI']} />
</div>
</section>

@@ -257,13 +258,13 @@ export default function CaseStudyCentralized() {
<section id="cta" className="flex flex-col items-center justify-center mt-16">
<div className="px-8 mt-8 mb-32 w-full max-w-custom">
<ActionCard
title="Let's Work Together!"
text="Business Intelligence portal which enhouses series of web applications & reporting tools used for in-depth analysis on product pricing, money flow, resources, employees, etc. Applications provide administrative users overview, as well as detail look scaled down to individual product."
btn1="More Projects"
btn2="Contact Us"
link1={'/portfolio'}
link2={'/contact'}
/>
title="Let's Work Together!"
text="Business Intelligence portal which enhouses series of web applications & reporting tools used for in-depth analysis on product pricing, money flow, resources, employees, etc. Applications provide administrative users overview, as well as detail look scaled down to individual product."
btn1="More Projects"
btn2="Contact Us"
link1={'/portfolio'}
link2={'/contact'}
/>
</div>
</section>
</div>

+ 135
- 135
frontend/src/pages/CaseStudyFinantial.jsx Просмотреть файл

@@ -5,26 +5,27 @@ import net from './../assets/icons/caseStudy/net.svg';
import angular from './../assets/icons/caseStudy/angular.svg';
import mssql from './../assets/icons/caseStudy/MSSQL.svg';
import { useEffect } from 'react';
import {motion} from 'framer-motion';
import { motion } from 'framer-motion';
import Wrapper from '../layout/Wrapper';
import TechNuggets from '../components/shared/TechNuggets';
//import useAnalytics from '../hooks/useAnalytics';
const numbers = [
{
value: 5,
static: '+',
title: 'Team Members'
title: 'Team Members',
},
{
value: 3,
static: '+',
title: 'Years Project Duration'
title: 'Years Project Duration',
},
{
value: '1,6m',
static: '+',
title: 'Transactions per Year'
}
]
title: 'Transactions per Year',
},
];

const _data = {
heading: {
@@ -32,13 +33,13 @@ const _data = {
heading: 'Financial Engine',
imgUrl:
'https://lh3.googleusercontent.com/pCtBoMQ4ea-MJV9TJzWucWkMOo0_0fetGCXblvffooAn9bG_ARbWNScRBBO16dNNrnk=w2400',
paragraph:
'Implementing a system for financial system management',
paragraph: 'Implementing a system for financial system management',
},

about: {
heading: 'About the Client',
paragraph: 'The client that deals with precious metals trading, storing, and investment had us expand the existing IT system with a sub-system that monitors and analyze the financial perspective of the business.',
paragraph:
'The client that deals with precious metals trading, storing, and investment had us expand the existing IT system with a sub-system that monitors and analyze the financial perspective of the business.',
country_heading: 'Country',
country_name: 'USA',
industry_heading: 'Industry',
@@ -108,153 +109,152 @@ const _data = {
};

export default function CaseStudyFinantial() {

useEffect(() => {
document.title = 'Case Study: Financial Engine';
},[]);
}, []);

//useAnalytics();

return (
<PageLayout>
<div className="bg-baby-blue dark:bg-dg-primary-1700 w-full pt-20 md:pt-24">
{/* Heading Section */}
<section
id="heading"
className="flex flex-col items-center justify-center m-auto py-16 md:py-32 bg-[url('https://lh3.googleusercontent.com/pCtBoMQ4ea-MJV9TJzWucWkMOo0_0fetGCXblvffooAn9bG_ARbWNScRBBO16dNNrnk=w2400')] bg-cover"
>
<div className="my-8 flex flex-col md:flex-row justify-start items-center w-full max-w-custom px-8 xl:px-0">
<div className="w-full">
<h6 className="subheading">{_data.heading.subheading}</h6>
<h1 className="heading text-dg-secondary mt-2">{_data.heading.heading}</h1>
<p className="paragraph mt-4">{_data.heading.paragraph}</p>
</div>
</div>
</section>

<Wrapper padding={' py-90p'}>
<motion.section
id="status-numbers"
className="flex flex-col md:flex-row items-start justify-between w-full gap-90p px-90p"
initial={{ y: 60, opacity: 0 }}
whileInView={{ y: 0, opacity: 1 }}
transition={{ duration: 0.5, ease: 'easeOut' }}
<div className="bg-baby-blue dark:bg-dg-primary-1700 w-full pt-20 md:pt-24">
{/* Heading Section */}
<section
id="heading"
className="flex flex-col items-center justify-center m-auto py-16 md:py-32 bg-[url('https://lh3.googleusercontent.com/pCtBoMQ4ea-MJV9TJzWucWkMOo0_0fetGCXblvffooAn9bG_ARbWNScRBBO16dNNrnk=w2400')] bg-cover"
>
{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>
<div className="my-8 flex flex-col md:flex-row justify-start items-center w-full max-w-custom px-8 xl:px-0">
<div className="w-full">
<h6 className="subheading">{_data.heading.subheading}</h6>
<h1 className="heading text-dg-secondary mt-2">{_data.heading.heading}</h1>
<p className="paragraph mt-4">{_data.heading.paragraph}</p>
</div>
))}
</motion.section>
</Wrapper>

{/* About the Client Section */}
<section id="client" className="flex flex-col items-center justify-center">
<div className="my-8 flex flex-col md:flex-row justify-center items-start w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2">
<h3 className="h3-heading text-teal-600">{_data.about.heading}</h3>
<p className="paragraph mt-4">{_data.about.paragraph}</p>
</div>
<div className="w-full md:w-1/2 grid grid-cols-2 md:grid-cols-3 gap-16 mt-8 md:mt-0">
<div className="hidden md:inline-block"></div>
<div className="float-left md:float-right text-left md:text-right">
<h5 className="text-teal-600 font-semibold">
{_data.about.country_heading}
</h5>
<p className="mt-4">{_data.about.country_name}</p>
</section>

<Wrapper padding={' py-90p'}>
<motion.section
id="status-numbers"
className="flex flex-col md:flex-row items-start justify-between w-full gap-90p px-90p"
initial={{ y: 60, opacity: 0 }}
whileInView={{ y: 0, opacity: 1 }}
transition={{ duration: 0.5, ease: 'easeOut' }}
>
{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>
</div>
))}
</motion.section>
</Wrapper>

{/* About the Client Section */}
<section id="client" className="flex flex-col items-center justify-center">
<div className="my-8 flex flex-col md:flex-row justify-center items-start w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2">
<h3 className="h3-heading text-teal-600">{_data.about.heading}</h3>
<p className="paragraph mt-4">{_data.about.paragraph}</p>
</div>
<div className="float-left md:float-right text-left md:text-right">
<h5 className="text-teal-600 font-semibold">
{_data.about.industry_heading}
</h5>
<p className="mt-4">{_data.about.industry_name}</p>
<div className="w-full md:w-1/2 grid grid-cols-2 md:grid-cols-3 gap-16 mt-8 md:mt-0">
<div className="hidden md:inline-block"></div>
<div className="float-left md:float-right text-left md:text-right">
<h4 className="text-teal-600 font-semibold">
{_data.about.country_heading}
</h4>
<p className="mt-4">{_data.about.country_name}</p>
</div>
<div className="float-left md:float-right text-left md:text-right">
<h4 className="text-teal-600 font-semibold">
{_data.about.industry_heading}
</h4>
<p className="mt-4">{_data.about.industry_name}</p>
</div>
</div>
</div>
</div>
</section>
</section>

{/* Domain Section */}
<section id="domain" className="flex flex-col items-center justify-center mt-16">
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading">{_data.domain.heading}</h3>
<p className="paragraph mt-4">{_data.domain.paragraph}</p>
{/* Domain Section */}
<section id="domain" className="flex flex-col items-center justify-center mt-16">
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading">{_data.domain.heading}</h3>
<p className="paragraph mt-4">{_data.domain.paragraph}</p>
</div>
</div>
</div>
</section>
</section>

{/* Challanges, Solution Section */}
<section
id="challanges_solution"
className="flex flex-col items-center justify-center mt-16"
>
<div className="my-8 flex flex-col md:flex-row justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2 md:pr-16">
<div>
<h3 className="h3-heading">{_data.challanges.heading}</h3>
<p className="text-sm text-dark-gray dark:text-white mt-4">
{_data.challanges.paragraph}
</p>
</div>
<div className="mt-8">
<h3 className="h3-heading">{_data.solution.heading}</h3>
<p className="text-sm text-dark-gray dark:text-white mt-4">
{_data.solution.paragraph}
</p>
{/* Challanges, Solution Section */}
<section
id="challanges_solution"
className="flex flex-col items-center justify-center mt-16"
>
<div className="my-8 flex flex-col md:flex-row justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2 md:pr-16">
<div>
<h3 className="h3-heading">{_data.challanges.heading}</h3>
<p className="text-sm text-dark-gray dark:text-white mt-4">
{_data.challanges.paragraph}
</p>
</div>
<div className="mt-8">
<h3 className="h3-heading">{_data.solution.heading}</h3>
<p className="text-sm text-dark-gray dark:text-white mt-4">
{_data.solution.paragraph}
</p>
</div>
</div>
<img
src={_data.solution.imgUrl}
alt="Case Study main image"
className="text-center w-full md:w-1/2"
/>
</div>
<img
src={_data.solution.imgUrl}
alt="Case Study main image"
className="text-center w-full md:w-1/2"
/>
</div>
</section>
</section>

{/* Results Section */}
<section id="results" className="flex flex-col items-center justify-center mt-16">
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading text-dg-secondary">{_data.results.heading}</h3>
<ul className="list-disc paragraph mt-2 pl-8">
{_data.results.list.map(item => (
<li key={item.id}>{item.text}</li>
))}
</ul>
{/* Results Section */}
<section id="results" className="flex flex-col items-center justify-center mt-16">
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading text-dg-secondary">{_data.results.heading}</h3>
<ul className="list-disc paragraph mt-2 pl-8">
{_data.results.list.map(item => (
<li key={item.id}>{item.text}</li>
))}
</ul>
</div>
</div>
</div>
</section>
</section>

{/* Technologies Section */}
<section
id="technologies"
className="flex flex-col items-center justify-center mt-16"
>
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading">Technologies</h3>
{/* Technologies Section */}
<section id="technologies" className="flex flex-col mt-16">
<div className="my-8 flex flex-col w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading">Technologies</h3>
</div>
<TechNuggets
tech={['.Net','Service-Oriented Architecture (SOA)', 'MS SQL Server', 'MS MVC', 'Event-Driven Architecture (EDA)']}
/>
</div>
<TechNuggets tech={['.Net','Angular','MSSQL']}/>
</div>
</section>
</section>

{/* CTA Section */}
<section id="cta" className="flex flex-col items-center justify-center mt-16">
<div className="px-8 mt-8 mb-32 w-full max-w-custom">
<ActionCard
title="Let's Work Together!"
text="Business Intelligence portal which enhouses series of web applications & reporting tools used for in-depth analysis on product pricing, money flow, resources, employees, etc. Applications provide administrative users overview, as well as detail look scaled down to individual product."
btn1="More Projects"
btn2="Contact Us"
link1={'/portfolio'}
link2={'/contact'}
/>
</div>
</section>
</div>
{/* CTA Section */}
<section id="cta" className="flex flex-col items-center justify-center mt-16">
<div className="px-8 mt-8 mb-32 w-full max-w-custom">
<ActionCard
title="Let's Work Together!"
text="Business Intelligence portal which enhouses series of web applications & reporting tools used for in-depth analysis on product pricing, money flow, resources, employees, etc. Applications provide administrative users overview, as well as detail look scaled down to individual product."
btn1="More Projects"
btn2="Contact Us"
link1={'/portfolio'}
link2={'/contact'}
/>
</div>
</section>
</div>
</PageLayout>
);
}

+ 132
- 134
frontend/src/pages/CaseStudyResource.jsx Просмотреть файл

@@ -7,21 +7,23 @@ import powerAutomate from './../assets/icons/caseStudy/power-automate.svg';
import mssql from './../assets/icons/caseStudy/MSSQL.svg';
import dataFactory from './../assets/icons/caseStudy/data-factory.svg';
import { useEffect } from 'react';
import {motion} from 'framer-motion';
import { motion } from 'framer-motion';
import Wrapper from '../layout/Wrapper';
import TechNuggets from '../components/shared/TechNuggets';
//import useAnalytics from '../hooks/useAnalytics';

const numbers = [
{
value: 6,
static: '+',
title: 'Team Members'
title: 'Team Members',
},
{
value: 6,
static: '+',
title: 'Months Project duration'
title: 'Months Project duration',
},
]
];

const _data = {
heading: {
@@ -114,157 +116,153 @@ const _data = {

export default function CaseStudyResource() {


useEffect(() => {
document.title = 'Case Study: Resource Planning System';
},[]);
}, []);

//useAnalytics();

return (
<PageLayout>
<div className="bg-baby-blue dark:bg-dg-primary-1700 w-full pt-20 md:pt-24">
{/* Heading Section */}
<section
id="heading"
className="flex flex-col items-center justify-center m-auto py-16 md:py-32 bg-[url('https://lh3.googleusercontent.com/b9F35_JPlulVv0jS3UAYKJ2z6gz_AsWprQef_1wWTFGJlhEyLGfA1AthyUcdgrm1Qdk=w2400')] bg-cover"
>
<div className="my-8 flex flex-col md:flex-row justify-start items-center w-full max-w-custom px-8 xl:px-0">
<div className="w-full">
<h6 className="subheading">{_data.heading.subheading}</h6>
<h1 className="heading text-dg-secondary mt-2">{_data.heading.heading}</h1>
<p className="paragraph mt-4">{_data.heading.paragraph}</p>
</div>
</div>
</section>

<Wrapper padding={' py-90p'}>
<motion.section
id="status-numbers"
className="flex flex-col md:flex-row items-start justify-between w-full gap-90p px-90p"
initial={{ y: 60, opacity: 0 }}
whileInView={{ y: 0, opacity: 1 }}
transition={{ duration: 0.5, ease: 'easeOut' }}
<div className="bg-baby-blue dark:bg-dg-primary-1700 w-full pt-20 md:pt-24">
{/* Heading Section */}
<section
id="heading"
className="flex flex-col items-center justify-center m-auto py-16 md:py-32 bg-[url('https://lh3.googleusercontent.com/b9F35_JPlulVv0jS3UAYKJ2z6gz_AsWprQef_1wWTFGJlhEyLGfA1AthyUcdgrm1Qdk=w2400')] bg-cover"
>
{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>
<div className="my-8 flex flex-col md:flex-row justify-start items-center w-full max-w-custom px-8 xl:px-0">
<div className="w-full">
<h6 className="subheading">{_data.heading.subheading}</h6>
<h1 className="heading text-dg-secondary mt-2">{_data.heading.heading}</h1>
<p className="paragraph mt-4">{_data.heading.paragraph}</p>
</div>
))}
</motion.section>
</Wrapper>

{/* About the Client Section */}
<section id="client" className="flex flex-col items-center justify-center">
<div className="my-8 flex flex-col md:flex-row justify-center items-start w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2">
<h3 className="h3-heading text-teal-600">{_data.about.heading}</h3>
<p className="paragraph mt-4">{_data.about.paragraph}</p>
</div>
<div className="w-full md:w-1/2 grid grid-cols-2 md:grid-cols-3 gap-16 mt-8 md:mt-0">
<div className="hidden md:inline-block"></div>
<div className="float-left md:float-right text-left md:text-right">
<h5 className="text-teal-600 font-semibold">{_data.about.country_heading}</h5>
<p className="mt-4">{_data.about.country_name}</p>
</section>

<Wrapper padding={' py-90p'}>
<motion.section
id="status-numbers"
className="flex flex-col md:flex-row items-start justify-between w-full gap-90p px-90p"
initial={{ y: 60, opacity: 0 }}
whileInView={{ y: 0, opacity: 1 }}
transition={{ duration: 0.5, ease: 'easeOut' }}
>
{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>
</div>
))}
</motion.section>
</Wrapper>

{/* About the Client Section */}
<section id="client" className="flex flex-col items-center justify-center">
<div className="my-8 flex flex-col md:flex-row justify-center items-start w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2">
<h3 className="h3-heading text-teal-600">{_data.about.heading}</h3>
<p className="paragraph mt-4">{_data.about.paragraph}</p>
</div>
<div className="float-left md:float-right text-left md:text-right">
<h5 className="text-teal-600 font-semibold">{_data.about.industry_heading}</h5>
<p className="mt-4">{_data.about.industry_name}</p>
<div className="w-full md:w-1/2 grid grid-cols-2 md:grid-cols-3 gap-16 mt-8 md:mt-0">
<div className="hidden md:inline-block"></div>
<div className="float-left md:float-right text-left md:text-right">
<h4 className="text-teal-600 font-semibold">
{_data.about.country_heading}
</h4>
<p className="mt-4">{_data.about.country_name}</p>
</div>
<div className="float-left md:float-right text-left md:text-right">
<h4 className="text-teal-600 font-semibold">
{_data.about.industry_heading}
</h4>
<p className="mt-4">{_data.about.industry_name}</p>
</div>
</div>
</div>
</div>
</section>
</section>

{/* Domain Section */}
<section id="domain" className="flex flex-col items-center justify-center mt-16">
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading">{_data.domain.heading}</h3>
<p className="paragraph mt-4">{_data.domain.paragraph}</p>
{/* Domain Section */}
<section id="domain" className="flex flex-col items-center justify-center mt-16">
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading">{_data.domain.heading}</h3>
<p className="paragraph mt-4">{_data.domain.paragraph}</p>
</div>
</div>
</div>
</section>
</section>

{/* Challanges, Solution Section */}
<section
id="challanges_solution"
className="flex flex-col items-center justify-center mt-16"
>
<div className="my-8 flex flex-col md:flex-row justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2 md:pr-16">
<div>
<h3 className="h3-heading">{_data.challanges.heading}</h3>
<p className="text-sm text-dark-gray dark:text-white mt-4">
{_data.challanges.paragraph}
</p>
</div>
<div className="mt-8">
<h3 className="h3-heading">{_data.solution.heading}</h3>
<p className="text-sm text-dark-gray dark:text-white mt-4">
{_data.solution.paragraph}
</p>
{/* Challanges, Solution Section */}
<section
id="challanges_solution"
className="flex flex-col items-center justify-center mt-16"
>
<div className="my-8 flex flex-col md:flex-row justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2 md:pr-16">
<div>
<h3 className="h3-heading">{_data.challanges.heading}</h3>
<p className="text-sm text-dark-gray dark:text-white mt-4">
{_data.challanges.paragraph}
</p>
</div>
<div className="mt-8">
<h3 className="h3-heading">{_data.solution.heading}</h3>
<p className="text-sm text-dark-gray dark:text-white mt-4">
{_data.solution.paragraph}
</p>
</div>
</div>
<img
src={_data.solution.imgUrl}
alt="Case Study main image"
className="text-center w-full md:w-1/2"
/>
</div>
<img
src={_data.solution.imgUrl}
alt="Case Study main image"
className="text-center w-full md:w-1/2"
/>
</div>
</section>
</section>

{/* Results Section */}
<section id="results" className="flex flex-col items-center justify-center mt-16">
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading text-dg-secondary">{_data.results.heading}</h3>
<ul className="list-disc paragraph mt-2 pl-8">
{_data.results.list.map(item => (
<li key={item.id}>{item.text}</li>
))}
</ul>
{/* Results Section */}
<section id="results" className="flex flex-col items-center justify-center mt-16">
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading text-dg-secondary">{_data.results.heading}</h3>
<ul className="list-disc paragraph mt-2 pl-8">
{_data.results.list.map(item => (
<li key={item.id}>{item.text}</li>
))}
</ul>
</div>
</div>
</div>
</section>
</section>

{/* Technologies Section */}
<section
id="technologies"
className="flex flex-col items-center justify-center mt-16"
>
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading">Technologies</h3>
</div>
<div className="grid grid-cols-4 justify-center justify-items-center gap-8 xl:flex xl:flex-row items-center xl:justify-start xl:gap-16 w-full mt-8">
{_data.technologies.map(technology => (
<img
key={technology.id}
src={technology.link}
alt="Technology's image"
className="w-12 md:w-16 lg:w-20"
/>
))}
{/* Technologies Section */}
<section id="technologies" className="flex flex-col mt-16">
<div className="my-8 flex flex-col w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading">Technologies</h3>
</div>
<TechNuggets
tech={['.Net', 'MS SQL Server', 'React Native', 'React.JS']}
/>
</div>
</div>
</section>
</section>

{/* CTA Section */}
<section id="cta" className="flex flex-col items-center justify-center mt-16">
<div className="px-8 mt-8 mb-32 w-full max-w-custom">
<ActionCard
title="Let's Work Together!"
text="Business Intelligence portal which enhouses series of web applications & reporting tools used for in-depth analysis on product pricing, money flow, resources, employees, etc. Applications provide administrative users overview, as well as detail look scaled down to individual product."
btn1="More Projects"
btn2="Contact Us"
link1={'/portfolio'}
link2={'/contact'}
/>
</div>
</section>
</div>
{/* CTA Section */}
<section id="cta" className="flex flex-col items-center justify-center mt-16">
<div className="px-8 mt-8 mb-32 w-full max-w-custom">
<ActionCard
title="Let's Work Together!"
text="Business Intelligence portal which enhouses series of web applications & reporting tools used for in-depth analysis on product pricing, money flow, resources, employees, etc. Applications provide administrative users overview, as well as detail look scaled down to individual product."
btn1="More Projects"
btn2="Contact Us"
link1={'/portfolio'}
link2={'/contact'}
/>
</div>
</section>
</div>
</PageLayout>
);
}

+ 142
- 147
frontend/src/pages/CaseStudyStrata.jsx Просмотреть файл

@@ -8,34 +8,35 @@ import jquery from './../assets/icons/caseStudy/jquery.svg';
import react from './../assets/icons/caseStudy/react-native.svg';
import mssql from './../assets/icons/caseStudy/MSSQL.svg';
import { useEffect } from 'react';
import {motion} from 'framer-motion';
import { motion } from 'framer-motion';
import Wrapper from '../layout/Wrapper';
import TechNuggets from '../components/shared/TechNuggets';
//import useAnalytics from '../hooks/useAnalytics';

const numbers = [
{
value: 5,
value: '10k',
static: '+',
title: 'Team Members'
title: 'Users',
},
{
value: '3',
value: '230k',
static: '+',
title: 'Years Project duration'
title: 'Tests Ordered',
},
{
value: '1,6m',
value: '200k',
static: '+',
title: 'Transactions per Year'
}
]
title: 'Laboratory Results',
},
];

const _data = {
heading: {
subheading: 'Case Study',
heading: 'Health Tracking Software',
imgUrl: strata,
paragraph:
'COVID and Health Tracking Business Software',
paragraph: 'COVID and Health Tracking Business Software',
},

about: {
@@ -64,8 +65,7 @@ const _data = {
heading: 'Solution',
paragraph:
'To fulfill all requirements, we made a flexible application that consists of 3 parts: Admin portal, User portal, and User mobile app.',
imgUrl:
'https://i.postimg.cc/L43QFftg/Strata-Small.png',
imgUrl: 'https://i.postimg.cc/L43QFftg/Strata-Small.png',
},

results: {
@@ -111,160 +111,155 @@ const _data = {
};

export default function CaseStudyStrata() {

useEffect(() => {
document.title = 'Case Study: Healthcare Tracking Software';
},[]);
}, []);

//useAnalytics();
return (
<PageLayout>
<div className="bg-baby-blue dark:bg-dg-primary-1700 w-full pt-20 md:pt-24">
{/* Heading Section */}
<section
id="heading"
className={"flex flex-col items-center justify-center m-auto py-16 md:py-32 relative bg-cover bg-[url('https://i.postimg.cc/ZK08syVS/Strata.jpg')] bg-no-repeat"}
>
<div className="my-8 flex flex-col md:flex-row justify-start items-center w-full max-w-custom px-8 xl:px-0">
<div className="w-full">
<h6 className="subheading">{_data.heading.subheading}</h6>
<h1 className="heading text-dg-secondary mt-2">{_data.heading.heading}</h1>
<p className="paragraph mt-4">{_data.heading.paragraph}</p>
</div>
</div>
</section>

{/* <Wrapper padding={' py-90p'}>
<motion.section
id="status-numbers"
className="flex flex-col md:flex-row items-start justify-between w-full gap-90p px-90p"
initial={{ y: 60, opacity: 0 }}
whileInView={{ y: 0, opacity: 1 }}
transition={{ duration: 0.5, ease: 'easeOut' }}
<div className="bg-baby-blue dark:bg-dg-primary-1700 w-full pt-20 md:pt-24">
{/* Heading Section */}
<section
id="heading"
className={
"flex flex-col items-center justify-center m-auto py-16 md:py-32 relative bg-cover bg-[url('https://i.postimg.cc/ZK08syVS/Strata.jpg')] bg-no-repeat"
}
>
{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>
<div className="my-8 flex flex-col md:flex-row justify-start items-center w-full max-w-custom px-8 xl:px-0">
<div className="w-full">
<h6 className="subheading">{_data.heading.subheading}</h6>
<h1 className="heading text-dg-secondary mt-2">{_data.heading.heading}</h1>
<p className="paragraph mt-4">{_data.heading.paragraph}</p>
</div>
))}
</motion.section>
</Wrapper> */}

{/* About the Client Section */}
<section id="client" className="flex flex-col items-center justify-center mt-16">
<div className="my-8 flex flex-col md:flex-row justify-center items-start w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2">
<h3 className="h3-heading text-teal-600">{_data.about.heading}</h3>
<p className="paragraph mt-4">{_data.about.paragraph}</p>
</div>
<div className="w-full md:w-1/2 grid grid-cols-2 md:grid-cols-3 gap-16 mt-8 md:mt-0">
<div className="hidden md:inline-block"></div>
<div className="float-left md:float-right text-left md:text-right">
<h5 className="text-teal-600 font-semibold">
{_data.about.country_heading}
</h5>
<p className="mt-4">{_data.about.country_name}</p>
</section>

<Wrapper padding={' py-90p'}>
<motion.section
id="status-numbers"
className="flex flex-col md:flex-row items-start justify-between w-full gap-90p px-90p"
initial={{ y: 60, opacity: 0 }}
whileInView={{ y: 0, opacity: 1 }}
transition={{ duration: 0.5, ease: 'easeOut' }}
>
{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>
</div>
))}
</motion.section>
</Wrapper>

{/* About the Client Section */}
<section id="client" className="flex flex-col items-center justify-center mt-16">
<div className="my-8 flex flex-col md:flex-row justify-center items-start w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2">
<h2 className="h3-heading text-teal-600">{_data.about.heading}</h2>
<p className="paragraph mt-4">{_data.about.paragraph}</p>
</div>
<div className="float-left md:float-right text-left md:text-right">
<h5 className="text-teal-600 font-semibold">
{_data.about.industry_heading}
</h5>
<p className="mt-4">{_data.about.industry_name}</p>
<div className="w-full md:w-1/2 grid grid-cols-2 md:grid-cols-3 gap-16 mt-8 md:mt-0">
<div className="hidden md:inline-block"></div>
<div className="float-left md:float-right text-left md:text-right">
<h3 className="text-teal-600 font-semibold">
{_data.about.country_heading}
</h3>
<p className="mt-4">{_data.about.country_name}</p>
</div>
<div className="float-left md:float-right text-left md:text-right">
<h3 className="text-teal-600 font-semibold">
{_data.about.industry_heading}
</h3>
<p className="mt-4">{_data.about.industry_name}</p>
</div>
</div>
</div>
</div>
</section>
</section>

{/* Domain Section */}
<section id="domain" className="flex flex-col items-center justify-center mt-16">
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading">{_data.domain.heading}</h3>
<p className="paragraph mt-4">{_data.domain.paragraph}</p>
{/* Domain Section */}
<section id="domain" className="flex flex-col items-center justify-center mt-16">
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading">{_data.domain.heading}</h3>
<p className="paragraph mt-4">{_data.domain.paragraph}</p>
</div>
</div>
</div>
</section>
</section>

{/* Challanges, Solution Section */}
<section
id="challanges_solution"
className="flex flex-col items-center justify-center mt-16"
>
<div className="my-8 flex flex-col md:flex-row justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2 md:pr-16">
<div>
<h3 className="h3-heading">{_data.challanges.heading}</h3>
<p className="text-sm text-dark-gray dark:text-white mt-4">
{_data.challanges.paragraph}
</p>
</div>
<div className="mt-8">
<h3 className="h3-heading">{_data.solution.heading}</h3>
<p className="text-sm text-dark-gray dark:text-white mt-4">
{_data.solution.paragraph}
</p>
{/* Challanges, Solution Section */}
<section
id="challanges_solution"
className="flex flex-col items-center justify-center mt-16"
>
<div className="my-8 flex flex-col md:flex-row justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2 md:pr-16">
<div>
<h3 className="h3-heading">{_data.challanges.heading}</h3>
<p className="text-sm text-dark-gray dark:text-white mt-4">
{_data.challanges.paragraph}
</p>
</div>
<div className="mt-8">
<h3 className="h3-heading">{_data.solution.heading}</h3>
<p className="text-sm text-dark-gray dark:text-white mt-4">
{_data.solution.paragraph}
</p>
</div>
</div>
<img
src={_data.solution.imgUrl}
alt="Case Study main image"
className="text-center w-full md:w-1/2"
/>
</div>
<img
src={_data.solution.imgUrl}
alt="Case Study main image"
className="text-center w-full md:w-1/2"
/>
</div>
</section>
</section>

{/* Results Section */}
<section id="results" className="flex flex-col items-center justify-center mt-16">
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading text-dg-secondary">{_data.results.heading}</h3>
<ul className="list-disc paragraph mt-2 pl-8">
{_data.results.list.map(item => (
<li key={item.id}>{item.text}</li>
))}
</ul>
{/* Results Section */}
<section id="results" className="flex flex-col items-center justify-center mt-16">
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading text-dg-secondary">{_data.results.heading}</h3>
<ul className="list-disc paragraph mt-2 pl-8">
{_data.results.list.map(item => (
<li key={item.id}>{item.text}</li>
))}
</ul>
</div>
</div>
</div>
</section>
</section>

{/* Technologies Section */}
<section
id="technologies"
className="flex flex-col items-center justify-center mt-16"
>
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading">Technologies</h3>
</div>
<div className="grid grid-cols-4 justify-center justify-items-center gap-8 xl:flex xl:flex-row items-center xl:justify-start xl:gap-16 w-full mt-8">
{_data.technologies.map(technology => (
<img
key={technology.id}
src={technology.link}
alt="Technology's image"
className="w-12 md:w-16 lg:w-20"
/>
))}
{/* Technologies Section */}
<section id="technologies" className="flex flex-col mt-16">
<div className="my-8 flex flex-col w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading">Technologies</h3>
</div>
<TechNuggets
tech={['C#', 'MVC', 'SQL','Ajax','React Native']}
/>
</div>
</div>
</section>
</section>

{/* CTA Section */}
<section id="cta" className="flex flex-col items-center justify-center mt-16">
<div className="px-8 mt-8 mb-32 w-full max-w-custom">
<ActionCard
title="Let's Work Together!"
text="Business Intelligence portal which enhouses series of web applications & reporting tools used for in-depth analysis on product pricing, money flow, resources, employees, etc. Applications provide administrative users overview, as well as detail look scaled down to individual product."
btn1="More Projects"
btn2="Contact Us"
link1={'/portfolio'}
link2={'/contact'}
/>
</div>
</section>
</div>
{/* CTA Section */}
<section id="cta" className="flex flex-col items-center justify-center mt-16">
<div className="px-8 mt-8 mb-32 w-full max-w-custom">
<ActionCard
title="Let's Work Together!"
text="Business Intelligence portal which enhouses series of web applications & reporting tools used for in-depth analysis on product pricing, money flow, resources, employees, etc. Applications provide administrative users overview, as well as detail look scaled down to individual product."
btn1="More Projects"
btn2="Contact Us"
link1={'/portfolio'}
link2={'/contact'}
/>
</div>
</section>
</div>
</PageLayout>
);
}

+ 135
- 131
frontend/src/pages/CaseStudyTicketing.jsx Просмотреть файл

@@ -8,25 +8,26 @@ import mssql from './../assets/icons/caseStudy/MSSQL.svg';
import raspberry from './../assets/icons/caseStudy/raspberrypi.svg';
import ionic from './../assets/icons/caseStudy/ionic.svg';
import { useEffect } from 'react';
import {motion} from 'framer-motion';
import { motion } from 'framer-motion';
import TechNuggets from '../components/shared/TechNuggets';
//import useAnalytics from '../hooks/useAnalytics';
const numbers = [
{
value: 10,
static: '+',
title: 'Projects'
title: 'Projects',
},
{
value: 10,
static: '+',
title: 'Years Project Duration'
title: 'Years Project Duration',
},
{
value: '1,5m',
static: '+',
title: 'Transactions per Year'
}
]
title: 'Transactions per Year',
},
];

const _data = {
heading: {
@@ -123,153 +124,156 @@ const _data = {

export default function CaseStudyTicketing() {

useEffect(() => {
document.title = 'Case Study: Ticketing System For Passengers';
},[]);
}, []);

//useAnalytics();

return (
<PageLayout>
<div className="bg-baby-blue dark:bg-dg-primary-1700 w-full pt-20 md:pt-24">
{/* Heading Section */}
<section
id="heading"
className="flex flex-col items-center justify-center m-auto py-16 md:py-32 bg-[url('https://lh6.googleusercontent.com/iYNVVAYNEmKe9mY9IFK39EUWT2GZLjnZjF0QoghP8HV1_q8arGWEryvCcPhOWRzRTwU=w2400')] bg-cover"
>
<div className="my-8 flex flex-col md:flex-row justify-start items-center w-full max-w-custom px-8 xl:px-0">
<div className="w-full">
<h6 className="subheading">{_data.heading.subheading}</h6>
<h1 className="heading text-dg-secondary mt-2">{_data.heading.heading}</h1>
<p className="paragraph mt-4">{_data.heading.paragraph}</p>
</div>
</div>
</section>

<Wrapper padding={' py-90p'}>
<motion.section
id="status-numbers"
className="flex flex-col md:flex-row items-center justify-between w-full gap-90p px-90p"
initial={{ y: 60, opacity: 0 }}
whileInView={{ y: 0, opacity: 1 }}
transition={{ duration: 0.5, ease: 'easeOut' }}
<div className="bg-baby-blue dark:bg-dg-primary-1700 w-full pt-20 md:pt-24">
{/* Heading Section */}
<section
id="heading"
className="flex flex-col items-center justify-center m-auto py-16 md:py-32 bg-[url('https://lh6.googleusercontent.com/iYNVVAYNEmKe9mY9IFK39EUWT2GZLjnZjF0QoghP8HV1_q8arGWEryvCcPhOWRzRTwU=w2400')] bg-cover"
>
{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>
<div className="my-8 flex flex-col md:flex-row justify-start items-center w-full max-w-custom px-8 xl:px-0">
<div className="w-full">
<h6 className="subheading">{_data.heading.subheading}</h6>
<h1 className="heading text-dg-secondary mt-2">{_data.heading.heading}</h1>
<p className="paragraph mt-4">{_data.heading.paragraph}</p>
</div>
))}
</motion.section>
</Wrapper>

{/* About the Client Section */}
<section id="client" className="flex flex-col items-start justify-center">
<div className="my-8 flex flex-col md:flex-row justify-center items-start w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2">
<h3 className="h3-heading text-teal-600">{_data.about.heading}</h3>
<p className="paragraph mt-4">{_data.about.paragraph}</p>
</div>
<div className="w-full md:w-1/2 grid grid-cols-2 md:grid-cols-3 gap-16 mt-8 md:mt-0">
<div className="hidden md:inline-block"></div>
<div className="float-left md:float-right text-left md:text-right">
<h5 className="text-teal-600 font-semibold">
{_data.about.country_heading}
</h5>
<p className="mt-4">{_data.about.country_name}</p>
</section>

<Wrapper padding={' py-90p'}>
<motion.section
id="status-numbers"
className="flex flex-col md:flex-row items-center justify-between w-full gap-90p px-90p"
initial={{ y: 60, opacity: 0 }}
whileInView={{ y: 0, opacity: 1 }}
transition={{ duration: 0.5, ease: 'easeOut' }}
>
{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>
</div>
))}
</motion.section>
</Wrapper>

{/* About the Client Section */}
<section id="client" className="flex flex-col items-start justify-center">
<div className="my-8 flex flex-col md:flex-row justify-center items-start w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2">
<h3 className="h3-heading text-teal-600">{_data.about.heading}</h3>
<p className="paragraph mt-4">{_data.about.paragraph}</p>
</div>
<div className="float-left md:float-right text-left md:text-right">
<h5 className="text-teal-600 font-semibold">
{_data.about.industry_heading}
</h5>
<p className="mt-4">{_data.about.industry_name}</p>
<div className="w-full md:w-1/2 grid grid-cols-2 md:grid-cols-3 gap-16 mt-8 md:mt-0">
<div className="hidden md:inline-block"></div>
<div className="float-left md:float-right text-left md:text-right">
<h4 className="text-teal-600 font-semibold">
{_data.about.country_heading}
</h4>
<p className="mt-4">{_data.about.country_name}</p>
</div>
<div className="float-left md:float-right text-left md:text-right">
<h4 className="text-teal-600 font-semibold">
{_data.about.industry_heading}
</h4>
<p className="mt-4">{_data.about.industry_name}</p>
</div>
</div>
</div>
</div>
</section>
</section>

{/* Domain Section */}
<section id="domain" className="flex flex-col items-center justify-center mt-16">
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading">{_data.domain.heading}</h3>
<p className="paragraph mt-4">{_data.domain.paragraph}</p>
{/* Domain Section */}
<section id="domain" className="flex flex-col items-center justify-center mt-16">
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading">{_data.domain.heading}</h3>
<p className="paragraph mt-4">{_data.domain.paragraph}</p>
</div>
</div>
</div>
</section>
</section>

{/* Challanges, Solution Section */}
<section
id="challanges_solution"
className="flex flex-col items-center justify-center mt-16"
>
<div className="my-8 flex flex-col md:flex-row justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2 md:pr-16">
<div>
<h3 className="h3-heading">{_data.challanges.heading}</h3>
<p className="text-sm text-dark-gray dark:text-white mt-4">
{_data.challanges.paragraph}
</p>
</div>
<div className="mt-8">
<h3 className="h3-heading">{_data.solution.heading}</h3>
<p className="text-sm text-dark-gray dark:text-white mt-4">
{_data.solution.paragraph}
</p>
{/* Challanges, Solution Section */}
<section
id="challanges_solution"
className="flex flex-col items-center justify-center mt-16"
>
<div className="my-8 flex flex-col md:flex-row justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full md:w-1/2 md:pr-16">
<div>
<h3 className="h3-heading">{_data.challanges.heading}</h3>
<p className="text-sm text-dark-gray dark:text-white mt-4">
{_data.challanges.paragraph}
</p>
</div>
<div className="mt-8">
<h3 className="h3-heading">{_data.solution.heading}</h3>
<p className="text-sm text-dark-gray dark:text-white mt-4">
{_data.solution.paragraph}
</p>
</div>
</div>
<img
src={_data.solution.imgUrl}
alt="Case Study main image"
className="text-center w-full md:w-1/2"
/>
</div>
<img
src={_data.solution.imgUrl}
alt="Case Study main image"
className="text-center w-full md:w-1/2"
/>
</div>
</section>
</section>

{/* Results Section */}
<section id="results" className="flex flex-col items-center justify-center mt-16">
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading text-dg-secondary">{_data.results.heading}</h3>
<ul className="list-disc paragraph mt-2 pl-8">
{_data.results.list.map(item => (
<li key={item.id}>{item.text}</li>
))}
</ul>
{/* Results Section */}
<section id="results" className="flex flex-col items-center justify-center mt-16">
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading text-dg-secondary">{_data.results.heading}</h3>
<ul className="list-disc paragraph mt-2 pl-8">
{_data.results.list.map(item => (
<li key={item.id}>{item.text}</li>
))}
</ul>
</div>
</div>
</div>
</section>
</section>

{/* Technologies Section */}
<section
id="technologies"
className="flex flex-col items-center justify-center mt-16"
>
<div className="my-8 flex flex-col justify-center items-center w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading">Technologies</h3>
{/* Technologies Section */}
<section
id="technologies"
className="flex flex-col mt-16"
>
<div className="my-8 flex flex-col w-full max-w-custom m-auto px-8 xl:px-0">
<div className="w-full">
<h3 className="h3-heading">Technologies</h3>
</div>
<TechNuggets
tech={['.Net', 'Angular', 'Java', 'MSSQL', 'Ionic', 'Raspberry PI']}
/>
</div>
<TechNuggets tech={['.Net','Angular','Java','MSSQL','Ionic','Raspberry PI']}/>
</div>
</section>
</section>

{/* CTA Section */}
<section id="cta" className="flex flex-col items-center justify-center mt-16">
<div className="px-8 mt-8 mb-32 w-full max-w-custom">
<ActionCard
title="Let's Work Together!"
text="Business Intelligence portal which enhouses series of web applications & reporting tools used for in-depth analysis on product pricing, money flow, resources, employees, etc. Applications provide administrative users overview, as well as detail look scaled down to individual product."
btn1="More Projects"
btn2="Contact Us"
link1={'/portfolio'}
link2={'/contact'}
/>
</div>
</section>
</div>
{/* CTA Section */}
<section id="cta" className="flex flex-col items-center justify-center mt-16">
<div className="px-8 mt-8 mb-32 w-full max-w-custom">
<ActionCard
title="Let's Work Together!"
text="Business Intelligence portal which enhouses series of web applications & reporting tools used for in-depth analysis on product pricing, money flow, resources, employees, etc. Applications provide administrative users overview, as well as detail look scaled down to individual product."
btn1="More Projects"
btn2="Contact Us"
link1={'/portfolio'}
link2={'/contact'}
/>
</div>
</section>
</div>
</PageLayout>
);
}

+ 5
- 12
frontend/src/pages/ContactPage.jsx Просмотреть файл

@@ -1,11 +1,7 @@
import React, { useEffect, useState } from 'react';
import Contact from '../components/shared/Contact';
import PageLayout from '../layout/PageLayout';
import Layout from '../layout/PageLayout';
import axios from 'axios';
import useDataApi from '../hooks/useDataApi';


//import useAnalytics from '../hooks/useAnalytics';

function ContactPage() {
const [data, setData] = useState('');
@@ -14,18 +10,15 @@ function ContactPage() {

useEffect(() => {
document.title = 'Contact Us';
},[]);

}, []);
return (
<PageLayout>
<section
id="contact"
className="h-fit bg-baby-blue dark:bg-dg-primary-1600 mt-90p"
>
<section id="contact" className="h-fit bg-baby-blue dark:bg-dg-primary-1600 mt-90p">
<h1 className="hidden">Contact us: Tell Us about Your Idea!</h1>
<Contact defaultIndex={0} />
</section>
</PageLayout>
</PageLayout>
);
}


+ 34
- 111
frontend/src/pages/Portfolio.jsx Просмотреть файл

@@ -13,6 +13,7 @@ import CardsGrid from '../components/CardsGrid';
import PageLayout from '../layout/PageLayout';

import StrataThumb from './../assets/images/CaseStudy/StrataThumb.jpg';
//import useAnalytics from '../hooks/useAnalytics';

const _data = {
heading: {
@@ -24,159 +25,81 @@ const _data = {
cards: [
{
id: 0,
title: 'Bi Healthcare Solution System',
imgUrl:
'https://lh6.googleusercontent.com/D7N87i3udAln4YBp5SbaSI-9r2pVnnT5K2VT6p0G3dQanVgTMC2tdgz71PWOYco-7yQ=w2400',
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',
'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',
'https://lh5.googleusercontent.com/f_G0H0C_qLHhsU8PBj6uTkNigzKiXzd24B_pgJ6UqVmBKlU2Lyxv2r5lf6uvY9d_0PY=w2400',
alt: 'Ticketing System for Passengers',
link: '/casestudyticketing',
},
{
id: 3,
title: 'Financial Engine',
imgUrl:
'https://lh3.googleusercontent.com/n-vcF1h8o4o3_CWZXoT-BQDLGFjL3_wt1twsDajycp8IhiiA2UkBoecsGd-ly_LRxJI=w2400',
'https://lh3.googleusercontent.com/n-vcF1h8o4o3_CWZXoT-BQDLGFjL3_wt1twsDajycp8IhiiA2UkBoecsGd-ly_LRxJI=w2400',
alt: 'Financial Engine',
link: '/casestudyfinancial',
},
{
id: 4,
title: 'Centralized Monitoring System',
imgUrl:
'https://lh4.googleusercontent.com/CwrSwX4UVcU-nYhEk4wWqsK8TUJbt881kVx2i4ryXYJ3xIsN8d7F1bY0qO_0thHCbBM=w2400',
'https://lh4.googleusercontent.com/CwrSwX4UVcU-nYhEk4wWqsK8TUJbt881kVx2i4ryXYJ3xIsN8d7F1bY0qO_0thHCbBM=w2400',
alt: 'Centralized Monitoring System',
link: '/casestudycentralized',
},
{
id: 5,
title: 'Health Tracking Software',
imgUrl: 'https://i.postimg.cc/HsKGcXVv/Strata-Thumb.jpg',
alt: 'Health Tracking Software',
link: '/casestudystrata',
},
],
};

export default function Portfolio() {
// const [cntPortfolio, setCntPortfolio] = useState('');
// const [array,setArray] = useState([]);
// const [smallArray, setSmallArray] = useState([]);
// const [largeArray, setLargeArray] = useState([]);
// const [current, setCurrent] = useState([]);
// const [isLoaded, setIsLoaded] = useState('');

// const api_url = process.env.REACT_APP_API_URL;

// const handleArray = (array) => {
// if (array == undefined) return;
// if (array.length <= 0) return;

// let left = false;
// let largeIndex = 4;
// let largeArray = [];
// let smallArray=[];
// let current = [];

// //ako je desno onda je 5
// //ako je levo onda je 7

// array.map((item) => {
// if (item.attributes.IsLarge === true) {
// largeArray.push(item);
// } else {
// smallArray.push(item);
// }
// })


// const index = smallArray.length + largeArray.length;

// for (let i = 0; i < index; i++) {
// //console.log(index)
// if(largeIndex - i == 0) {
// current.push(largeArray.shift());
// left = !left;
// if(!left) {
// largeIndex = largeIndex + 6;
// } else {
// largeIndex = largeIndex + 4;
// }

// } else {
// current.push(smallArray.shift());
// }
// }
// setCurrent(current);
// }

// useEffect(async () => {
// var vid = document.getElementById('animation');
// vid.playbackRate = 2;
// var temp = [];
// axios
// .get(
// `${api_url}/api/portfoliopage?populate[0]=heading&&populate[1]=case_studies&&populate[2]=case_studies.img`,
// )
// .then(res => {
// //console.log(res.data.data.attributes);
// setCntPortfolio(res.data.data.attributes);
// setArray(res.data.data.attributes.case_studies.data)
// setIsLoaded(true);
// })
// .catch(err => {
// console.log(err);
// setIsLoaded(false);
// });

// }, []);

// useEffect(() => {
// console.log(array);
// handleArray(array);
// },[array]);

// 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">
// <video id="animation" width="540" height="540" autoPlay muted loop>
// <source src={Animation_Diligent} type="video/webm" />
// Loading...
// </video>
// </div>
// );
// }

useEffect(() => {
document.title = 'Case Studies';
},[]);
}, []);

//useAnalytics();

return (
<PageLayout>
<div className="flex flex-col gap-90p pt-32">
<Wrapper>
<div className="flex flex-col gap-8p">
<PageTitle
heading={_data.heading.heading}
subheading={_data.heading.subheading}
left
color
/>
<p className="paragraph">{_data.heading.paragraph}</p>
</div>
</Wrapper>
<Wrapper>
<CardsGrid data={_data.cards} />
</Wrapper>
</div>
<div className="flex flex-col gap-90p pt-32">
<Wrapper>
<h1 className="hidden">Our Work - Case Studies</h1>
<div className="flex flex-col gap-8p">
<PageTitle
heading={_data.heading.heading}
subheading={_data.heading.subheading}
left
color
/>
<p className="paragraph">{_data.heading.paragraph}</p>
</div>
</Wrapper>
<Wrapper>
<CardsGrid data={_data.cards} />
</Wrapper>
</div>
</PageLayout>
);
}

+ 3
- 0
frontend/src/pages/PrivacyPolicy.jsx Просмотреть файл

@@ -1,4 +1,5 @@
import React, { useEffect } from 'react';
//import useAnalytics from '../hooks/useAnalytics';
import Wrapper from '../layout/Wrapper';

const PrivacyPolicy = () => {
@@ -7,6 +8,8 @@ const PrivacyPolicy = () => {
document.title = 'Privacy Policy';
}, []);

//useAnalytics();


return (
<div className="mt-32p">

+ 123
- 137
frontend/src/pages/ProcessPage.jsx Просмотреть файл

@@ -10,140 +10,118 @@ import axios from 'axios';

import Animation_Diligent from '../assets/animation_diligent.webm';

import {ReactComponent as ProcessSvg} from './../assets/images/Process.svg';
import { ReactComponent as ProcessSvg } from './../assets/images/Process.svg';
import { m } from 'framer-motion';
import PageLayout from '../layout/PageLayout';
import ProcessFacelessSlider from '../components/shared/ProcessFacelessSlider';
import useWindowSize from '../hooks/useWindowSize';
import ProcessSlider from '../components/ProcessSlider';
//import useAnalytics from '../hooks/useAnalytics';

const _data = {
heading : {
heading : "How We Do It?",
subheading: "Our Process",
paragraph: "We work with our clients to deliver the full software release lifecycle, from development to final rollout. We understand how important a good process is for success because our team members have deep backgrounds in product development. Our clients can rely on us for a complete software release solution that meets their needs and achieves their desired outcomes."
heading: {
heading: 'How We Do It?',
subheading: 'Our Process',
paragraph:
'We work with our clients to deliver the full software release lifecycle, from development to final rollout. We understand how important a good process is for success because our team members have deep backgrounds in product development. Our clients can rely on us for a complete software release solution that meets their needs and achieves their desired outcomes.',
},
processImg : {
url: ""
processImg: {
url: '',
},
cards : [
cards: [
{
id: "1",
title: "Figure It Out",
id: '1',
title: 'Figure It Out',
subtitle: "After understanding the company's goals, we build a digital strategy.",
paragraphs: [
{
paragraph: "We collaborate with you to comprehend each business possibility associated with your project. Early technological issues are identified, followed by study and solution architecture. Our user-centric methodology yields results that are straightforward and interesting. To better understand your user base, we create Personas, Journey Mapping, and Usability Testing."
}
]
paragraph:
'We collaborate with you to comprehend each business possibility associated with your project. Early technological issues are identified, followed by study and solution architecture. Our user-centric methodology yields results that are straightforward and interesting. To better understand your user base, we create Personas, Journey Mapping, and Usability Testing.',
},
],
},
{
id: "2",
title: "Solution Design",
subtitle: "Align user and business strategies.",
id: '2',
title: 'Solution Design',
subtitle: 'Align user and business strategies.',
paragraphs: [
{
paragraph: "User experience (UX) User research inevitably leads to design. Know your users, their requirements, and their objectives. Our multidisciplinary design team creates system flows, journey maps, annotated wireframes, final UI designs, and click-model prototypes."
paragraph:
'User experience (UX) User research inevitably leads to design. Know your users, their requirements, and their objectives. Our multidisciplinary design team creates system flows, journey maps, annotated wireframes, final UI designs, and click-model prototypes.',
},
{
paragraph: "Close communication is essential for success here, and concepts are iterated on both our and your teams. We'll keep optimizing until we have the ideal design that meets your needs and those of your users."
}
]
paragraph:
"Close communication is essential for success here, and concepts are iterated on both our and your teams. We'll keep optimizing until we have the ideal design that meets your needs and those of your users.",
},
],
},
{
id: "3",
title: "Build",
subtitle: "Delightful user experiences meet precise engineering.",
id: '3',
title: 'Build',
subtitle: 'Delightful user experiences meet precise engineering.',
paragraphs: [
{
paragraph: "Diligent can point you in the direction of the appropriate framework, language, and platform for your project, whether you already have a codebase or you start from scratch. Our talented group of developers includes computer scientists who are proficient in a variety of programming languages."
paragraph:
'Diligent can point you in the direction of the appropriate framework, language, and platform for your project, whether you already have a codebase or you start from scratch. Our talented group of developers includes computer scientists who are proficient in a variety of programming languages.',
},
{
paragraph: "We'll assist you in selecting the best technology for your project. We proceed with secure front-end, back-end, and full-stack development after deciding on the optimal strategy."
}
]
paragraph:
"We'll assist you in selecting the best technology for your project. We proceed with secure front-end, back-end, and full-stack development after deciding on the optimal strategy.",
},
],
},
{
id: "4",
title: "QA Test",
subtitle: "Maximum efficiency, zero bugs.",
id: '4',
title: 'QA Test',
subtitle: 'Maximum efficiency, zero bugs.',
paragraphs: [
{
paragraph: "We take pride in creating quality software. Our code is scalable, reusable, readable, and high performing. We have developed extensive testing processes and standardized Diligent Software Practices thanks to our more than 7 years of expertise in software development with a wide range of projects."
}
]
paragraph:
'We take pride in creating quality software. Our code is scalable, reusable, readable, and high performing. We have developed extensive testing processes and standardized Diligent Software Practices thanks to our more than 7 years of expertise in software development with a wide range of projects.',
},
],
},
{
id: "5",
title: "Launch",
subtitle: "Go Live!",
id: '5',
title: 'Launch',
subtitle: 'Go Live!',
paragraphs: [
{
paragraph: "We are prepared to launch after all sprints have ended and User Acceptance Testing (UAT) has been successful. Hosting is often done with Amazon AWS, which allows us to quickly grow, backup, and manage your application."
paragraph:
'We are prepared to launch after all sprints have ended and User Acceptance Testing (UAT) has been successful. Hosting is often done with Amazon AWS, which allows us to quickly grow, backup, and manage your application.',
},
{
paragraph: "Depending on the nature and complexity of the project, one or several releases may be appropriate. Your time to market will be accelerated in either case by our agile development."
}
]
paragraph:
'Depending on the nature and complexity of the project, one or several releases may be appropriate. Your time to market will be accelerated in either case by our agile development.',
},
],
},
{
id: "6",
title: "Maintain and Improve",
subtitle: "Continually optimize and grow.",
id: '6',
title: 'Maintain and Improve',
subtitle: 'Continually optimize and grow.',
paragraphs: [
{
paragraph: "We aim to provide long-term support for your program and establish ourselves as a reliable technological partner. We're here to support you while you update, monitor, and manage your app."
paragraph:
"We aim to provide long-term support for your program and establish ourselves as a reliable technological partner. We're here to support you while you update, monitor, and manage your app.",
},
{
paragraph: "We will work with you to ensure stability and longevity. We also assist with new concepts and features. Allow us to assist you with your plan so you may keep wowing your users, clients, and investors."
}
]
paragraph:
'We will work with you to ensure stability and longevity. We also assist with new concepts and features. Allow us to assist you with your plan so you may keep wowing your users, clients, and investors.',
},
],
},

],
ActionCard : {
heading: "Let’s Work Together!",
paragraph: "Business Intelligence portal which enhouses series of web applications & reporting tools used for in-depth analysis on product pricing, money flow, resources, employees, etc. Applications provide administrative users overview, as well as detail look scaled down to individual product.",
primaryBtn: "Contact Us",
secondaryBtn: "Portfolio"
}
}
ActionCard: {
heading: 'Let’s Work Together!',
paragraph:
'Business Intelligence portal which enhouses series of web applications & reporting tools used for in-depth analysis on product pricing, money flow, resources, employees, etc. Applications provide administrative users overview, as well as detail look scaled down to individual product.',
primaryBtn: 'Contact Us',
secondaryBtn: 'Portfolio',
},
};

const ProcessPage = () => {
//const api_url = process.env.REACT_APP_API_URL;
// const [cntProcess, setCntProcess] = useState('');
// const [isLoaded, setIsLoaded] = useState('');
// useEffect(() => {
// var vid = document.getElementById('animation');
// vid.playbackRate = 2;
// async function fetch() {
// axios
// .get(
// `${api_url}/api/process-page`,
// )
// .then(res => {
// setCntProcess(res.data.data.attributes);
// //console.log(res.data.data.attributes);
// setIsLoaded(true);
// })
// .catch(err => {
// console.log(err);
// setIsLoaded(false);
// });
// }
// fetch();
// }, []);

// 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">
// <video id="animation" width="540" height="540" autoPlay muted loop>
// <source src={Animation_Diligent} type="video/webm" />
// Loading...
// </video>
// </div>
// );
// }

const [isMobile, setIsMobile] = useState(false);

@@ -151,7 +129,9 @@ const ProcessPage = () => {

useEffect(() => {
document.title = 'Process';
},[]);
}, []);

//useAnalytics();

useEffect(() => {
if (windowInfo.width < 1000)
@@ -162,59 +142,65 @@ const ProcessPage = () => {

return (
<PageLayout>
<div className="pt-32">
{_data.heading.heading && (
<Wrapper>
<PageTitle
left
color
heading={_data.heading.heading}
subheading={_data.heading.subheading}
/>
{/* <div className="flex justify-center items-center mt-90p overflow-x-auto">
<div className="pt-32">
{_data.heading.heading && (
<Wrapper>
<h1 className="hidden">Our Process - How We Do It?</h1>
<PageTitle
left
color
heading={_data.heading.heading}
subheading={_data.heading.subheading}
/>
{/* <div className="flex justify-center items-center mt-90p overflow-x-auto">
<div className='w-full' draggable >
<ProcessSvg className='' />
</div>
</div> */}
<div className="relative mx-auto my-32p md:my-90p">
{!isMobile ? (
<div className='w-full'>
<ProcessSvg className='' />
</div>
) :
(
<div className='' >
<ProcessSlider/>
</div>
)
}
</div>
<p className="my-90p">{_data.heading.paragraph}</p>
</Wrapper>
)}
<Wrapper bg padding={' py-90p'}>
{_data.cards.length > 0 && (
<ProcessCardsWrapper>
{_data.cards.map((item, index) => (
<ProcessCard
key={index}
id={item.id}
title={item.title}
subtitle={item.subtitle}
text={item.paragraphs}
numeric
/>
))}
</ProcessCardsWrapper>
<div className="relative mx-auto my-32p md:my-90p">
{!isMobile ? (
<div className="w-full">
<ProcessSvg className="" />
</div>
) : (
<div className="">
<ProcessSlider />
</div>
)}
</div>
<p className="my-90p">{_data.heading.paragraph}</p>
</Wrapper>
)}
</Wrapper>
<Wrapper>
<div className='my-90p'>
<ActionCard title={_data.ActionCard.heading} text={_data.ActionCard.paragraph} btn1={_data.ActionCard.primaryBtn} btn2={_data.ActionCard.secondaryBtn} link1={"/contact"} link2={'/portfolio'}/>
</div>
</Wrapper>
</div>
<Wrapper bg padding={' py-90p'}>
{_data.cards.length > 0 && (
<ProcessCardsWrapper>
{_data.cards.map((item, index) => (
<ProcessCard
key={index}
id={item.id}
title={item.title}
subtitle={item.subtitle}
text={item.paragraphs}
numeric
/>
))}
</ProcessCardsWrapper>
)}
</Wrapper>
<Wrapper>
<div className="my-90p">
<ActionCard
title={_data.ActionCard.heading}
text={_data.ActionCard.paragraph}
btn1={_data.ActionCard.primaryBtn}
btn2={_data.ActionCard.secondaryBtn}
link1={'/contact'}
link2={'/portfolio'}
/>
</div>
</Wrapper>
</div>
</PageLayout>
);
};

+ 219
- 0
frontend/src/pages/WorkWithUs.jsx Просмотреть файл

@@ -0,0 +1,219 @@
import React, { Children, useEffect } from 'react'
import { Link } from 'react-router-dom'
import CustomLink from '../components/root/CustomLink'
import TertiaryButton from '../components/root/TertiaryButton'
import ActionCard from '../components/shared/ActionCard'
import CardLife from '../components/shared/CardLife'
import PageHeading from '../components/shared/PageHeading'
import PageTitle from '../components/shared/PageTitle'
import Testimonials from '../components/Testimonials'
//import useAnalytics from '../hooks/useAnalytics'
import Wrapper from '../layout/Wrapper'
import {ReactComponent as DownalodIcon } from './../assets/download-icon.svg'
import {ReactComponent as BusIcon } from './../assets/icons/workwithus/bus.svg'
import {ReactComponent as FintechIcon } from './../assets/icons/workwithus/empty-wallet-tick.svg'
import {ReactComponent as HospitalIcon } from './../assets/icons/workwithus/hospital.svg'
import {ReactComponent as SchoolIcon } from './../assets/icons/workwithus/teacher.svg'

const _data = {
downloadIcon: '',
downloadFilePath: `${process.env.PUBLIC_URL}/DiligentCompanyOverview.pdf`,
downloadFileName: 'Diligent Company Overview.pdf',
problems: [
{
id:1,
title:'Lack of dedication and long-term commitment',
paragraph:'More often than not, our clients come to realize that the only familiar face they see from the company to which they outsource is the account manager. Technical staff fluctuates, hampering team cohesion, and preventing meaningful progress and team growth - there’s little valuable knowledge accumulation in the team.'
},
{
id:2,
title:'Resources are unable to scale with what the company needs',
paragraph:'Dynamic of the business environment demands from our clients the ability to perform a fast-paced scale up and down of their tech teams. The delays introduced due to lack of available resources, or lack of appropriate resources, prolong the development process or stop it altogether. Inability to quickly scale down impacts the budget, flexibility in responding to unforeseen market conditions, and fast repurposing of resources. ',
},
{
id:3,
title:'Lack of quality tech-staff that wouldn’t break a bank',
paragraph:'Our clients are unable to onboard enough high-quality tech resources to cover all their needs . The two main reasons for this are lack of available high-quality resources and the cost of those resources.',
}
],
help: [
{
id:1,
title:'We outsource for a company, not a project',
paragraph:'All of our resources are dedicated to a single client. We provide the conditions, and expect them to put all their focus into understanding the whole of the client’s business - from high level to the details. This approach allows for knowledge accumulation and increase in value of their contribution with time.'
},
{
id:2,
title:'Long term, dedicated engineers',
paragraph:'Related to the previous point, our relationships with the clients tend to be very long-term. We have, where the relationship was long enough, the same resources onboarded with the same client for more than a decade. Our resources are more a part of the client’s company then they are of Diligent - Diligent is just the venue allowing them to do their job. ',
},
{
id:3,
title:'Jump right in - we know our domains',
paragraph:'Diligent’s resources, in business domains where we have accumulated experience, are capable of quickly producing high-value contributions to our clients. We know the concepts, we are familiar with the processes, we’ve faced the problems and solved them. If faced with something new - we’ll learn and do it quickly.'
},
{
id:4,
title:'Competitive prices',
paragraph:'Diligent provides a low entry price for our new clients until proven as a valuable partner. Even afterwards, once we’ve shown what we can do and contribute meaningfully to our client’s business, we tend to operate with lower fees than our competitors. Simply ask us for a bid or a pricing table and we’ll show you.'
}
]

};

const Segment = ({children}) => {
return (
<div className='py-[48px] mx-auto w-full text-center'>
{children}
</div>
);
}

const TechCard = ({children}) => {
return (
<div className='rounded-[8px] bg-white py-[24px] px-[32px] items-center justify-center text-center'>
{children}
</div>
)
}
const HelpParagraph = ({title, paragraph}) => {
return (
<div>
<h4 className='font-semibold text-title'>{title}</h4>
<p>{paragraph}</p>
</div>
)
}

const WorkWithUs = () => {
//useAnalytics();

useEffect(() => {
document.title = 'Work With Us';
},[]);

return (
<div className='mt-90p'>
<Wrapper padding={' py-[48px]'}>
<PageTitle heading={'Diligent at a Glance'} subheading={'work with us'} />
</Wrapper>
<div className='flex flex-col md:flex gap-[32px] w-fit mx-auto'>
<CustomLink href={_data.downloadFilePath} downloadFile={_data.downloadFileName} context={'Company Overview'}>
<p>Company Overview</p>
<DownalodIcon/>
</CustomLink>
</div>
<Segment>
<p>Our clients primarily come from one of the following 4 business domains:</p>
</Segment>
<Wrapper bg padding={' py-[48px]'}>
<div className='flex grid grid-cols-2 lg:grid-cols-4 gap-32p items-center justify-center mx-auto'>
<TechCard>
<FintechIcon className='mx-auto'/>
<p>Fintech</p>
</TechCard>
<TechCard>
<HospitalIcon className='mx-auto'/>
<p>Healthcare</p>
</TechCard>
<TechCard>
<BusIcon className='mx-auto'/>
<p>Transportation</p>
</TechCard>
<TechCard>
<SchoolIcon className='mx-auto'/>
<p>Education</p>
</TechCard>
</div>
</Wrapper>
<Wrapper padding={' py-[48px]'}>
<p className='pb-32p max-w-[1000px] mx-auto'>Within those domains, our customers range from startups (11.2 Ventures), over small and medium sized companies (Gold Bullion International, Intellum…), to Fortune 500 companies (Henry Schein…).</p>
<p className='max-w-[1000px] mx-auto'>Decision to outsource the whole, or a part, of software development accompanied with a demand for personal, long-term, dedication and responsibility is common for our clients. Most of them have already had some experience with other outsourcing companies, or are in active relationships with other outsourcing companies, when they decide to give us a try.</p>
</Wrapper>
<Wrapper padding={' py-[48px]'}>
<h4 className='font-semibold font-secondary text-[#9B32CE] text-subtitle-48 text-center w-full'>What Are Their Problems?</h4>
</Wrapper>
<Wrapper >
<section>
<div className="flex flex-col justify-center items-start w-full max-w-custom m-auto px-8 xl:px-0 mb-[90px]">
<div className="flex flex-col gap-32p w-full max-w-[950px] mx-auto">
{_data.problems.map((item, index) => (
<CardLife
key={index}
number={item.id}
heading={item.title}
paragraph={item.paragraph}
/>
))}
</div>
</div>
</section>
</Wrapper>
<Wrapper padding={' py-[48px] mb-32p'}>
<h4 className='font-semibold font-secondary text-[#9B32CE] text-subtitle-48 text-center w-full'>How We Help Them?</h4>
</Wrapper>
<Wrapper padding={' py-90p'}>
<section>
<div className="flex flex-col justify-center items-start w-full max-w-custom m-auto px-8 xl:px-0 mb-32p">
<div className="flex flex-col gap-[72px] w-full max-w-[950px] mx-auto">
{_data.help.map((item, index) => (
<HelpParagraph
key={index}
title={item.title}
paragraph={item.paragraph}
/>
))}
</div>
</div>
</section>
</Wrapper>
<Wrapper padding={' py-90p'} bg>
<h4 className='font-semibold font-secondary text-[#9B32CE] text-subtitle-48 text-center w-full py-32p'>What Our Customers Say?</h4>
<Testimonials noTitle />
</Wrapper>
<Wrapper padding={' py-[48px] mb-32p'}>
<h4 className='font-semibold font-secondary text-[#9B32CE] text-subtitle-48 text-center w-full py-32p'>Success</h4>
<p className='max-w-[1000px] mx-auto text-center w-full'>For us, the definition of success is a multifaceted subject. In short, we don’t declare a victory unless:</p>
<ul className='mx-[72px] lg:mx-[250px]'>
<li className='my-32p list-disc'>Deliverables are <b className='text-[#9B32CE]'>on time and within budget</b></li>
<li className='my-32p list-disc'>Deliverables are <b className='text-[#9B32CE]'>what the client needs</b>. We produce meaningful and positive contributions, we do not want to tick the checkboxes just so that we can call it done.</li>
<li className='my-32p list-disc'>Our resources involved with the client <b className='text-[#9B32CE]'>have gained knowledge in the process</b>, they understand the client’s business, what they’ve created and most importantly - why it was created</li>
<li className='my-32p list-disc'>Our clients can <b className='text-[#9B32CE]'>demonstratively measure the improvements</b> in stability, volume, earnings, their client/user satisfaction…as a result of our contribimport useAnalytics from './../hooks/useAnalytics';
utions. </li>

</ul>
</Wrapper>
<Wrapper padding={' py-32p'}>
<div className='flex flex-col md:flex gap-[32px] w-fit mx-auto'>
<CustomLink href={_data.downloadFilePath} downloadFile context={'Company Overview'}>
<p>Company Overview</p>
<DownalodIcon/>
</CustomLink>
</div>
</Wrapper>
<Wrapper padding={' py-90p'}>
<ActionCard
title="Let's Work Together!"
text="We’d be happy to try and find a way to contribute to your business."
btn2="Portfolio"
btn1="Contact Us"
link2={'/portfolio'}
link1={'/contact'}
/>
</Wrapper>
</div>
)

}

export default WorkWithUs

+ 109
- 0
frontend/src/routes.js Просмотреть файл

@@ -0,0 +1,109 @@
import CaseStudy from "./components/CaseStudy";
import About from "./pages/About";
import Careers from "./pages/Careers";
import CaseStudyBI from "./pages/CaseStudyBI";
import CaseStudyCentralized from "./pages/CaseStudyCentralized";
import CaseStudyFinantial from "./pages/CaseStudyFinantial";
import CaseStudyResource from "./pages/CaseStudyResource";
import CaseStudyStrata from "./pages/CaseStudyStrata";
import CaseStudyTicketing from "./pages/CaseStudyTicketing";
import ContactPage from "./pages/ContactPage";
import Home from "./pages/Home";
import Portfolio from "./pages/Portfolio";
import PrivacyPolicy from "./pages/PrivacyPolicy";
import ProcessPage from "./pages/ProcessPage";
import WorkWithUs from "./pages/WorkWithUs";

const routes = [
{
path: '/',
component: <Home/>,
title: 'Diligent Software',
exact: true,
},
{
path: '/workwithus',
component: <WorkWithUs/>,
title: 'Work with Us',
exact: true,
nav:true
},
{
path: '/portfolio',
component: <Portfolio/>,
title: 'Case Studies',
exact: true,
nav:true
},
{
path: '/process',
component: <ProcessPage />,
title: 'Process',
exact: true,
nav:true,
},
{
path: '/casestudybi',
component: <CaseStudyBI/>,
title: 'BI Healthcare System',
exact: true
},
{
path: '/casestudystrata',
component: <CaseStudyStrata/>,
title: 'Health Tracking Software',
exact: true
},
{
path: '/casestudyfinancial',
component: <CaseStudyFinantial/>,
title: 'Financial Engine',
exact: true
},
{
path: '/casestudyticketing',
component: <CaseStudyTicketing/>,
title: 'Ticketing System for Passengers',
exact: true
},
{
path: '/casestudycentralized',
component: <CaseStudyCentralized/>,
title: 'Centralized Monitoring System',
exact: true
},
{
path: '/casestudyresource',
component: <CaseStudyResource/>,
title: 'Resource Planning System',
exact: true
},
{
path: '/careers',
component: <Careers/>,
title: 'Careers',
exact: true,
nav:true,
},
{
path: '/about',
component: <About/>,
title: 'About Us',
exact: true,
nav:true,
},
{
path: '/contact',
component: <ContactPage/>,
title: 'Contact Us',
exact: true,
},
{
path: '/privacypolicy',
component: <PrivacyPolicy/>,
title: 'Privacy Policy',
exact: true
},
];

export default routes;

+ 18
- 19
frontend/src/styles/text.css Просмотреть файл

@@ -8,7 +8,7 @@
}

.subheading {
@apply tracking-widest text-subhead font-secondary uppercase text-dg-secondary font-semibold
@apply tracking-widest text-subhead font-secondary uppercase text-dg-secondary font-semibold;
}

.h3-heading {
@@ -19,18 +19,18 @@
@apply border-dg-primary-1000 capitalize text-dg-primary-1000 hover:border-dg-primary-1200 hover:text-white transition-all hover:transition-all;
}
.paragraph {
@apply text-p-mobile md:text-p text-dark-gray dark:text-white
@apply text-p-mobile md:text-p text-dark-gray dark:text-white;
}

.display-number {
@apply text-display-numb font-secondary font-bold text-dg-primary-1000
@apply text-display-numb font-secondary font-bold text-dg-primary-1000;
}
.number-title {
@apply text-title-24 font-secondary font-normal text-dark-gray
@apply text-title-24 font-secondary font-normal text-dark-gray;
}

.title-card {
@apply text-title font-semibold
@apply text-title font-semibold;
}

.subtitle-card-italic {
@@ -41,22 +41,21 @@
}

.title-italic {
@apply text-italic-title text-dg-primary-400 font-semibold italic my-8p capitalize
@apply text-italic-title text-dg-primary-400 font-semibold italic my-8p capitalize;
}

}

.no-wrap {
flex-wrap: nowrap;
}
.no-wrap {
flex-wrap: nowrap;
}

.title-colored {
background: linear-gradient(270deg, #90278F 0%, #8468BF 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.title-colored {
background: linear-gradient(270deg, #90278f 0%, #8468bf 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}

.italic {
font-style: italic;
}
.italic {
font-style: italic;
}

+ 6
- 1
frontend/tailwind.config.js Просмотреть файл

@@ -9,7 +9,7 @@ module.exports = {
fontSize: {
'head' : ['56px', {
letterSpacing: '1px',
lineHeight: '55px',
lineHeight: '74px',
}],
'subhead' : ['12px', {
letterSpacing: '28px',
@@ -70,7 +70,12 @@ module.exports = {
'display-numb' : ['56px', {
letterSpacing: '2px',
lineHeight: 'normal'
}],
'subtitle-48' : ['48px', {
letterSpacing: '0px',
lineHeight: 'normal'
}]

},
minHeight: {
'12': '3rem',

+ 12
- 0
node_modules/.bin/loose-envify Просмотреть файл

@@ -0,0 +1,12 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")

case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac

if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../loose-envify/cli.js" "$@"
else
exec node "$basedir/../loose-envify/cli.js" "$@"
fi

+ 17
- 0
node_modules/.bin/loose-envify.cmd Просмотреть файл

@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0

IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)

endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\loose-envify\cli.js" %*

+ 28
- 0
node_modules/.bin/loose-envify.ps1 Просмотреть файл

@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent

$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../loose-envify/cli.js" $args
} else {
& "$basedir/node$exe" "$basedir/../loose-envify/cli.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../loose-envify/cli.js" $args
} else {
& "node$exe" "$basedir/../loose-envify/cli.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret

+ 72
- 0
node_modules/.package-lock.json Просмотреть файл

@@ -0,0 +1,72 @@
{
"name": "website-new",
"lockfileVersion": 2,
"requires": true,
"packages": {
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"peer": true
},
"node_modules/loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
"peer": true,
"dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0"
},
"bin": {
"loose-envify": "cli.js"
}
},
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/prop-types": {
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
"peer": true,
"dependencies": {
"loose-envify": "^1.4.0",
"object-assign": "^4.1.1",
"react-is": "^16.13.1"
}
},
"node_modules/react": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
"integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/react-ga": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/react-ga/-/react-ga-3.3.1.tgz",
"integrity": "sha512-4Vc0W5EvXAXUN/wWyxvsAKDLLgtJ3oLmhYYssx+YzphJpejtOst6cbIHCIyF50Fdxuf5DDKqRYny24yJ2y7GFQ==",
"peerDependencies": {
"prop-types": "^15.6.0",
"react": "^15.6.2 || ^16.0 || ^17 || ^18"
}
},
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
"peer": true
}
}
}

+ 151
- 0
node_modules/js-tokens/CHANGELOG.md Просмотреть файл

@@ -0,0 +1,151 @@
### Version 4.0.0 (2018-01-28) ###

- Added: Support for ES2018. The only change needed was recognizing the `s`
regex flag.
- Changed: _All_ tokens returned by the `matchToToken` function now have a
`closed` property. It is set to `undefined` for the tokens where “closed”
doesn’t make sense. This means that all tokens objects have the same shape,
which might improve performance.

These are the breaking changes:

- `'/a/s'.match(jsTokens)` no longer returns `['/', 'a', '/', 's']`, but
`['/a/s']`. (There are of course other variations of this.)
- Code that rely on some token objects not having the `closed` property could
now behave differently.


### Version 3.0.2 (2017-06-28) ###

- No code changes. Just updates to the readme.


### Version 3.0.1 (2017-01-30) ###

- Fixed: ES2015 unicode escapes with more than 6 hex digits are now matched
correctly.


### Version 3.0.0 (2017-01-11) ###

This release contains one breaking change, that should [improve performance in
V8][v8-perf]:

> So how can you, as a JavaScript developer, ensure that your RegExps are fast?
> If you are not interested in hooking into RegExp internals, make sure that
> neither the RegExp instance, nor its prototype is modified in order to get the
> best performance:
>
> ```js
> var re = /./g;
> re.exec(''); // Fast path.
> re.new_property = 'slow';
> ```

This module used to export a single regex, with `.matchToToken` bolted
on, just like in the above example. This release changes the exports of
the module to avoid this issue.

Before:

```js
import jsTokens from "js-tokens"
// or:
var jsTokens = require("js-tokens")
var matchToToken = jsTokens.matchToToken
```

After:

```js
import jsTokens, {matchToToken} from "js-tokens"
// or:
var jsTokens = require("js-tokens").default
var matchToToken = require("js-tokens").matchToToken
```

[v8-perf]: http://v8project.blogspot.se/2017/01/speeding-up-v8-regular-expressions.html


### Version 2.0.0 (2016-06-19) ###

- Added: Support for ES2016. In other words, support for the `**` exponentiation
operator.

These are the breaking changes:

- `'**'.match(jsTokens)` no longer returns `['*', '*']`, but `['**']`.
- `'**='.match(jsTokens)` no longer returns `['*', '*=']`, but `['**=']`.


### Version 1.0.3 (2016-03-27) ###

- Improved: Made the regex ever so slightly smaller.
- Updated: The readme.


### Version 1.0.2 (2015-10-18) ###

- Improved: Limited npm package contents for a smaller download. Thanks to
@zertosh!


### Version 1.0.1 (2015-06-20) ###

- Fixed: Declared an undeclared variable.


### Version 1.0.0 (2015-02-26) ###

- Changed: Merged the 'operator' and 'punctuation' types into 'punctuator'. That
type is now equivalent to the Punctuator token in the ECMAScript
specification. (Backwards-incompatible change.)
- Fixed: A `-` followed by a number is now correctly matched as a punctuator
followed by a number. It used to be matched as just a number, but there is no
such thing as negative number literals. (Possibly backwards-incompatible
change.)


### Version 0.4.1 (2015-02-21) ###

- Added: Support for the regex `u` flag.


### Version 0.4.0 (2015-02-21) ###

- Improved: `jsTokens.matchToToken` performance.
- Added: Support for octal and binary number literals.
- Added: Support for template strings.


### Version 0.3.1 (2015-01-06) ###

- Fixed: Support for unicode spaces. They used to be allowed in names (which is
very confusing), and some unicode newlines were wrongly allowed in strings and
regexes.


### Version 0.3.0 (2014-12-19) ###

- Changed: The `jsTokens.names` array has been replaced with the
`jsTokens.matchToToken` function. The capturing groups of `jsTokens` are no
longer part of the public API; instead use said function. See this [gist] for
an example. (Backwards-incompatible change.)
- Changed: The empty string is now considered an “invalid” token, instead an
“empty” token (its own group). (Backwards-incompatible change.)
- Removed: component support. (Backwards-incompatible change.)

[gist]: https://gist.github.com/lydell/be49dbf80c382c473004


### Version 0.2.0 (2014-06-19) ###

- Changed: Match ES6 function arrows (`=>`) as an operator, instead of its own
category (“functionArrow”), for simplicity. (Backwards-incompatible change.)
- Added: ES6 splats (`...`) are now matched as an operator (instead of three
punctuations). (Backwards-incompatible change.)


### Version 0.1.0 (2014-03-08) ###

- Initial release.

+ 21
- 0
node_modules/js-tokens/LICENSE Просмотреть файл

@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2014, 2015, 2016, 2017, 2018 Simon Lydell

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

+ 240
- 0
node_modules/js-tokens/README.md Просмотреть файл

@@ -0,0 +1,240 @@
Overview [![Build Status](https://travis-ci.org/lydell/js-tokens.svg?branch=master)](https://travis-ci.org/lydell/js-tokens)
========

A regex that tokenizes JavaScript.

```js
var jsTokens = require("js-tokens").default

var jsString = "var foo=opts.foo;\n..."

jsString.match(jsTokens)
// ["var", " ", "foo", "=", "opts", ".", "foo", ";", "\n", ...]
```


Installation
============

`npm install js-tokens`

```js
import jsTokens from "js-tokens"
// or:
var jsTokens = require("js-tokens").default
```


Usage
=====

### `jsTokens` ###

A regex with the `g` flag that matches JavaScript tokens.

The regex _always_ matches, even invalid JavaScript and the empty string.

The next match is always directly after the previous.

### `var token = matchToToken(match)` ###

```js
import {matchToToken} from "js-tokens"
// or:
var matchToToken = require("js-tokens").matchToToken
```

Takes a `match` returned by `jsTokens.exec(string)`, and returns a `{type:
String, value: String}` object. The following types are available:

- string
- comment
- regex
- number
- name
- punctuator
- whitespace
- invalid

Multi-line comments and strings also have a `closed` property indicating if the
token was closed or not (see below).

Comments and strings both come in several flavors. To distinguish them, check if
the token starts with `//`, `/*`, `'`, `"` or `` ` ``.

Names are ECMAScript IdentifierNames, that is, including both identifiers and
keywords. You may use [is-keyword-js] to tell them apart.

Whitespace includes both line terminators and other whitespace.

[is-keyword-js]: https://github.com/crissdev/is-keyword-js


ECMAScript support
==================

The intention is to always support the latest ECMAScript version whose feature
set has been finalized.

If adding support for a newer version requires changes, a new version with a
major verion bump will be released.

Currently, ECMAScript 2018 is supported.


Invalid code handling
=====================

Unterminated strings are still matched as strings. JavaScript strings cannot
contain (unescaped) newlines, so unterminated strings simply end at the end of
the line. Unterminated template strings can contain unescaped newlines, though,
so they go on to the end of input.

Unterminated multi-line comments are also still matched as comments. They
simply go on to the end of the input.

Unterminated regex literals are likely matched as division and whatever is
inside the regex.

Invalid ASCII characters have their own capturing group.

Invalid non-ASCII characters are treated as names, to simplify the matching of
names (except unicode spaces which are treated as whitespace). Note: See also
the [ES2018](#es2018) section.

Regex literals may contain invalid regex syntax. They are still matched as
regex literals. They may also contain repeated regex flags, to keep the regex
simple.

Strings may contain invalid escape sequences.


Limitations
===========

Tokenizing JavaScript using regexes—in fact, _one single regex_—won’t be
perfect. But that’s not the point either.

You may compare jsTokens with [esprima] by using `esprima-compare.js`.
See `npm run esprima-compare`!

[esprima]: http://esprima.org/

### Template string interpolation ###

Template strings are matched as single tokens, from the starting `` ` `` to the
ending `` ` ``, including interpolations (whose tokens are not matched
individually).

Matching template string interpolations requires recursive balancing of `{` and
`}`—something that JavaScript regexes cannot do. Only one level of nesting is
supported.

### Division and regex literals collision ###

Consider this example:

```js
var g = 9.82
var number = bar / 2/g

var regex = / 2/g
```

A human can easily understand that in the `number` line we’re dealing with
division, and in the `regex` line we’re dealing with a regex literal. How come?
Because humans can look at the whole code to put the `/` characters in context.
A JavaScript regex cannot. It only sees forwards. (Well, ES2018 regexes can also
look backwards. See the [ES2018](#es2018) section).

When the `jsTokens` regex scans throught the above, it will see the following
at the end of both the `number` and `regex` rows:

```js
/ 2/g
```

It is then impossible to know if that is a regex literal, or part of an
expression dealing with division.

Here is a similar case:

```js
foo /= 2/g
foo(/= 2/g)
```

The first line divides the `foo` variable with `2/g`. The second line calls the
`foo` function with the regex literal `/= 2/g`. Again, since `jsTokens` only
sees forwards, it cannot tell the two cases apart.

There are some cases where we _can_ tell division and regex literals apart,
though.

First off, we have the simple cases where there’s only one slash in the line:

```js
var foo = 2/g
foo /= 2
```

Regex literals cannot contain newlines, so the above cases are correctly
identified as division. Things are only problematic when there are more than
one non-comment slash in a single line.

Secondly, not every character is a valid regex flag.

```js
var number = bar / 2/e
```

The above example is also correctly identified as division, because `e` is not a
valid regex flag. I initially wanted to future-proof by allowing `[a-zA-Z]*`
(any letter) as flags, but it is not worth it since it increases the amount of
ambigous cases. So only the standard `g`, `m`, `i`, `y` and `u` flags are
allowed. This means that the above example will be identified as division as
long as you don’t rename the `e` variable to some permutation of `gmiyus` 1 to 6
characters long.

Lastly, we can look _forward_ for information.

- If the token following what looks like a regex literal is not valid after a
regex literal, but is valid in a division expression, then the regex literal
is treated as division instead. For example, a flagless regex cannot be
followed by a string, number or name, but all of those three can be the
denominator of a division.
- Generally, if what looks like a regex literal is followed by an operator, the
regex literal is treated as division instead. This is because regexes are
seldomly used with operators (such as `+`, `*`, `&&` and `==`), but division
could likely be part of such an expression.

Please consult the regex source and the test cases for precise information on
when regex or division is matched (should you need to know). In short, you
could sum it up as:

If the end of a statement looks like a regex literal (even if it isn’t), it
will be treated as one. Otherwise it should work as expected (if you write sane
code).

### ES2018 ###

ES2018 added some nice regex improvements to the language.

- [Unicode property escapes] should allow telling names and invalid non-ASCII
characters apart without blowing up the regex size.
- [Lookbehind assertions] should allow matching telling division and regex
literals apart in more cases.
- [Named capture groups] might simplify some things.

These things would be nice to do, but are not critical. They probably have to
wait until the oldest maintained Node.js LTS release supports those features.

[Unicode property escapes]: http://2ality.com/2017/07/regexp-unicode-property-escapes.html
[Lookbehind assertions]: http://2ality.com/2017/05/regexp-lookbehind-assertions.html
[Named capture groups]: http://2ality.com/2017/05/regexp-named-capture-groups.html


License
=======

[MIT](LICENSE).

+ 23
- 0
node_modules/js-tokens/index.js Просмотреть файл

@@ -0,0 +1,23 @@
// Copyright 2014, 2015, 2016, 2017, 2018 Simon Lydell
// License: MIT. (See LICENSE.)

Object.defineProperty(exports, "__esModule", {
value: true
})

// This regex comes from regex.coffee, and is inserted here by generate-index.js
// (run `npm run build`).
exports.default = /((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyus]{1,6}\b(?![\u0080-\uFFFF$\\]|\s*(?:[+\-*%&|^<>!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g

exports.matchToToken = function(match) {
var token = {type: "invalid", value: match[0], closed: undefined}
if (match[ 1]) token.type = "string" , token.closed = !!(match[3] || match[4])
else if (match[ 5]) token.type = "comment"
else if (match[ 6]) token.type = "comment", token.closed = !!match[7]
else if (match[ 8]) token.type = "regex"
else if (match[ 9]) token.type = "number"
else if (match[10]) token.type = "name"
else if (match[11]) token.type = "punctuator"
else if (match[12]) token.type = "whitespace"
return token
}

+ 30
- 0
node_modules/js-tokens/package.json Просмотреть файл

@@ -0,0 +1,30 @@
{
"name": "js-tokens",
"version": "4.0.0",
"author": "Simon Lydell",
"license": "MIT",
"description": "A regex that tokenizes JavaScript.",
"keywords": [
"JavaScript",
"js",
"token",
"tokenize",
"regex"
],
"files": [
"index.js"
],
"repository": "lydell/js-tokens",
"scripts": {
"test": "mocha --ui tdd",
"esprima-compare": "node esprima-compare ./index.js everything.js/es5.js",
"build": "node generate-index.js",
"dev": "npm run build && npm test"
},
"devDependencies": {
"coffeescript": "2.1.1",
"esprima": "4.0.0",
"everything.js": "1.0.3",
"mocha": "5.0.0"
}
}

+ 21
- 0
node_modules/loose-envify/LICENSE Просмотреть файл

@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2015 Andres Suarez <zertosh@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

+ 45
- 0
node_modules/loose-envify/README.md Просмотреть файл

@@ -0,0 +1,45 @@
# loose-envify

[![Build Status](https://travis-ci.org/zertosh/loose-envify.svg?branch=master)](https://travis-ci.org/zertosh/loose-envify)

Fast (and loose) selective `process.env` replacer using [js-tokens](https://github.com/lydell/js-tokens) instead of an AST. Works just like [envify](https://github.com/hughsk/envify) but much faster.

## Gotchas

* Doesn't handle broken syntax.
* Doesn't look inside embedded expressions in template strings.
- **this won't work:**
```js
console.log(`the current env is ${process.env.NODE_ENV}`);
```
* Doesn't replace oddly-spaced or oddly-commented expressions.
- **this won't work:**
```js
console.log(process./*won't*/env./*work*/NODE_ENV);
```

## Usage/Options

loose-envify has the exact same interface as [envify](https://github.com/hughsk/envify), including the CLI.

## Benchmark

```
envify:

$ for i in {1..5}; do node bench/bench.js 'envify'; done
708ms
727ms
791ms
719ms
720ms

loose-envify:

$ for i in {1..5}; do node bench/bench.js '../'; done
51ms
52ms
52ms
52ms
52ms
```

+ 16
- 0
node_modules/loose-envify/cli.js Просмотреть файл

@@ -0,0 +1,16 @@
#!/usr/bin/env node
'use strict';

var looseEnvify = require('./');
var fs = require('fs');

if (process.argv[2]) {
fs.createReadStream(process.argv[2], {encoding: 'utf8'})
.pipe(looseEnvify(process.argv[2]))
.pipe(process.stdout);
} else {
process.stdin.resume()
process.stdin
.pipe(looseEnvify(__filename))
.pipe(process.stdout);
}

+ 4
- 0
node_modules/loose-envify/custom.js Просмотреть файл

@@ -0,0 +1,4 @@
// envify compatibility
'use strict';

module.exports = require('./loose-envify');

+ 3
- 0
node_modules/loose-envify/index.js Просмотреть файл

@@ -0,0 +1,3 @@
'use strict';

module.exports = require('./loose-envify')(process.env);

+ 36
- 0
node_modules/loose-envify/loose-envify.js Просмотреть файл

@@ -0,0 +1,36 @@
'use strict';

var stream = require('stream');
var util = require('util');
var replace = require('./replace');

var jsonExtRe = /\.json$/;

module.exports = function(rootEnv) {
rootEnv = rootEnv || process.env;
return function (file, trOpts) {
if (jsonExtRe.test(file)) {
return stream.PassThrough();
}
var envs = trOpts ? [rootEnv, trOpts] : [rootEnv];
return new LooseEnvify(envs);
};
};

function LooseEnvify(envs) {
stream.Transform.call(this);
this._data = '';
this._envs = envs;
}
util.inherits(LooseEnvify, stream.Transform);

LooseEnvify.prototype._transform = function(buf, enc, cb) {
this._data += buf;
cb();
};

LooseEnvify.prototype._flush = function(cb) {
var replaced = replace(this._data, this._envs);
this.push(replaced);
cb();
};

+ 36
- 0
node_modules/loose-envify/package.json Просмотреть файл

@@ -0,0 +1,36 @@
{
"name": "loose-envify",
"version": "1.4.0",
"description": "Fast (and loose) selective `process.env` replacer using js-tokens instead of an AST",
"keywords": [
"environment",
"variables",
"browserify",
"browserify-transform",
"transform",
"source",
"configuration"
],
"homepage": "https://github.com/zertosh/loose-envify",
"license": "MIT",
"author": "Andres Suarez <zertosh@gmail.com>",
"main": "index.js",
"bin": {
"loose-envify": "cli.js"
},
"repository": {
"type": "git",
"url": "git://github.com/zertosh/loose-envify.git"
},
"scripts": {
"test": "tap test/*.js"
},
"dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0"
},
"devDependencies": {
"browserify": "^13.1.1",
"envify": "^3.4.0",
"tap": "^8.0.0"
}
}

+ 65
- 0
node_modules/loose-envify/replace.js Просмотреть файл

@@ -0,0 +1,65 @@
'use strict';

var jsTokens = require('js-tokens').default;

var processEnvRe = /\bprocess\.env\.[_$a-zA-Z][$\w]+\b/;
var spaceOrCommentRe = /^(?:\s|\/[/*])/;

function replace(src, envs) {
if (!processEnvRe.test(src)) {
return src;
}

var out = [];
var purge = envs.some(function(env) {
return env._ && env._.indexOf('purge') !== -1;
});

jsTokens.lastIndex = 0
var parts = src.match(jsTokens);

for (var i = 0; i < parts.length; i++) {
if (parts[i ] === 'process' &&
parts[i + 1] === '.' &&
parts[i + 2] === 'env' &&
parts[i + 3] === '.') {
var prevCodeToken = getAdjacentCodeToken(-1, parts, i);
var nextCodeToken = getAdjacentCodeToken(1, parts, i + 4);
var replacement = getReplacementString(envs, parts[i + 4], purge);
if (prevCodeToken !== '.' &&
nextCodeToken !== '.' &&
nextCodeToken !== '=' &&
typeof replacement === 'string') {
out.push(replacement);
i += 4;
continue;
}
}
out.push(parts[i]);
}

return out.join('');
}

function getAdjacentCodeToken(dir, parts, i) {
while (true) {
var part = parts[i += dir];
if (!spaceOrCommentRe.test(part)) {
return part;
}
}
}

function getReplacementString(envs, name, purge) {
for (var j = 0; j < envs.length; j++) {
var env = envs[j];
if (typeof env[name] !== 'undefined') {
return JSON.stringify(env[name]);
}
}
if (purge) {
return 'undefined';
}
}

module.exports = replace;

+ 90
- 0
node_modules/object-assign/index.js Просмотреть файл

@@ -0,0 +1,90 @@
/*
object-assign
(c) Sindre Sorhus
@license MIT
*/

'use strict';
/* eslint-disable no-unused-vars */
var getOwnPropertySymbols = Object.getOwnPropertySymbols;
var hasOwnProperty = Object.prototype.hasOwnProperty;
var propIsEnumerable = Object.prototype.propertyIsEnumerable;

function toObject(val) {
if (val === null || val === undefined) {
throw new TypeError('Object.assign cannot be called with null or undefined');
}

return Object(val);
}

function shouldUseNative() {
try {
if (!Object.assign) {
return false;
}

// Detect buggy property enumeration order in older V8 versions.

// https://bugs.chromium.org/p/v8/issues/detail?id=4118
var test1 = new String('abc'); // eslint-disable-line no-new-wrappers
test1[5] = 'de';
if (Object.getOwnPropertyNames(test1)[0] === '5') {
return false;
}

// https://bugs.chromium.org/p/v8/issues/detail?id=3056
var test2 = {};
for (var i = 0; i < 10; i++) {
test2['_' + String.fromCharCode(i)] = i;
}
var order2 = Object.getOwnPropertyNames(test2).map(function (n) {
return test2[n];
});
if (order2.join('') !== '0123456789') {
return false;
}

// https://bugs.chromium.org/p/v8/issues/detail?id=3056
var test3 = {};
'abcdefghijklmnopqrst'.split('').forEach(function (letter) {
test3[letter] = letter;
});
if (Object.keys(Object.assign({}, test3)).join('') !==
'abcdefghijklmnopqrst') {
return false;
}

return true;
} catch (err) {
// We don't expect any of the above to throw, but better to be safe.
return false;
}
}

module.exports = shouldUseNative() ? Object.assign : function (target, source) {
var from;
var to = toObject(target);
var symbols;

for (var s = 1; s < arguments.length; s++) {
from = Object(arguments[s]);

for (var key in from) {
if (hasOwnProperty.call(from, key)) {
to[key] = from[key];
}
}

if (getOwnPropertySymbols) {
symbols = getOwnPropertySymbols(from);
for (var i = 0; i < symbols.length; i++) {
if (propIsEnumerable.call(from, symbols[i])) {
to[symbols[i]] = from[symbols[i]];
}
}
}
}

return to;
};

+ 21
- 0
node_modules/object-assign/license Просмотреть файл

@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

+ 42
- 0
node_modules/object-assign/package.json Просмотреть файл

@@ -0,0 +1,42 @@
{
"name": "object-assign",
"version": "4.1.1",
"description": "ES2015 `Object.assign()` ponyfill",
"license": "MIT",
"repository": "sindresorhus/object-assign",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"test": "xo && ava",
"bench": "matcha bench.js"
},
"files": [
"index.js"
],
"keywords": [
"object",
"assign",
"extend",
"properties",
"es2015",
"ecmascript",
"harmony",
"ponyfill",
"prollyfill",
"polyfill",
"shim",
"browser"
],
"devDependencies": {
"ava": "^0.16.0",
"lodash": "^4.16.4",
"matcha": "^0.7.0",
"xo": "^0.16.0"
}
}

+ 61
- 0
node_modules/object-assign/readme.md Просмотреть файл

@@ -0,0 +1,61 @@
# object-assign [![Build Status](https://travis-ci.org/sindresorhus/object-assign.svg?branch=master)](https://travis-ci.org/sindresorhus/object-assign)

> ES2015 [`Object.assign()`](http://www.2ality.com/2014/01/object-assign.html) [ponyfill](https://ponyfill.com)


## Use the built-in

Node.js 4 and up, as well as every evergreen browser (Chrome, Edge, Firefox, Opera, Safari),
support `Object.assign()` :tada:. If you target only those environments, then by all
means, use `Object.assign()` instead of this package.


## Install

```
$ npm install --save object-assign
```


## Usage

```js
const objectAssign = require('object-assign');

objectAssign({foo: 0}, {bar: 1});
//=> {foo: 0, bar: 1}

// multiple sources
objectAssign({foo: 0}, {bar: 1}, {baz: 2});
//=> {foo: 0, bar: 1, baz: 2}

// overwrites equal keys
objectAssign({foo: 0}, {foo: 1}, {foo: 2});
//=> {foo: 2}

// ignores null and undefined sources
objectAssign({foo: 0}, null, {bar: 1}, undefined);
//=> {foo: 0, bar: 1}
```


## API

### objectAssign(target, [source, ...])

Assigns enumerable own properties of `source` objects to the `target` object and returns the `target` object. Additional `source` objects will overwrite previous ones.


## Resources

- [ES2015 spec - Object.assign](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign)


## Related

- [deep-assign](https://github.com/sindresorhus/deep-assign) - Recursive `Object.assign()`


## License

MIT © [Sindre Sorhus](https://sindresorhus.com)

+ 21
- 0
node_modules/prop-types/LICENSE Просмотреть файл

@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2013-present, Facebook, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

+ 302
- 0
node_modules/prop-types/README.md Просмотреть файл

@@ -0,0 +1,302 @@
# prop-types [![Build Status](https://travis-ci.com/facebook/prop-types.svg?branch=main)](https://travis-ci.org/facebook/prop-types)

Runtime type checking for React props and similar objects.

You can use prop-types to document the intended types of properties passed to
components. React (and potentially other libraries—see the `checkPropTypes()`
reference below) will check props passed to your components against those
definitions, and warn in development if they don’t match.

## Installation

```shell
npm install --save prop-types
```

## Importing

```js
import PropTypes from 'prop-types'; // ES6
var PropTypes = require('prop-types'); // ES5 with npm
```

### CDN

If you prefer to exclude `prop-types` from your application and use it
globally via `window.PropTypes`, the `prop-types` package provides
single-file distributions, which are hosted on the following CDNs:

* [**unpkg**](https://unpkg.com/prop-types/)
```html
<!-- development version -->
<script src="https://unpkg.com/prop-types@15.6/prop-types.js"></script>

<!-- production version -->
<script src="https://unpkg.com/prop-types@15.6/prop-types.min.js"></script>
```

* [**cdnjs**](https://cdnjs.com/libraries/prop-types)
```html
<!-- development version -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.6.0/prop-types.js"></script>

<!-- production version -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.6.0/prop-types.min.js"></script>
```

To load a specific version of `prop-types` replace `15.6.0` with the version number.

## Usage

PropTypes was originally exposed as part of the React core module, and is
commonly used with React components.
Here is an example of using PropTypes with a React component, which also
documents the different validators provided:

```js
import React from 'react';
import PropTypes from 'prop-types';

class MyComponent extends React.Component {
render() {
// ... do things with the props
}
}

MyComponent.propTypes = {
// You can declare that a prop is a specific JS primitive. By default, these
// are all optional.
optionalArray: PropTypes.array,
optionalBigInt: PropTypes.bigint,
optionalBool: PropTypes.bool,
optionalFunc: PropTypes.func,
optionalNumber: PropTypes.number,
optionalObject: PropTypes.object,
optionalString: PropTypes.string,
optionalSymbol: PropTypes.symbol,

// Anything that can be rendered: numbers, strings, elements or an array
// (or fragment) containing these types.
// see https://reactjs.org/docs/rendering-elements.html for more info
optionalNode: PropTypes.node,

// A React element (ie. <MyComponent />).
optionalElement: PropTypes.element,

// A React element type (eg. MyComponent).
// a function, string, or "element-like" object (eg. React.Fragment, Suspense, etc.)
// see https://github.com/facebook/react/blob/HEAD/packages/shared/isValidElementType.js
optionalElementType: PropTypes.elementType,

// You can also declare that a prop is an instance of a class. This uses
// JS's instanceof operator.
optionalMessage: PropTypes.instanceOf(Message),

// You can ensure that your prop is limited to specific values by treating
// it as an enum.
optionalEnum: PropTypes.oneOf(['News', 'Photos']),

// An object that could be one of many types
optionalUnion: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.instanceOf(Message)
]),

// An array of a certain type
optionalArrayOf: PropTypes.arrayOf(PropTypes.number),

// An object with property values of a certain type
optionalObjectOf: PropTypes.objectOf(PropTypes.number),

// You can chain any of the above with `isRequired` to make sure a warning
// is shown if the prop isn't provided.

// An object taking on a particular shape
optionalObjectWithShape: PropTypes.shape({
optionalProperty: PropTypes.string,
requiredProperty: PropTypes.number.isRequired
}),

// An object with warnings on extra properties
optionalObjectWithStrictShape: PropTypes.exact({
optionalProperty: PropTypes.string,
requiredProperty: PropTypes.number.isRequired
}),

requiredFunc: PropTypes.func.isRequired,

// A value of any data type
requiredAny: PropTypes.any.isRequired,

// You can also specify a custom validator. It should return an Error
// object if the validation fails. Don't `console.warn` or throw, as this
// won't work inside `oneOfType`.
customProp: function(props, propName, componentName) {
if (!/matchme/.test(props[propName])) {
return new Error(
'Invalid prop `' + propName + '` supplied to' +
' `' + componentName + '`. Validation failed.'
);
}
},

// You can also supply a custom validator to `arrayOf` and `objectOf`.
// It should return an Error object if the validation fails. The validator
// will be called for each key in the array or object. The first two
// arguments of the validator are the array or object itself, and the
// current item's key.
customArrayProp: PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) {
if (!/matchme/.test(propValue[key])) {
return new Error(
'Invalid prop `' + propFullName + '` supplied to' +
' `' + componentName + '`. Validation failed.'
);
}
})
};
```

Refer to the [React documentation](https://facebook.github.io/react/docs/typechecking-with-proptypes.html) for more information.

## Migrating from React.PropTypes

Check out [Migrating from React.PropTypes](https://facebook.github.io/react/blog/2017/04/07/react-v15.5.0.html#migrating-from-react.proptypes) for details on how to migrate to `prop-types` from `React.PropTypes`.

Note that this blog posts **mentions a codemod script that performs the conversion automatically**.

There are also important notes below.

## How to Depend on This Package?

For apps, we recommend putting it in `dependencies` with a caret range.
For example:

```js
"dependencies": {
"prop-types": "^15.5.7"
}
```

For libraries, we *also* recommend leaving it in `dependencies`:

```js
"dependencies": {
"prop-types": "^15.5.7"
},
"peerDependencies": {
"react": "^15.5.0"
}
```

**Note:** there are known issues in versions before 15.5.7 so we recommend using it as the minimal version.

Make sure that the version range uses a caret (`^`) and thus is broad enough for npm to efficiently deduplicate packages.

For UMD bundles of your components, make sure you **don’t** include `PropTypes` in the build. Usually this is done by marking it as an external (the specifics depend on your bundler), just like you do with React.

## Compatibility

### React 0.14

This package is compatible with **React 0.14.9**. Compared to 0.14.8 (which was released in March of 2016), there are no other changes in 0.14.9, so it should be a painless upgrade.

```shell
# ATTENTION: Only run this if you still use React 0.14!
npm install --save react@^0.14.9 react-dom@^0.14.9
```

### React 15+

This package is compatible with **React 15.3.0** and higher.

```
npm install --save react@^15.3.0 react-dom@^15.3.0
```

### What happens on other React versions?

It outputs warnings with the message below even though the developer doesn’t do anything wrong. Unfortunately there is no solution for this other than updating React to either 15.3.0 or higher, or 0.14.9 if you’re using React 0.14.

## Difference from `React.PropTypes`: Don’t Call Validator Functions

First of all, **which version of React are you using**? You might be seeing this message because a component library has updated to use `prop-types` package, but your version of React is incompatible with it. See the [above section](#compatibility) for more details.

Are you using either React 0.14.9 or a version higher than React 15.3.0? Read on.

When you migrate components to use the standalone `prop-types`, **all validator functions will start throwing an error if you call them directly**. This makes sure that nobody relies on them in production code, and it is safe to strip their implementations to optimize the bundle size.

Code like this is still fine:

```js
MyComponent.propTypes = {
myProp: PropTypes.bool
};
```

However, code like this will not work with the `prop-types` package:

```js
// Will not work with `prop-types` package!
var errorOrNull = PropTypes.bool(42, 'myProp', 'MyComponent', 'prop');
```

It will throw an error:

```
Calling PropTypes validators directly is not supported by the `prop-types` package.
Use PropTypes.checkPropTypes() to call them.
```

(If you see **a warning** rather than an error with this message, please check the [above section about compatibility](#compatibility).)

This is new behavior, and you will only encounter it when you migrate from `React.PropTypes` to the `prop-types` package. For the vast majority of components, this doesn’t matter, and if you didn’t see [this warning](https://facebook.github.io/react/warnings/dont-call-proptypes.html) in your components, your code is safe to migrate. This is not a breaking change in React because you are only opting into this change for a component by explicitly changing your imports to use `prop-types`. If you temporarily need the old behavior, you can keep using `React.PropTypes` until React 16.

**If you absolutely need to trigger the validation manually**, call `PropTypes.checkPropTypes()`. Unlike the validators themselves, this function is safe to call in production, as it will be replaced by an empty function:

```js
// Works with standalone PropTypes
PropTypes.checkPropTypes(MyComponent.propTypes, props, 'prop', 'MyComponent');
```
See below for more info.

**If you DO want to use validation in production**, you can choose to use the **development version** by importing/requiring `prop-types/prop-types` instead of `prop-types`.

**You might also see this error** if you’re calling a `PropTypes` validator from your own custom `PropTypes` validator. In this case, the fix is to make sure that you are passing *all* of the arguments to the inner function. There is a more in-depth explanation of how to fix it [on this page](https://facebook.github.io/react/warnings/dont-call-proptypes.html#fixing-the-false-positive-in-third-party-proptypes). Alternatively, you can temporarily keep using `React.PropTypes` until React 16, as it would still only warn in this case.

If you use a bundler like Browserify or Webpack, don’t forget to [follow these instructions](https://reactjs.org/docs/optimizing-performance.html#use-the-production-build) to correctly bundle your application in development or production mode. Otherwise you’ll ship unnecessary code to your users.

## PropTypes.checkPropTypes

React will automatically check the propTypes you set on the component, but if
you are using PropTypes without React then you may want to manually call
`PropTypes.checkPropTypes`, like so:

```js
const myPropTypes = {
name: PropTypes.string,
age: PropTypes.number,
// ... define your prop validations
};

const props = {
name: 'hello', // is valid
age: 'world', // not valid
};

// Let's say your component is called 'MyComponent'

// Works with standalone PropTypes
PropTypes.checkPropTypes(myPropTypes, props, 'prop', 'MyComponent');
// This will warn as follows:
// Warning: Failed prop type: Invalid prop `age` of type `string` supplied to
// `MyComponent`, expected `number`.
```

## PropTypes.resetWarningCache()

`PropTypes.checkPropTypes(...)` only `console.error`s a given message once. To reset the error warning cache in tests, call `PropTypes.resetWarningCache()`

### License

prop-types is [MIT licensed](./LICENSE).

+ 103
- 0
node_modules/prop-types/checkPropTypes.js Просмотреть файл

@@ -0,0 +1,103 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

var printWarning = function() {};

if (process.env.NODE_ENV !== 'production') {
var ReactPropTypesSecret = require('./lib/ReactPropTypesSecret');
var loggedTypeFailures = {};
var has = require('./lib/has');

printWarning = function(text) {
var message = 'Warning: ' + text;
if (typeof console !== 'undefined') {
console.error(message);
}
try {
// --- Welcome to debugging React ---
// This error was thrown as a convenience so that you can use this stack
// to find the callsite that caused this warning to fire.
throw new Error(message);
} catch (x) { /**/ }
};
}

/**
* Assert that the values match with the type specs.
* Error messages are memorized and will only be shown once.
*
* @param {object} typeSpecs Map of name to a ReactPropType
* @param {object} values Runtime values that need to be type-checked
* @param {string} location e.g. "prop", "context", "child context"
* @param {string} componentName Name of the component for error messages.
* @param {?Function} getStack Returns the component stack.
* @private
*/
function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
if (process.env.NODE_ENV !== 'production') {
for (var typeSpecName in typeSpecs) {
if (has(typeSpecs, typeSpecName)) {
var error;
// Prop type validation may throw. In case they do, we don't want to
// fail the render phase where it didn't fail before. So we log it.
// After these have been cleaned up, we'll let them throw.
try {
// This is intentionally an invariant that gets caught. It's the same
// behavior as without this statement except with a better message.
if (typeof typeSpecs[typeSpecName] !== 'function') {
var err = Error(
(componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' +
'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.' +
'This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.'
);
err.name = 'Invariant Violation';
throw err;
}
error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
} catch (ex) {
error = ex;
}
if (error && !(error instanceof Error)) {
printWarning(
(componentName || 'React class') + ': type specification of ' +
location + ' `' + typeSpecName + '` is invalid; the type checker ' +
'function must return `null` or an `Error` but returned a ' + typeof error + '. ' +
'You may have forgotten to pass an argument to the type checker ' +
'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +
'shape all require an argument).'
);
}
if (error instanceof Error && !(error.message in loggedTypeFailures)) {
// Only monitor this failure once because there tends to be a lot of the
// same error.
loggedTypeFailures[error.message] = true;

var stack = getStack ? getStack() : '';

printWarning(
'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '')
);
}
}
}
}
}

/**
* Resets warning cache when testing.
*
* @private
*/
checkPropTypes.resetWarningCache = function() {
if (process.env.NODE_ENV !== 'production') {
loggedTypeFailures = {};
}
}

module.exports = checkPropTypes;

+ 19
- 0
node_modules/prop-types/factory.js Просмотреть файл

@@ -0,0 +1,19 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

// React 15.5 references this module, and assumes PropTypes are still callable in production.
// Therefore we re-export development-only version with all the PropTypes checks here.
// However if one is migrating to the `prop-types` npm library, they will go through the
// `index.js` entry point, and it will branch depending on the environment.
var factory = require('./factoryWithTypeCheckers');
module.exports = function(isValidElement) {
// It is still allowed in 15.5.
var throwOnDirectAccess = false;
return factory(isValidElement, throwOnDirectAccess);
};

+ 65
- 0
node_modules/prop-types/factoryWithThrowingShims.js Просмотреть файл

@@ -0,0 +1,65 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

var ReactPropTypesSecret = require('./lib/ReactPropTypesSecret');

function emptyFunction() {}
function emptyFunctionWithReset() {}
emptyFunctionWithReset.resetWarningCache = emptyFunction;

module.exports = function() {
function shim(props, propName, componentName, location, propFullName, secret) {
if (secret === ReactPropTypesSecret) {
// It is still safe when called from React.
return;
}
var err = new Error(
'Calling PropTypes validators directly is not supported by the `prop-types` package. ' +
'Use PropTypes.checkPropTypes() to call them. ' +
'Read more at http://fb.me/use-check-prop-types'
);
err.name = 'Invariant Violation';
throw err;
};
shim.isRequired = shim;
function getShim() {
return shim;
};
// Important!
// Keep this list in sync with production version in `./factoryWithTypeCheckers.js`.
var ReactPropTypes = {
array: shim,
bigint: shim,
bool: shim,
func: shim,
number: shim,
object: shim,
string: shim,
symbol: shim,

any: shim,
arrayOf: getShim,
element: shim,
elementType: shim,
instanceOf: getShim,
node: shim,
objectOf: getShim,
oneOf: getShim,
oneOfType: getShim,
shape: getShim,
exact: getShim,

checkPropTypes: emptyFunctionWithReset,
resetWarningCache: emptyFunction
};

ReactPropTypes.PropTypes = ReactPropTypes;

return ReactPropTypes;
};

+ 610
- 0
node_modules/prop-types/factoryWithTypeCheckers.js Просмотреть файл

@@ -0,0 +1,610 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

var ReactIs = require('react-is');
var assign = require('object-assign');

var ReactPropTypesSecret = require('./lib/ReactPropTypesSecret');
var has = require('./lib/has');
var checkPropTypes = require('./checkPropTypes');

var printWarning = function() {};

if (process.env.NODE_ENV !== 'production') {
printWarning = function(text) {
var message = 'Warning: ' + text;
if (typeof console !== 'undefined') {
console.error(message);
}
try {
// --- Welcome to debugging React ---
// This error was thrown as a convenience so that you can use this stack
// to find the callsite that caused this warning to fire.
throw new Error(message);
} catch (x) {}
};
}

function emptyFunctionThatReturnsNull() {
return null;
}

module.exports = function(isValidElement, throwOnDirectAccess) {
/* global Symbol */
var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec.

/**
* Returns the iterator method function contained on the iterable object.
*
* Be sure to invoke the function with the iterable as context:
*
* var iteratorFn = getIteratorFn(myIterable);
* if (iteratorFn) {
* var iterator = iteratorFn.call(myIterable);
* ...
* }
*
* @param {?object} maybeIterable
* @return {?function}
*/
function getIteratorFn(maybeIterable) {
var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]);
if (typeof iteratorFn === 'function') {
return iteratorFn;
}
}

/**
* Collection of methods that allow declaration and validation of props that are
* supplied to React components. Example usage:
*
* var Props = require('ReactPropTypes');
* var MyArticle = React.createClass({
* propTypes: {
* // An optional string prop named "description".
* description: Props.string,
*
* // A required enum prop named "category".
* category: Props.oneOf(['News','Photos']).isRequired,
*
* // A prop named "dialog" that requires an instance of Dialog.
* dialog: Props.instanceOf(Dialog).isRequired
* },
* render: function() { ... }
* });
*
* A more formal specification of how these methods are used:
*
* type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...)
* decl := ReactPropTypes.{type}(.isRequired)?
*
* Each and every declaration produces a function with the same signature. This
* allows the creation of custom validation functions. For example:
*
* var MyLink = React.createClass({
* propTypes: {
* // An optional string or URI prop named "href".
* href: function(props, propName, componentName) {
* var propValue = props[propName];
* if (propValue != null && typeof propValue !== 'string' &&
* !(propValue instanceof URI)) {
* return new Error(
* 'Expected a string or an URI for ' + propName + ' in ' +
* componentName
* );
* }
* }
* },
* render: function() {...}
* });
*
* @internal
*/

var ANONYMOUS = '<<anonymous>>';

// Important!
// Keep this list in sync with production version in `./factoryWithThrowingShims.js`.
var ReactPropTypes = {
array: createPrimitiveTypeChecker('array'),
bigint: createPrimitiveTypeChecker('bigint'),
bool: createPrimitiveTypeChecker('boolean'),
func: createPrimitiveTypeChecker('function'),
number: createPrimitiveTypeChecker('number'),
object: createPrimitiveTypeChecker('object'),
string: createPrimitiveTypeChecker('string'),
symbol: createPrimitiveTypeChecker('symbol'),

any: createAnyTypeChecker(),
arrayOf: createArrayOfTypeChecker,
element: createElementTypeChecker(),
elementType: createElementTypeTypeChecker(),
instanceOf: createInstanceTypeChecker,
node: createNodeChecker(),
objectOf: createObjectOfTypeChecker,
oneOf: createEnumTypeChecker,
oneOfType: createUnionTypeChecker,
shape: createShapeTypeChecker,
exact: createStrictShapeTypeChecker,
};

/**
* inlined Object.is polyfill to avoid requiring consumers ship their own
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
*/
/*eslint-disable no-self-compare*/
function is(x, y) {
// SameValue algorithm
if (x === y) {
// Steps 1-5, 7-10
// Steps 6.b-6.e: +0 != -0
return x !== 0 || 1 / x === 1 / y;
} else {
// Step 6.a: NaN == NaN
return x !== x && y !== y;
}
}
/*eslint-enable no-self-compare*/

/**
* We use an Error-like object for backward compatibility as people may call
* PropTypes directly and inspect their output. However, we don't use real
* Errors anymore. We don't inspect their stack anyway, and creating them
* is prohibitively expensive if they are created too often, such as what
* happens in oneOfType() for any type before the one that matched.
*/
function PropTypeError(message, data) {
this.message = message;
this.data = data && typeof data === 'object' ? data: {};
this.stack = '';
}
// Make `instanceof Error` still work for returned errors.
PropTypeError.prototype = Error.prototype;

function createChainableTypeChecker(validate) {
if (process.env.NODE_ENV !== 'production') {
var manualPropTypeCallCache = {};
var manualPropTypeWarningCount = 0;
}
function checkType(isRequired, props, propName, componentName, location, propFullName, secret) {
componentName = componentName || ANONYMOUS;
propFullName = propFullName || propName;

if (secret !== ReactPropTypesSecret) {
if (throwOnDirectAccess) {
// New behavior only for users of `prop-types` package
var err = new Error(
'Calling PropTypes validators directly is not supported by the `prop-types` package. ' +
'Use `PropTypes.checkPropTypes()` to call them. ' +
'Read more at http://fb.me/use-check-prop-types'
);
err.name = 'Invariant Violation';
throw err;
} else if (process.env.NODE_ENV !== 'production' && typeof console !== 'undefined') {
// Old behavior for people using React.PropTypes
var cacheKey = componentName + ':' + propName;
if (
!manualPropTypeCallCache[cacheKey] &&
// Avoid spamming the console because they are often not actionable except for lib authors
manualPropTypeWarningCount < 3
) {
printWarning(
'You are manually calling a React.PropTypes validation ' +
'function for the `' + propFullName + '` prop on `' + componentName + '`. This is deprecated ' +
'and will throw in the standalone `prop-types` package. ' +
'You may be seeing this warning due to a third-party PropTypes ' +
'library. See https://fb.me/react-warning-dont-call-proptypes ' + 'for details.'
);
manualPropTypeCallCache[cacheKey] = true;
manualPropTypeWarningCount++;
}
}
}
if (props[propName] == null) {
if (isRequired) {
if (props[propName] === null) {
return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required ' + ('in `' + componentName + '`, but its value is `null`.'));
}
return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required in ' + ('`' + componentName + '`, but its value is `undefined`.'));
}
return null;
} else {
return validate(props, propName, componentName, location, propFullName);
}
}

var chainedCheckType = checkType.bind(null, false);
chainedCheckType.isRequired = checkType.bind(null, true);

return chainedCheckType;
}

function createPrimitiveTypeChecker(expectedType) {
function validate(props, propName, componentName, location, propFullName, secret) {
var propValue = props[propName];
var propType = getPropType(propValue);
if (propType !== expectedType) {
// `propValue` being instance of, say, date/regexp, pass the 'object'
// check, but we can offer a more precise error message here rather than
// 'of type `object`'.
var preciseType = getPreciseType(propValue);

return new PropTypeError(
'Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + preciseType + '` supplied to `' + componentName + '`, expected ') + ('`' + expectedType + '`.'),
{expectedType: expectedType}
);
}
return null;
}
return createChainableTypeChecker(validate);
}

function createAnyTypeChecker() {
return createChainableTypeChecker(emptyFunctionThatReturnsNull);
}

function createArrayOfTypeChecker(typeChecker) {
function validate(props, propName, componentName, location, propFullName) {
if (typeof typeChecker !== 'function') {
return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside arrayOf.');
}
var propValue = props[propName];
if (!Array.isArray(propValue)) {
var propType = getPropType(propValue);
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an array.'));
}
for (var i = 0; i < propValue.length; i++) {
var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']', ReactPropTypesSecret);
if (error instanceof Error) {
return error;
}
}
return null;
}
return createChainableTypeChecker(validate);
}

function createElementTypeChecker() {
function validate(props, propName, componentName, location, propFullName) {
var propValue = props[propName];
if (!isValidElement(propValue)) {
var propType = getPropType(propValue);
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement.'));
}
return null;
}
return createChainableTypeChecker(validate);
}

function createElementTypeTypeChecker() {
function validate(props, propName, componentName, location, propFullName) {
var propValue = props[propName];
if (!ReactIs.isValidElementType(propValue)) {
var propType = getPropType(propValue);
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement type.'));
}
return null;
}
return createChainableTypeChecker(validate);
}

function createInstanceTypeChecker(expectedClass) {
function validate(props, propName, componentName, location, propFullName) {
if (!(props[propName] instanceof expectedClass)) {
var expectedClassName = expectedClass.name || ANONYMOUS;
var actualClassName = getClassName(props[propName]);
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.'));
}
return null;
}
return createChainableTypeChecker(validate);
}

function createEnumTypeChecker(expectedValues) {
if (!Array.isArray(expectedValues)) {
if (process.env.NODE_ENV !== 'production') {
if (arguments.length > 1) {
printWarning(
'Invalid arguments supplied to oneOf, expected an array, got ' + arguments.length + ' arguments. ' +
'A common mistake is to write oneOf(x, y, z) instead of oneOf([x, y, z]).'
);
} else {
printWarning('Invalid argument supplied to oneOf, expected an array.');
}
}
return emptyFunctionThatReturnsNull;
}

function validate(props, propName, componentName, location, propFullName) {
var propValue = props[propName];
for (var i = 0; i < expectedValues.length; i++) {
if (is(propValue, expectedValues[i])) {
return null;
}
}

var valuesString = JSON.stringify(expectedValues, function replacer(key, value) {
var type = getPreciseType(value);
if (type === 'symbol') {
return String(value);
}
return value;
});
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of value `' + String(propValue) + '` ' + ('supplied to `' + componentName + '`, expected one of ' + valuesString + '.'));
}
return createChainableTypeChecker(validate);
}

function createObjectOfTypeChecker(typeChecker) {
function validate(props, propName, componentName, location, propFullName) {
if (typeof typeChecker !== 'function') {
return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside objectOf.');
}
var propValue = props[propName];
var propType = getPropType(propValue);
if (propType !== 'object') {
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an object.'));
}
for (var key in propValue) {
if (has(propValue, key)) {
var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret);
if (error instanceof Error) {
return error;
}
}
}
return null;
}
return createChainableTypeChecker(validate);
}

function createUnionTypeChecker(arrayOfTypeCheckers) {
if (!Array.isArray(arrayOfTypeCheckers)) {
process.env.NODE_ENV !== 'production' ? printWarning('Invalid argument supplied to oneOfType, expected an instance of array.') : void 0;
return emptyFunctionThatReturnsNull;
}

for (var i = 0; i < arrayOfTypeCheckers.length; i++) {
var checker = arrayOfTypeCheckers[i];
if (typeof checker !== 'function') {
printWarning(
'Invalid argument supplied to oneOfType. Expected an array of check functions, but ' +
'received ' + getPostfixForTypeWarning(checker) + ' at index ' + i + '.'
);
return emptyFunctionThatReturnsNull;
}
}

function validate(props, propName, componentName, location, propFullName) {
var expectedTypes = [];
for (var i = 0; i < arrayOfTypeCheckers.length; i++) {
var checker = arrayOfTypeCheckers[i];
var checkerResult = checker(props, propName, componentName, location, propFullName, ReactPropTypesSecret);
if (checkerResult == null) {
return null;
}
if (checkerResult.data && has(checkerResult.data, 'expectedType')) {
expectedTypes.push(checkerResult.data.expectedType);
}
}
var expectedTypesMessage = (expectedTypes.length > 0) ? ', expected one of type [' + expectedTypes.join(', ') + ']': '';
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`' + expectedTypesMessage + '.'));
}
return createChainableTypeChecker(validate);
}

function createNodeChecker() {
function validate(props, propName, componentName, location, propFullName) {
if (!isNode(props[propName])) {
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a ReactNode.'));
}
return null;
}
return createChainableTypeChecker(validate);
}

function invalidValidatorError(componentName, location, propFullName, key, type) {
return new PropTypeError(
(componentName || 'React class') + ': ' + location + ' type `' + propFullName + '.' + key + '` is invalid; ' +
'it must be a function, usually from the `prop-types` package, but received `' + type + '`.'
);
}

function createShapeTypeChecker(shapeTypes) {
function validate(props, propName, componentName, location, propFullName) {
var propValue = props[propName];
var propType = getPropType(propValue);
if (propType !== 'object') {
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.'));
}
for (var key in shapeTypes) {
var checker = shapeTypes[key];
if (typeof checker !== 'function') {
return invalidValidatorError(componentName, location, propFullName, key, getPreciseType(checker));
}
var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret);
if (error) {
return error;
}
}
return null;
}
return createChainableTypeChecker(validate);
}

function createStrictShapeTypeChecker(shapeTypes) {
function validate(props, propName, componentName, location, propFullName) {
var propValue = props[propName];
var propType = getPropType(propValue);
if (propType !== 'object') {
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.'));
}
// We need to check all keys in case some are required but missing from props.
var allKeys = assign({}, props[propName], shapeTypes);
for (var key in allKeys) {
var checker = shapeTypes[key];
if (has(shapeTypes, key) && typeof checker !== 'function') {
return invalidValidatorError(componentName, location, propFullName, key, getPreciseType(checker));
}
if (!checker) {
return new PropTypeError(
'Invalid ' + location + ' `' + propFullName + '` key `' + key + '` supplied to `' + componentName + '`.' +
'\nBad object: ' + JSON.stringify(props[propName], null, ' ') +
'\nValid keys: ' + JSON.stringify(Object.keys(shapeTypes), null, ' ')
);
}
var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret);
if (error) {
return error;
}
}
return null;
}

return createChainableTypeChecker(validate);
}

function isNode(propValue) {
switch (typeof propValue) {
case 'number':
case 'string':
case 'undefined':
return true;
case 'boolean':
return !propValue;
case 'object':
if (Array.isArray(propValue)) {
return propValue.every(isNode);
}
if (propValue === null || isValidElement(propValue)) {
return true;
}

var iteratorFn = getIteratorFn(propValue);
if (iteratorFn) {
var iterator = iteratorFn.call(propValue);
var step;
if (iteratorFn !== propValue.entries) {
while (!(step = iterator.next()).done) {
if (!isNode(step.value)) {
return false;
}
}
} else {
// Iterator will provide entry [k,v] tuples rather than values.
while (!(step = iterator.next()).done) {
var entry = step.value;
if (entry) {
if (!isNode(entry[1])) {
return false;
}
}
}
}
} else {
return false;
}

return true;
default:
return false;
}
}

function isSymbol(propType, propValue) {
// Native Symbol.
if (propType === 'symbol') {
return true;
}

// falsy value can't be a Symbol
if (!propValue) {
return false;
}

// 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol'
if (propValue['@@toStringTag'] === 'Symbol') {
return true;
}

// Fallback for non-spec compliant Symbols which are polyfilled.
if (typeof Symbol === 'function' && propValue instanceof Symbol) {
return true;
}

return false;
}

// Equivalent of `typeof` but with special handling for array and regexp.
function getPropType(propValue) {
var propType = typeof propValue;
if (Array.isArray(propValue)) {
return 'array';
}
if (propValue instanceof RegExp) {
// Old webkits (at least until Android 4.0) return 'function' rather than
// 'object' for typeof a RegExp. We'll normalize this here so that /bla/
// passes PropTypes.object.
return 'object';
}
if (isSymbol(propType, propValue)) {
return 'symbol';
}
return propType;
}

// This handles more types than `getPropType`. Only used for error messages.
// See `createPrimitiveTypeChecker`.
function getPreciseType(propValue) {
if (typeof propValue === 'undefined' || propValue === null) {
return '' + propValue;
}
var propType = getPropType(propValue);
if (propType === 'object') {
if (propValue instanceof Date) {
return 'date';
} else if (propValue instanceof RegExp) {
return 'regexp';
}
}
return propType;
}

// Returns a string that is postfixed to a warning about an invalid type.
// For example, "undefined" or "of type array"
function getPostfixForTypeWarning(value) {
var type = getPreciseType(value);
switch (type) {
case 'array':
case 'object':
return 'an ' + type;
case 'boolean':
case 'date':
case 'regexp':
return 'a ' + type;
default:
return type;
}
}

// Returns class name of the object, if any.
function getClassName(propValue) {
if (!propValue.constructor || !propValue.constructor.name) {
return ANONYMOUS;
}
return propValue.constructor.name;
}

ReactPropTypes.checkPropTypes = checkPropTypes;
ReactPropTypes.resetWarningCache = checkPropTypes.resetWarningCache;
ReactPropTypes.PropTypes = ReactPropTypes;

return ReactPropTypes;
};

+ 19
- 0
node_modules/prop-types/index.js Просмотреть файл

@@ -0,0 +1,19 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

if (process.env.NODE_ENV !== 'production') {
var ReactIs = require('react-is');

// By explicitly using `prop-types` you are opting into new development behavior.
// http://fb.me/prop-types-in-prod
var throwOnDirectAccess = true;
module.exports = require('./factoryWithTypeCheckers')(ReactIs.isElement, throwOnDirectAccess);
} else {
// By explicitly using `prop-types` you are opting into new production behavior.
// http://fb.me/prop-types-in-prod
module.exports = require('./factoryWithThrowingShims')();
}

+ 12
- 0
node_modules/prop-types/lib/ReactPropTypesSecret.js Просмотреть файл

@@ -0,0 +1,12 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';

module.exports = ReactPropTypesSecret;

+ 1
- 0
node_modules/prop-types/lib/has.js Просмотреть файл

@@ -0,0 +1 @@
module.exports = Function.call.bind(Object.prototype.hasOwnProperty);

+ 60
- 0
node_modules/prop-types/package.json Просмотреть файл

@@ -0,0 +1,60 @@
{
"name": "prop-types",
"version": "15.8.1",
"description": "Runtime type checking for React props and similar objects.",
"sideEffects": false,
"main": "index.js",
"license": "MIT",
"files": [
"LICENSE",
"README.md",
"checkPropTypes.js",
"factory.js",
"factoryWithThrowingShims.js",
"factoryWithTypeCheckers.js",
"index.js",
"prop-types.js",
"prop-types.min.js",
"lib"
],
"repository": "facebook/prop-types",
"keywords": [
"react"
],
"bugs": {
"url": "https://github.com/facebook/prop-types/issues"
},
"homepage": "https://facebook.github.io/react/",
"dependencies": {
"loose-envify": "^1.4.0",
"object-assign": "^4.1.1",
"react-is": "^16.13.1"
},
"scripts": {
"pretest": "npm run lint",
"lint": "eslint .",
"test": "npm run tests-only",
"tests-only": "jest",
"umd": "NODE_ENV=development browserify index.js -t loose-envify --standalone PropTypes -o prop-types.js",
"umd-min": "NODE_ENV=production browserify index.js -t loose-envify -t uglifyify --standalone PropTypes -p bundle-collapser/plugin -o | uglifyjs --compress unused,dead_code -o prop-types.min.js",
"build": "yarn umd && yarn umd-min",
"prepublish": "not-in-publish || yarn build"
},
"devDependencies": {
"babel-jest": "^19.0.0",
"babel-preset-react": "^6.24.1",
"browserify": "^16.5.0",
"bundle-collapser": "^1.4.0",
"eslint": "^8.6.0",
"in-publish": "^2.0.1",
"jest": "^19.0.2",
"react": "^15.7.0",
"uglifyify": "^5.0.2",
"uglifyjs": "^2.4.11"
},
"browserify": {
"transform": [
"loose-envify"
]
}
}

+ 1315
- 0
node_modules/prop-types/prop-types.js
Разница между файлами не показана из-за своего большого размера
Просмотреть файл


+ 1
- 0
node_modules/prop-types/prop-types.min.js Просмотреть файл

@@ -0,0 +1 @@
!function(f){"object"==typeof exports&&"undefined"!=typeof module?module.exports=f():"function"==typeof define&&define.amd?define([],f):("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).PropTypes=f()}(function(){return function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var p="function"==typeof require&&require;if(!f&&p)return p(i,!0);if(u)return u(i,!0);throw(p=new Error("Cannot find module '"+i+"'")).code="MODULE_NOT_FOUND",p}p=n[i]={exports:{}},e[i][0].call(p.exports,function(r){return o(e[i][1][r]||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}({1:[function(require,module,exports){"use strict";var ReactPropTypesSecret=require(3);function emptyFunction(){}function emptyFunctionWithReset(){}emptyFunctionWithReset.resetWarningCache=emptyFunction,module.exports=function(){function e(e,t,n,r,o,c){if(c!==ReactPropTypesSecret){c=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw c.name="Invariant Violation",c}}function t(){return e}var n={array:e.isRequired=e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:emptyFunctionWithReset,resetWarningCache:emptyFunction};return n.PropTypes=n}},{3:3}],2:[function(require,module,exports){module.exports=require(1)()},{1:1}],3:[function(require,module,exports){"use strict";module.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},{}]},{},[2])(2)});

+ 6
- 0
node_modules/react-ga/.eslintignore Просмотреть файл

@@ -0,0 +1,6 @@
node_modules
coverage
.nyc_output
dist
.github
.husky

+ 58
- 0
node_modules/react-ga/.eslintrc.js Просмотреть файл

@@ -0,0 +1,58 @@
module.exports = {
parser: '@babel/eslint-parser',
extends: ['airbnb', 'prettier', 'plugin:jest/recommended'],
plugins: ['prettier', 'jest'],
env: {
browser: true
},
rules: {
'prettier/prettier': 'error',
'react/no-find-dom-node': 'off',
'arrow-body-style': 'off',
'no-mixed-operators': 'off',
'no-shadow': ['error', { allow: ['err', 'error'] }],
'react/prefer-stateless-function': [
'error',
{ ignorePureComponents: true }
],

'no-console': ['error', { allow: ['warn', 'error', 'info'] }],
'no-underscore-dangle': 'off',
'guard-for-in': 'off',
'no-param-reassign': ['error', { props: false }],
'jsx-a11y/label-has-associated-control': 'off',
'jsx-a11y/control-has-associated-control': 'off',
'react/jsx-curly-brace-presence': 'off',
'react/jsx-one-expression-per-line': 'off',
'react/jsx-props-no-spreading': 'off'
},
overrides: [
{
files: ['demo/**/*', 'src/components/*.js'],
rules: {
'import/no-extraneous-dependencies': [
'error',
{ devDependencies: true }
],
'import/no-named-as-default-member': 'off',
'react/no-array-index-key': 'off',
'react/jsx-no-bind': 'off',
'react/prop-types': 'off'
}
},
{
files: ['test/**/*'],
env: {
browser: true,
node: true,
'jest/globals': true
},
rules: {
'import/no-extraneous-dependencies': [
'error',
{ devDependencies: true }
]
}
}
]
};

+ 23
- 0
node_modules/react-ga/.github/workflows/release.yml Просмотреть файл

@@ -0,0 +1,23 @@
name: Release
on:
push:
branches:
- master
jobs:
release:
name: Release
runs-on: ubuntu-18.04
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Setup Node.js
uses: actions/setup-node@v1
with:
node-version: 16
- name: Install dependencies
run: npm ci
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npx semantic-release

+ 26
- 0
node_modules/react-ga/.github/workflows/tests.yml Просмотреть файл

@@ -0,0 +1,26 @@
name: Tests

on:
pull_request:
branches: [master]

jobs:
test:
runs-on: ubuntu-latest
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Use Node.js 12
uses: actions/setup-node@v1
with:
node-version: 16
- run: npm ci
- run: npm install react prop-types
- run: npm run build
- run: npm run lint
- run: npm test
- run: npm test:types
- uses: wagoid/commitlint-github-action@v1

+ 4
- 0
node_modules/react-ga/.husky/commit-msg Просмотреть файл

@@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx commitlint -e

+ 4
- 0
node_modules/react-ga/.husky/pre-commit Просмотреть файл

@@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged

+ 0
- 0
node_modules/react-ga/.lintstagedrc.js Просмотреть файл


Некоторые файлы не были показаны из-за большого количества измененных файлов

Загрузка…
Отмена
Сохранить