| @@ -1,12 +1,12 @@ | |||
| { | |||
| "name": "frontend", | |||
| "version": "1.0.20", | |||
| "version": "1.1.18", | |||
| "lockfileVersion": 2, | |||
| "requires": true, | |||
| "packages": { | |||
| "": { | |||
| "name": "frontend", | |||
| "version": "1.0.20", | |||
| "version": "1.1.18", | |||
| "dependencies": { | |||
| "@faceless-ui/slider": "^1.1.14", | |||
| "@faceless-ui/window-info": "^2.1.1", | |||
| @@ -21,12 +21,19 @@ | |||
| "emailjs": "^4.0.0", | |||
| "emailjs-com": "^3.2.0", | |||
| "eslint-plugin-prettier": "^4.0.0", | |||
| "form-data": "^4.0.0", | |||
| "formik": "^2.2.9", | |||
| "framer-motion": "^6.3.4", | |||
| "mailgun.js": "^8.0.6", | |||
| "prop-types": "^15.8.1", | |||
| "react": "^17.0.2", | |||
| "react-cookie": "^4.1.1", | |||
| "react-dom": "^17.0.2", | |||
| "react-dropzone": "^12.0.5", | |||
| "react-ga": "^3.3.1", | |||
| "react-ga4": "^1.4.1", | |||
| "react-google-recaptcha": "^2.1.0", | |||
| "react-helmet-async": "^1.3.0", | |||
| "react-mailchimp-subscribe": "^2.1.3", | |||
| "react-markdown": "^8.0.0", | |||
| "react-router-dom": "^6.2.1", | |||
| @@ -3609,6 +3616,11 @@ | |||
| "@types/node": "*" | |||
| } | |||
| }, | |||
| "node_modules/@types/cookie": { | |||
| "version": "0.3.3", | |||
| "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.3.3.tgz", | |||
| "integrity": "sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow==" | |||
| }, | |||
| "node_modules/@types/debug": { | |||
| "version": "4.1.7", | |||
| "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", | |||
| @@ -3682,6 +3694,15 @@ | |||
| "@types/unist": "*" | |||
| } | |||
| }, | |||
| "node_modules/@types/hoist-non-react-statics": { | |||
| "version": "3.3.1", | |||
| "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", | |||
| "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", | |||
| "dependencies": { | |||
| "@types/react": "*", | |||
| "hoist-non-react-statics": "^3.3.0" | |||
| } | |||
| }, | |||
| "node_modules/@types/html-minifier-terser": { | |||
| "version": "6.1.0", | |||
| "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", | |||
| @@ -3781,8 +3802,7 @@ | |||
| "node_modules/@types/prop-types": { | |||
| "version": "15.7.5", | |||
| "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", | |||
| "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", | |||
| "peer": true | |||
| "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" | |||
| }, | |||
| "node_modules/@types/q": { | |||
| "version": "1.5.5", | |||
| @@ -3803,7 +3823,6 @@ | |||
| "version": "18.0.21", | |||
| "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.21.tgz", | |||
| "integrity": "sha512-7QUCOxvFgnD5Jk8ZKlUAhVcRj7GuJRjnjjiY/IUBWKgOlnvDvTMLD4RTF7NPyVmbRhNrbomZiOepg7M/2Kj1mA==", | |||
| "peer": true, | |||
| "dependencies": { | |||
| "@types/prop-types": "*", | |||
| "@types/scheduler": "*", | |||
| @@ -3826,8 +3845,7 @@ | |||
| "node_modules/@types/scheduler": { | |||
| "version": "0.16.2", | |||
| "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", | |||
| "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", | |||
| "peer": true | |||
| "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" | |||
| }, | |||
| "node_modules/@types/serve-index": { | |||
| "version": "1.9.1", | |||
| @@ -5104,6 +5122,11 @@ | |||
| "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", | |||
| "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" | |||
| }, | |||
| "node_modules/base-64": { | |||
| "version": "1.0.0", | |||
| "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", | |||
| "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==" | |||
| }, | |||
| "node_modules/batch": { | |||
| "version": "0.6.1", | |||
| "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", | |||
| @@ -6199,8 +6222,7 @@ | |||
| "node_modules/csstype": { | |||
| "version": "3.1.1", | |||
| "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", | |||
| "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==", | |||
| "peer": true | |||
| "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" | |||
| }, | |||
| "node_modules/damerau-levenshtein": { | |||
| "version": "1.0.8", | |||
| @@ -7953,9 +7975,9 @@ | |||
| "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==" | |||
| }, | |||
| "node_modules/follow-redirects": { | |||
| "version": "1.14.8", | |||
| "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz", | |||
| "integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==", | |||
| "version": "1.15.2", | |||
| "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", | |||
| "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", | |||
| "funding": [ | |||
| { | |||
| "type": "individual", | |||
| @@ -8156,9 +8178,9 @@ | |||
| } | |||
| }, | |||
| "node_modules/form-data": { | |||
| "version": "3.0.1", | |||
| "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", | |||
| "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", | |||
| "version": "4.0.0", | |||
| "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", | |||
| "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", | |||
| "dependencies": { | |||
| "asynckit": "^0.4.0", | |||
| "combined-stream": "^1.0.8", | |||
| @@ -11258,6 +11280,19 @@ | |||
| } | |||
| } | |||
| }, | |||
| "node_modules/jsdom/node_modules/form-data": { | |||
| "version": "3.0.1", | |||
| "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", | |||
| "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", | |||
| "dependencies": { | |||
| "asynckit": "^0.4.0", | |||
| "combined-stream": "^1.0.8", | |||
| "mime-types": "^2.1.12" | |||
| }, | |||
| "engines": { | |||
| "node": ">= 6" | |||
| } | |||
| }, | |||
| "node_modules/jsesc": { | |||
| "version": "2.5.2", | |||
| "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", | |||
| @@ -11556,6 +11591,25 @@ | |||
| "sourcemap-codec": "^1.4.4" | |||
| } | |||
| }, | |||
| "node_modules/mailgun.js": { | |||
| "version": "8.0.6", | |||
| "resolved": "https://registry.npmjs.org/mailgun.js/-/mailgun.js-8.0.6.tgz", | |||
| "integrity": "sha512-b+c7QO1T4oFsudEcRB2H7oZKth8ZDeYRW4xjW12QQVNYDSJCVxqSQfps6ofcH8fqcCMJdzc76HVNGdnUZgBPCw==", | |||
| "dependencies": { | |||
| "axios": "^0.27.2", | |||
| "base-64": "^1.0.0", | |||
| "url-join": "^4.0.1" | |||
| } | |||
| }, | |||
| "node_modules/mailgun.js/node_modules/axios": { | |||
| "version": "0.27.2", | |||
| "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", | |||
| "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", | |||
| "dependencies": { | |||
| "follow-redirects": "^1.14.9", | |||
| "form-data": "^4.0.0" | |||
| } | |||
| }, | |||
| "node_modules/make-dir": { | |||
| "version": "3.1.0", | |||
| "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", | |||
| @@ -14385,6 +14439,31 @@ | |||
| "node": ">=14" | |||
| } | |||
| }, | |||
| "node_modules/react-async-script": { | |||
| "version": "1.2.0", | |||
| "resolved": "https://registry.npmjs.org/react-async-script/-/react-async-script-1.2.0.tgz", | |||
| "integrity": "sha512-bCpkbm9JiAuMGhkqoAiC0lLkb40DJ0HOEJIku+9JDjxX3Rcs+ztEOG13wbrOskt3n2DTrjshhaQ/iay+SnGg5Q==", | |||
| "dependencies": { | |||
| "hoist-non-react-statics": "^3.3.0", | |||
| "prop-types": "^15.5.0" | |||
| }, | |||
| "peerDependencies": { | |||
| "react": ">=16.4.1" | |||
| } | |||
| }, | |||
| "node_modules/react-cookie": { | |||
| "version": "4.1.1", | |||
| "resolved": "https://registry.npmjs.org/react-cookie/-/react-cookie-4.1.1.tgz", | |||
| "integrity": "sha512-ffn7Y7G4bXiFbnE+dKhHhbP+b8I34mH9jqnm8Llhj89zF4nPxPutxHT1suUqMeCEhLDBI7InYwf1tpaSoK5w8A==", | |||
| "dependencies": { | |||
| "@types/hoist-non-react-statics": "^3.0.1", | |||
| "hoist-non-react-statics": "^3.0.0", | |||
| "universal-cookie": "^4.0.0" | |||
| }, | |||
| "peerDependencies": { | |||
| "react": ">= 16.3.0" | |||
| } | |||
| }, | |||
| "node_modules/react-dev-utils": { | |||
| "version": "12.0.0", | |||
| "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.0.tgz", | |||
| @@ -14541,6 +14620,53 @@ | |||
| "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", | |||
| "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==" | |||
| }, | |||
| "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-ga4": { | |||
| "version": "1.4.1", | |||
| "resolved": "https://registry.npmjs.org/react-ga4/-/react-ga4-1.4.1.tgz", | |||
| "integrity": "sha512-ioBMEIxd4ePw4YtaloTUgqhQGqz5ebDdC4slEpLgy2sLx1LuZBC9iYCwDymTXzcntw6K1dHX183ulP32nNdG7w==" | |||
| }, | |||
| "node_modules/react-google-recaptcha": { | |||
| "version": "2.1.0", | |||
| "resolved": "https://registry.npmjs.org/react-google-recaptcha/-/react-google-recaptcha-2.1.0.tgz", | |||
| "integrity": "sha512-K9jr7e0CWFigi8KxC3WPvNqZZ47df2RrMAta6KmRoE4RUi7Ys6NmNjytpXpg4HI/svmQJLKR+PncEPaNJ98DqQ==", | |||
| "dependencies": { | |||
| "prop-types": "^15.5.0", | |||
| "react-async-script": "^1.1.1" | |||
| }, | |||
| "peerDependencies": { | |||
| "react": ">=16.4.1" | |||
| } | |||
| }, | |||
| "node_modules/react-helmet-async": { | |||
| "version": "1.3.0", | |||
| "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", | |||
| "integrity": "sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==", | |||
| "dependencies": { | |||
| "@babel/runtime": "^7.12.5", | |||
| "invariant": "^2.2.4", | |||
| "prop-types": "^15.7.2", | |||
| "react-fast-compare": "^3.2.0", | |||
| "shallowequal": "^1.1.0" | |||
| }, | |||
| "peerDependencies": { | |||
| "react": "^16.6.0 || ^17.0.0 || ^18.0.0", | |||
| "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0" | |||
| } | |||
| }, | |||
| "node_modules/react-helmet-async/node_modules/react-fast-compare": { | |||
| "version": "3.2.0", | |||
| "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", | |||
| "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" | |||
| }, | |||
| "node_modules/react-is": { | |||
| "version": "16.13.1", | |||
| "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", | |||
| @@ -16767,6 +16893,15 @@ | |||
| "url": "https://opencollective.com/unified" | |||
| } | |||
| }, | |||
| "node_modules/universal-cookie": { | |||
| "version": "4.0.4", | |||
| "resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-4.0.4.tgz", | |||
| "integrity": "sha512-lbRVHoOMtItjWbM7TwDLdl8wug7izB0tq3/YVKhT/ahB4VDvWMyvnADfnJI8y6fSvsjh51Ix7lTGC6Tn4rMPhw==", | |||
| "dependencies": { | |||
| "@types/cookie": "^0.3.3", | |||
| "cookie": "^0.4.0" | |||
| } | |||
| }, | |||
| "node_modules/universalify": { | |||
| "version": "2.0.0", | |||
| "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", | |||
| @@ -16805,6 +16940,11 @@ | |||
| "punycode": "^2.1.0" | |||
| } | |||
| }, | |||
| "node_modules/url-join": { | |||
| "version": "4.0.1", | |||
| "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", | |||
| "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" | |||
| }, | |||
| "node_modules/util-deprecate": { | |||
| "version": "1.0.2", | |||
| "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", | |||
| @@ -20362,6 +20502,11 @@ | |||
| "@types/node": "*" | |||
| } | |||
| }, | |||
| "@types/cookie": { | |||
| "version": "0.3.3", | |||
| "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.3.3.tgz", | |||
| "integrity": "sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow==" | |||
| }, | |||
| "@types/debug": { | |||
| "version": "4.1.7", | |||
| "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", | |||
| @@ -20435,6 +20580,15 @@ | |||
| "@types/unist": "*" | |||
| } | |||
| }, | |||
| "@types/hoist-non-react-statics": { | |||
| "version": "3.3.1", | |||
| "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", | |||
| "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", | |||
| "requires": { | |||
| "@types/react": "*", | |||
| "hoist-non-react-statics": "^3.3.0" | |||
| } | |||
| }, | |||
| "@types/html-minifier-terser": { | |||
| "version": "6.1.0", | |||
| "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", | |||
| @@ -20534,8 +20688,7 @@ | |||
| "@types/prop-types": { | |||
| "version": "15.7.5", | |||
| "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", | |||
| "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", | |||
| "peer": true | |||
| "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" | |||
| }, | |||
| "@types/q": { | |||
| "version": "1.5.5", | |||
| @@ -20556,7 +20709,6 @@ | |||
| "version": "18.0.21", | |||
| "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.21.tgz", | |||
| "integrity": "sha512-7QUCOxvFgnD5Jk8ZKlUAhVcRj7GuJRjnjjiY/IUBWKgOlnvDvTMLD4RTF7NPyVmbRhNrbomZiOepg7M/2Kj1mA==", | |||
| "peer": true, | |||
| "requires": { | |||
| "@types/prop-types": "*", | |||
| "@types/scheduler": "*", | |||
| @@ -20579,8 +20731,7 @@ | |||
| "@types/scheduler": { | |||
| "version": "0.16.2", | |||
| "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", | |||
| "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", | |||
| "peer": true | |||
| "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" | |||
| }, | |||
| "@types/serve-index": { | |||
| "version": "1.9.1", | |||
| @@ -21538,6 +21689,11 @@ | |||
| "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", | |||
| "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" | |||
| }, | |||
| "base-64": { | |||
| "version": "1.0.0", | |||
| "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", | |||
| "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==" | |||
| }, | |||
| "batch": { | |||
| "version": "0.6.1", | |||
| "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", | |||
| @@ -22354,8 +22510,7 @@ | |||
| "csstype": { | |||
| "version": "3.1.1", | |||
| "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", | |||
| "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==", | |||
| "peer": true | |||
| "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" | |||
| }, | |||
| "damerau-levenshtein": { | |||
| "version": "1.0.8", | |||
| @@ -23658,9 +23813,9 @@ | |||
| "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==" | |||
| }, | |||
| "follow-redirects": { | |||
| "version": "1.14.8", | |||
| "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz", | |||
| "integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==" | |||
| "version": "1.15.2", | |||
| "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", | |||
| "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" | |||
| }, | |||
| "fork-ts-checker-webpack-plugin": { | |||
| "version": "6.5.0", | |||
| @@ -23788,9 +23943,9 @@ | |||
| } | |||
| }, | |||
| "form-data": { | |||
| "version": "3.0.1", | |||
| "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", | |||
| "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", | |||
| "version": "4.0.0", | |||
| "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", | |||
| "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", | |||
| "requires": { | |||
| "asynckit": "^0.4.0", | |||
| "combined-stream": "^1.0.8", | |||
| @@ -26005,6 +26160,18 @@ | |||
| "whatwg-url": "^8.5.0", | |||
| "ws": "^7.4.6", | |||
| "xml-name-validator": "^3.0.0" | |||
| }, | |||
| "dependencies": { | |||
| "form-data": { | |||
| "version": "3.0.1", | |||
| "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", | |||
| "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", | |||
| "requires": { | |||
| "asynckit": "^0.4.0", | |||
| "combined-stream": "^1.0.8", | |||
| "mime-types": "^2.1.12" | |||
| } | |||
| } | |||
| } | |||
| }, | |||
| "jsesc": { | |||
| @@ -26250,6 +26417,27 @@ | |||
| "sourcemap-codec": "^1.4.4" | |||
| } | |||
| }, | |||
| "mailgun.js": { | |||
| "version": "8.0.6", | |||
| "resolved": "https://registry.npmjs.org/mailgun.js/-/mailgun.js-8.0.6.tgz", | |||
| "integrity": "sha512-b+c7QO1T4oFsudEcRB2H7oZKth8ZDeYRW4xjW12QQVNYDSJCVxqSQfps6ofcH8fqcCMJdzc76HVNGdnUZgBPCw==", | |||
| "requires": { | |||
| "axios": "^0.27.2", | |||
| "base-64": "^1.0.0", | |||
| "url-join": "^4.0.1" | |||
| }, | |||
| "dependencies": { | |||
| "axios": { | |||
| "version": "0.27.2", | |||
| "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", | |||
| "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", | |||
| "requires": { | |||
| "follow-redirects": "^1.14.9", | |||
| "form-data": "^4.0.0" | |||
| } | |||
| } | |||
| } | |||
| }, | |||
| "make-dir": { | |||
| "version": "3.1.0", | |||
| "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", | |||
| @@ -28094,6 +28282,25 @@ | |||
| "whatwg-fetch": "^3.6.2" | |||
| } | |||
| }, | |||
| "react-async-script": { | |||
| "version": "1.2.0", | |||
| "resolved": "https://registry.npmjs.org/react-async-script/-/react-async-script-1.2.0.tgz", | |||
| "integrity": "sha512-bCpkbm9JiAuMGhkqoAiC0lLkb40DJ0HOEJIku+9JDjxX3Rcs+ztEOG13wbrOskt3n2DTrjshhaQ/iay+SnGg5Q==", | |||
| "requires": { | |||
| "hoist-non-react-statics": "^3.3.0", | |||
| "prop-types": "^15.5.0" | |||
| } | |||
| }, | |||
| "react-cookie": { | |||
| "version": "4.1.1", | |||
| "resolved": "https://registry.npmjs.org/react-cookie/-/react-cookie-4.1.1.tgz", | |||
| "integrity": "sha512-ffn7Y7G4bXiFbnE+dKhHhbP+b8I34mH9jqnm8Llhj89zF4nPxPutxHT1suUqMeCEhLDBI7InYwf1tpaSoK5w8A==", | |||
| "requires": { | |||
| "@types/hoist-non-react-statics": "^3.0.1", | |||
| "hoist-non-react-statics": "^3.0.0", | |||
| "universal-cookie": "^4.0.0" | |||
| } | |||
| }, | |||
| "react-dev-utils": { | |||
| "version": "12.0.0", | |||
| "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.0.tgz", | |||
| @@ -28210,6 +28417,45 @@ | |||
| "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", | |||
| "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==" | |||
| }, | |||
| "react-ga": { | |||
| "version": "3.3.1", | |||
| "resolved": "https://registry.npmjs.org/react-ga/-/react-ga-3.3.1.tgz", | |||
| "integrity": "sha512-4Vc0W5EvXAXUN/wWyxvsAKDLLgtJ3oLmhYYssx+YzphJpejtOst6cbIHCIyF50Fdxuf5DDKqRYny24yJ2y7GFQ==", | |||
| "requires": {} | |||
| }, | |||
| "react-ga4": { | |||
| "version": "1.4.1", | |||
| "resolved": "https://registry.npmjs.org/react-ga4/-/react-ga4-1.4.1.tgz", | |||
| "integrity": "sha512-ioBMEIxd4ePw4YtaloTUgqhQGqz5ebDdC4slEpLgy2sLx1LuZBC9iYCwDymTXzcntw6K1dHX183ulP32nNdG7w==" | |||
| }, | |||
| "react-google-recaptcha": { | |||
| "version": "2.1.0", | |||
| "resolved": "https://registry.npmjs.org/react-google-recaptcha/-/react-google-recaptcha-2.1.0.tgz", | |||
| "integrity": "sha512-K9jr7e0CWFigi8KxC3WPvNqZZ47df2RrMAta6KmRoE4RUi7Ys6NmNjytpXpg4HI/svmQJLKR+PncEPaNJ98DqQ==", | |||
| "requires": { | |||
| "prop-types": "^15.5.0", | |||
| "react-async-script": "^1.1.1" | |||
| } | |||
| }, | |||
| "react-helmet-async": { | |||
| "version": "1.3.0", | |||
| "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", | |||
| "integrity": "sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==", | |||
| "requires": { | |||
| "@babel/runtime": "^7.12.5", | |||
| "invariant": "^2.2.4", | |||
| "prop-types": "^15.7.2", | |||
| "react-fast-compare": "^3.2.0", | |||
| "shallowequal": "^1.1.0" | |||
| }, | |||
| "dependencies": { | |||
| "react-fast-compare": { | |||
| "version": "3.2.0", | |||
| "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", | |||
| "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" | |||
| } | |||
| } | |||
| }, | |||
| "react-is": { | |||
| "version": "16.13.1", | |||
| "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", | |||
| @@ -29856,6 +30102,15 @@ | |||
| "unist-util-is": "^5.0.0" | |||
| } | |||
| }, | |||
| "universal-cookie": { | |||
| "version": "4.0.4", | |||
| "resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-4.0.4.tgz", | |||
| "integrity": "sha512-lbRVHoOMtItjWbM7TwDLdl8wug7izB0tq3/YVKhT/ahB4VDvWMyvnADfnJI8y6fSvsjh51Ix7lTGC6Tn4rMPhw==", | |||
| "requires": { | |||
| "@types/cookie": "^0.3.3", | |||
| "cookie": "^0.4.0" | |||
| } | |||
| }, | |||
| "universalify": { | |||
| "version": "2.0.0", | |||
| "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", | |||
| @@ -29884,6 +30139,11 @@ | |||
| "punycode": "^2.1.0" | |||
| } | |||
| }, | |||
| "url-join": { | |||
| "version": "4.0.1", | |||
| "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", | |||
| "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" | |||
| }, | |||
| "util-deprecate": { | |||
| "version": "1.0.2", | |||
| "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", | |||
| @@ -1,6 +1,6 @@ | |||
| { | |||
| "name": "frontend", | |||
| "version": "1.1.1", | |||
| "version": "1.1.18", | |||
| "private": true, | |||
| "dependencies": { | |||
| "@faceless-ui/slider": "^1.1.14", | |||
| @@ -16,12 +16,19 @@ | |||
| "emailjs": "^4.0.0", | |||
| "emailjs-com": "^3.2.0", | |||
| "eslint-plugin-prettier": "^4.0.0", | |||
| "form-data": "^4.0.0", | |||
| "formik": "^2.2.9", | |||
| "framer-motion": "^6.3.4", | |||
| "mailgun.js": "^8.0.6", | |||
| "prop-types": "^15.8.1", | |||
| "react": "^17.0.2", | |||
| "react-cookie": "^4.1.1", | |||
| "react-dom": "^17.0.2", | |||
| "react-dropzone": "^12.0.5", | |||
| "react-ga": "^3.3.1", | |||
| "react-ga4": "^1.4.1", | |||
| "react-google-recaptcha": "^2.1.0", | |||
| "react-helmet-async": "^1.3.0", | |||
| "react-mailchimp-subscribe": "^2.1.3", | |||
| "react-markdown": "^8.0.0", | |||
| "react-router-dom": "^6.2.1", | |||
| @@ -5,10 +5,7 @@ | |||
| <link rel="icon" href="%PUBLIC_URL%/favicon_diligent.png" /> | |||
| <meta name="viewport" content="width=device-width, height=device-height" /> | |||
| <meta name="theme-color" content="#000000" /> | |||
| <meta | |||
| name="description" | |||
| content="Diligent Software's Website" | |||
| /> | |||
| <meta name="description" content="Diligent Software's Website" data-rh="true" /> | |||
| <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> | |||
| <!-- | |||
| manifest.json provides metadata used when your web app is installed on a | |||
| @@ -27,15 +24,16 @@ | |||
| <title>Diligent Software</title> | |||
| <!-- Google tag (gtag.js) --> | |||
| <!-- <script async src='https://www.googletagmanager.com/gtag/js?id=G-PTZC3WLTZ1'></script> | |||
| <script async src="https://www.googletagmanager.com/gtag/js?id=G-PD7YZVDG30"></script> | |||
| <script> | |||
| window.dataLayer = window.dataLayer || []; | |||
| function gtag() { dataLayer.push(arguments); } | |||
| gtag('js', new Date()); | |||
| gtag('config', 'G-PTZC3WLTZ1'); | |||
| </script> --> | |||
| function gtag() { | |||
| dataLayer.push(arguments); | |||
| } | |||
| gtag("js", new Date()); | |||
| gtag("config", "G-PD7YZVDG30"); | |||
| </script> | |||
| </head> | |||
| <body> | |||
| <noscript>You need to enable JavaScript to run this app.</noscript> | |||
| @@ -22,6 +22,24 @@ body { | |||
| scrollbar-width: none; /* Firefox */ | |||
| } | |||
| .radial-gradient { | |||
| background: radial-gradient(circle, #ffffff00, #8468BF 60%); | |||
| } | |||
| .scale-image { | |||
| -webkit-transform: scale(1); | |||
| transform: scale(1); | |||
| -webkit-transform-origin: center; | |||
| transform-origin: center; | |||
| } | |||
| @media only screen and (max-width: 650px) { | |||
| .scale-image { | |||
| -webkit-transform: scale(1.5); | |||
| transform: scale(1.5); | |||
| -webkit-transform-origin: center; | |||
| transform-origin: center; | |||
| } | |||
| } | |||
| @media only screen and (max-width: 500px) { | |||
| .size-07 { | |||
| transform: scale(0.7); | |||
| @@ -2,13 +2,14 @@ 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 CookieBanner from './components/shared/CookieBanner'; | |||
| import Footer from './components/shared/Footer'; | |||
| import Loader from './components/shared/Loader'; | |||
| import ScrollToTop from './components/root/ScrollToTop'; | |||
| import ReactGA from 'react-ga4'; | |||
| import { useCookies, Cookies } from 'react-cookie'; | |||
| import routes from './routes'; | |||
| const Home = lazy(() => import('./pages/Home')); | |||
| const Portfolio = lazy(() => import('./pages/Portfolio')); | |||
| const Services = lazy(() => import('./pages/Services')); | |||
| @@ -29,24 +30,26 @@ const WorkWithUs = lazy(() => import('./pages/WorkWithUs')); | |||
| // Navigation Links | |||
| const links = routes.filter(item => item.nav === true); | |||
| function App() { | |||
| //tabs for contact form | |||
| const link = useNavigate(); | |||
| const [cookies, setCookie, removeCookie] = useCookies(['user']); | |||
| const [diligentCookie, setDiligentCookie] = useState(cookies.diligent_ga); | |||
| //scroll to Contact segment | |||
| const forwardedRef = useRef(null); | |||
| //initialize analytics page tracking | |||
| //usePageTracking(); | |||
| useEffect(() => { | |||
| if (diligentCookie === 'true') { | |||
| ReactGA.initialize(process.env.REACT_APP_MEASUREMENT_ID); | |||
| } | |||
| }, [diligentCookie]); | |||
| //scroll to Contact fn | |||
| function scrollToView(event) { | |||
| event.preventDefault(); | |||
| if (forwardedRef) { | |||
| //console.log(forwardedRef.current.offsetTop); | |||
| window.scrollTo({ behavior: 'smooth', top: forwardedRef.current.offsetTop }) | |||
| window.scrollTo({ behavior: 'smooth', top: forwardedRef.current.offsetTop }); | |||
| } else { | |||
| link('/contact'); | |||
| } | |||
| @@ -62,6 +65,16 @@ function App() { | |||
| } | |||
| } | |||
| const handleAccept = () => { | |||
| setCookie('diligent_ga', 'true', { path: '/' }); | |||
| setDiligentCookie(prevValue => !prevValue); | |||
| }; | |||
| const handleDecline = () => { | |||
| setCookie('diligent_ga', 'false', { path: '/' }); | |||
| setDiligentCookie(prevValue => !prevValue); | |||
| }; | |||
| return ( | |||
| <div> | |||
| <ScrollToTop /> | |||
| @@ -71,22 +84,25 @@ function App() { | |||
| activeLinks={activeLinks} | |||
| forwardedRef={forwardedRef} | |||
| ></Navigation> | |||
| {diligentCookie === undefined && ( | |||
| <CookieBanner handleAccept={handleAccept} handleDecline={handleDecline} /> | |||
| )} | |||
| <Suspense fallback={<Loader />}> | |||
| <Routes> | |||
| <Route exact path="/" element={<Home forwardedRef={forwardedRef} />}/> | |||
| <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 />}/> | |||
| <Route exact path="/" element={<Home forwardedRef={forwardedRef} />} /> | |||
| <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> | |||
| @@ -1,106 +0,0 @@ | |||
| import propTypes from 'prop-types'; | |||
| import { useState } from 'react'; | |||
| import { ReactComponent as BackTriangle } from '../assets/graphics/BackTriangle.svg'; | |||
| import TriangleButton from './shared/TriangleButton'; | |||
| const api_url = process.env.REACT_APP_API_URL; | |||
| export default function CardCareers(props) { | |||
| const [hideJob, setHideJob] = useState(true); | |||
| return ( | |||
| <div | |||
| className={'transition-all hover:transition-all pb-0 hover:pb-12 flex flex-col justify-center items-center w-4/5 lg:w-5/6 mb-8 lg:mb-0 lg:mr-8 group' | |||
| } | |||
| > | |||
| {/* Collapsed Card */} | |||
| { hideJob && <div> | |||
| <img | |||
| src={api_url + props.image} | |||
| className={ | |||
| 'ml-auto mr-auto block w-2/5 bg-baby-blue text-dark-gray rounded-full p-4' | |||
| } | |||
| /> | |||
| <h3 className={'mt-6 font-semibold text-2xl'}> | |||
| {props.heading} | |||
| </h3> | |||
| <p className={'mt-6 text-sm'}>{props.paragraph}</p> | |||
| <a | |||
| href={'#' + props.heading.split(' ')[0]} | |||
| onClick={() => setHideJob(!hideJob)} | |||
| 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>} | |||
| {/* Expanded Job */} | |||
| { !hideJob && <div | |||
| id={props.heading.split(' ')[0]} | |||
| className={ | |||
| !hideJob | |||
| ? 'hidden' | |||
| : 'dark:text-white w-full h-fit shadow-md rounded-md px-12 lg:px-16 py-12 lg:py-16' | |||
| } | |||
| > | |||
| <div className="flex flex-col items-start justify-center text-left"> | |||
| <div className="flex flex-row items-center justify-start"> | |||
| <div className='mr-4'> | |||
| <TriangleButton onClick={() => setHideJob(!hideJob)} direction={'left'}/> | |||
| </div> | |||
| <img | |||
| src={api_url + props.image} | |||
| className="ml-auto mr-auto block w-2/5 bg-baby-blue text-dark-gray rounded-full p-4" | |||
| /> | |||
| <h3 className="ml-6 w-full font-semibold text-2xl">{props.heading}</h3> | |||
| </div> | |||
| <p className="mt-6 text-sm">{props.paragraph}</p> | |||
| <h4 className="mt-6 font-semibold text-lg">{props.requirements_heading}</h4> | |||
| <p className="mt-6 text-sm">{props.requirements_paragraph}</p> | |||
| <br /> | |||
| <h4 className="mt-6 font-semibold text-lg">{props.expectations_heading}</h4> | |||
| <p className="mt-6 text-sm">{props.expectations_paragraph}</p> | |||
| <h4 className="mt-6 font-semibold text-lg">{props.benefits_heading}</h4> | |||
| <p className="mt-6 text-sm">{props.benefits_paragraph}</p> | |||
| <div className="flex flex-row w-full items-center justify-end"> | |||
| <a | |||
| href="#contact" | |||
| onClick={() => { | |||
| setHideJob(!hideJob); | |||
| props.setClickedPosition('#' + props.hash_position); | |||
| }} | |||
| className="btn btn_primary mt-8 transition-all hover:transition-all" | |||
| > | |||
| Apply | |||
| </a> | |||
| </div> | |||
| </div> | |||
| </div>} | |||
| </div> | |||
| ); | |||
| } | |||
| CardCareers.propTypes = { | |||
| key: propTypes.number, | |||
| image: propTypes.string, | |||
| heading: propTypes.string, | |||
| paragraph: propTypes.string, | |||
| requirements_heading: propTypes.string, | |||
| requirements_paragraph: propTypes.string, | |||
| expectations_heading: propTypes.string, | |||
| expectations_paragraph: propTypes.string, | |||
| benefits_heading: propTypes.string, | |||
| benefits_paragraph: propTypes.string, | |||
| hash_position: propTypes.string, | |||
| setClickedPosition: propTypes.func, | |||
| }; | |||
| @@ -1,15 +1,11 @@ | |||
| import propTypes from 'prop-types'; | |||
| import { useEffect, useState } from 'react'; | |||
| import { ReactComponent as BackTriangle } from '../assets/graphics/BackTriangle.svg'; | |||
| import Wrapper from '../layout/Wrapper'; | |||
| import { useState } from 'react'; | |||
| import Wrapper from '../../layout/Wrapper'; | |||
| import ExpandedCard from './ExpandedCard'; | |||
| import TriangleButton from './shared/TriangleButton'; | |||
| import CareerCard from './CareerCard'; | |||
| import Grid from '../layout/Grid'; | |||
| import { ref } from 'yup'; | |||
| import useClickOutside from '../hooks/useClickOutside'; | |||
| import useComponentVisible from '../hooks/useClickOutside'; | |||
| //import useClickOutside from '../../hooks/useClickOutside'; | |||
| import useComponentVisible from '../../hooks/useClickOutside'; | |||
| const api_url = process.env.REACT_APP_API_URL; | |||
| @@ -29,12 +25,14 @@ export default function CardCareers2({ cards }) { | |||
| {isComponentVisible ? | |||
| <ExpandedCard card={expandedCard} setExpanded={setIsComponentVisible} setExpandedCard={setExpandedCard}></ExpandedCard> | |||
| : | |||
| <div className='flex flex-row justify-center w-full'> | |||
| { | |||
| <div className='flex flex-col md:flex-row justify-center w-full gap-8'> | |||
| {/* { | |||
| cards.map((item, index) => ( | |||
| <CareerCard card={item} key={index} setExpanded={setIsComponentVisible} setExpandedCard={setExpandedCard} /> | |||
| )) | |||
| } | |||
| } */} | |||
| <CareerCard card={cards.NetDev} setExpanded={setIsComponentVisible} setExpandedCard={setExpandedCard} /> | |||
| {/* <CareerCard card={cards.NetDevIntern} setExpanded={setIsComponentVisible} setExpandedCard={setExpandedCard} /> */} | |||
| </div> | |||
| } | |||
| @@ -1,6 +1,6 @@ | |||
| import React from 'react'; | |||
| import PropTypes from 'prop-types'; | |||
| import net from './../assets/icons/net.svg'; | |||
| import net from './../../assets/icons/net.svg'; | |||
| const _card = { | |||
| role: '.Net Developer', | |||
| @@ -0,0 +1,210 @@ | |||
| import React, { useContext, useEffect } from 'react'; | |||
| import PropTypes from 'prop-types'; | |||
| import TriangleButton from '../shared/TriangleButton'; | |||
| import { useNavigate } from 'react-router-dom'; | |||
| import net from './../../assets/icons/net.svg'; | |||
| import { m } from 'framer-motion'; | |||
| import useClickOutside from '../../hooks/useClickOutside'; | |||
| import { UIContext } from '../../context'; | |||
| const _data = { | |||
| requirements: [ | |||
| 'Good software development fundamentals and knowledge of .NET architecture concepts & patterns', | |||
| 'Good knowledge of software design patterns', | |||
| 'Good knowledge of databases and database design', | |||
| 'Experience in working with microservices is a big plus', | |||
| 'The ability to work in a big team but also to work independently', | |||
| 'Excellent communication skills', | |||
| ], | |||
| key: [ | |||
| 'Working as a full-stack developer on various project and products', | |||
| 'Working with 3rd-party APIs', | |||
| 'Working on different integration scenarios', | |||
| 'Setting up project structure and architecture', | |||
| 'Being involved in full project development, from writing a specification to deploying a finished product', | |||
| ], | |||
| offer: [ | |||
| 'Full Remote position', | |||
| 'A fast-growth company with stable projects and strong international clients', | |||
| 'Opportunity to work in teams with experienced engineers', | |||
| 'Competitive employment conditions', | |||
| 'An environment that will make you feel good about your job', | |||
| 'Challenging and diverse projects', | |||
| 'Support in your personal and professional growth', | |||
| 'Flexible working hours', | |||
| 'Private health insurance', | |||
| ], | |||
| }; | |||
| const _card = { | |||
| role: '.Net Developer', | |||
| shortDetails: | |||
| 'Team Diligent is constantly growing! We are looking for a team player that will work with experienced engineers. If technology is your passion and you are ready to move the boundaries of your knowledge every day, then, Diligent is the right place for you. If you are not from Niš, we are offering a full remote position.', | |||
| }; | |||
| const ExpandedCard = ({ card, setExpanded, setExpandedCard }) => { | |||
| const linkTo = useNavigate(); | |||
| const {uiContext, setUiContext} = useContext(UIContext); | |||
| useEffect(() => { | |||
| console.log(card); | |||
| }, []) | |||
| function handleContext(id) { | |||
| setUiContext({ | |||
| ...uiContext, | |||
| tab: id, | |||
| }); | |||
| } | |||
| return ( | |||
| <div | |||
| className={ | |||
| 'dark:text-white card-no-hover w-full h-fit shadow-md rounded-md px-12 lg:px-32 py-12 lg:py-16' | |||
| } | |||
| > | |||
| {card.templateFlag === 1 && ( | |||
| <div className="flex flex-col items-start justify-center text-left"> | |||
| <div className="flex flex-row items-center justify-start"> | |||
| <div className="mr-4 lg:hidden"> | |||
| <TriangleButton | |||
| onClick={() => { | |||
| setExpanded(false); | |||
| setExpandedCard({}); | |||
| }} | |||
| direction={'left'} | |||
| /> | |||
| </div> | |||
| <div className="hidden lg:block absolute top-20 left-12"> | |||
| <TriangleButton | |||
| onClick={() => { | |||
| setExpanded(false); | |||
| setExpandedCard({}); | |||
| }} | |||
| direction={'left'} | |||
| /> | |||
| </div> | |||
| <img | |||
| src={net} | |||
| className="ml-auto mr-auto block w-[70px] bg-baby-blue text-dark-gray" | |||
| /> | |||
| <h3 className="ml-6 w-full font-semibold text-2xl">{card.role}</h3> | |||
| </div> | |||
| <p className="mt-6 text-sm">{card.extended.shortDetails}</p> | |||
| <h4 className="mt-6 font-semibold text-lg">Key Responsibilities:</h4> | |||
| <ul> | |||
| {_data.key.map((item, index) => ( | |||
| <li className="list-disc ml-6" key={index}> | |||
| {item} | |||
| </li> | |||
| ))} | |||
| </ul> | |||
| <br /> | |||
| <h4 className="mt-6 font-semibold text-lg">Requirements:</h4> | |||
| <ul> | |||
| {_data.requirements.map((item, index) => ( | |||
| <li className="list-disc ml-6" key={index}> | |||
| {item} | |||
| </li> | |||
| ))} | |||
| </ul> | |||
| <br /> | |||
| <h4 className="mt-6 font-semibold text-lg">What We Offer:</h4> | |||
| <ul> | |||
| {_data.offer.map((item, index) => ( | |||
| <li className="list-disc ml-6" key={index}> | |||
| {item} | |||
| </li> | |||
| ))} | |||
| </ul> | |||
| <br /> | |||
| <div className="flex flex-row w-full items-center justify-end"> | |||
| <a | |||
| href="/contact" | |||
| className="btn btn_primary mt-8 transition-all hover:transition-all" | |||
| onClick={()=> handleContext(card.id)} | |||
| > | |||
| Apply | |||
| </a> | |||
| </div> | |||
| </div> | |||
| )} | |||
| {card.templateFlag === 2 && ( | |||
| <div className="flex flex-col items-start justify-center text-left"> | |||
| <div className="flex flex-row items-center justify-start"> | |||
| <div className="mr-4 lg:hidden"> | |||
| <TriangleButton | |||
| onClick={() => { | |||
| setExpanded(false); | |||
| setExpandedCard({}); | |||
| }} | |||
| direction={'left'} | |||
| /> | |||
| </div> | |||
| <div className="hidden lg:block absolute top-20 left-12"> | |||
| <TriangleButton | |||
| onClick={() => { | |||
| setExpanded(false); | |||
| setExpandedCard({}); | |||
| }} | |||
| direction={'left'} | |||
| /> | |||
| </div> | |||
| <img | |||
| src={net} | |||
| className="ml-auto mr-auto block w-[70px] bg-baby-blue text-dark-gray" | |||
| /> | |||
| <h3 className="ml-6 w-full font-semibold text-2xl">{card.role}</h3> | |||
| </div> | |||
| <p className="mt-6 text-sm">{card.extended.paragraph}</p> | |||
| <h4 className="mt-6 font-semibold text-lg">What We Offer:</h4> | |||
| <ul> | |||
| {card.extended.offer.map((item, index) => ( | |||
| <li className="list-disc ml-6" key={index}> | |||
| {item} | |||
| </li> | |||
| ))} | |||
| </ul> | |||
| <br /> | |||
| <h4 className="mt-6 font-semibold text-lg">Requirements:</h4> | |||
| <ul> | |||
| {card.extended.requirements.map((item, index) => ( | |||
| <li className="list-disc ml-6" key={index}> | |||
| {item} | |||
| </li> | |||
| ))} | |||
| </ul> | |||
| <br /> | |||
| <h4 className="mt-6 font-semibold text-lg">Our selection process has the following steps:</h4> | |||
| <ul> | |||
| {card.extended.selectionProcess.map((item, index) => ( | |||
| <li className="list-decimal ml-6" key={index}> | |||
| {item} | |||
| </li> | |||
| ))} | |||
| </ul> | |||
| <br /> | |||
| <p className="mt-6 text-sm">{card.extended.conslusionParagraph}</p> | |||
| <br/> | |||
| <div className="flex flex-row w-full items-center justify-end"> | |||
| <a | |||
| href="/contact" | |||
| className="btn btn_primary mt-8 transition-all hover:transition-all" | |||
| onClick={()=> handleContext(card.id)} | |||
| > | |||
| Apply | |||
| </a> | |||
| </div> | |||
| </div> | |||
| )} | |||
| </div> | |||
| ); | |||
| }; | |||
| ExpandedCard.propTypes = {}; | |||
| export default ExpandedCard; | |||
| @@ -1,108 +0,0 @@ | |||
| import React from 'react' | |||
| import PropTypes from 'prop-types' | |||
| import TriangleButton from './shared/TriangleButton'; | |||
| import { useNavigate } from 'react-router-dom'; | |||
| import net from './../assets/icons/net.svg'; | |||
| import { m } from 'framer-motion'; | |||
| import useClickOutside from '../hooks/useClickOutside'; | |||
| const _data = { | |||
| requirements: [ | |||
| 'Good software development fundamentals and knowledge of .NET architecture concepts & patterns', | |||
| 'Good knowledge of software design patterns', | |||
| 'Good knowledge of databases and database design', | |||
| 'Experience in working with microservices is a big plus', | |||
| 'The ability to work in a big team but also to work independently', | |||
| 'Excellent communication skills' | |||
| ], | |||
| key: [ | |||
| 'Working as a full-stack developer on various project and products', | |||
| 'Working with 3rd-party APIs', | |||
| 'Working on different integration scenarios', | |||
| 'Setting up project structure and architecture', | |||
| 'Being involved in full project development, from writing a specification to deploying a finished product' | |||
| ], | |||
| offer: [ | |||
| 'Full Remote position', | |||
| 'A fast-growth company with stable projects and strong international clients', | |||
| 'Opportunity to work in teams with experienced engineers', | |||
| 'Competitive employment conditions', | |||
| 'An environment that will make you feel good about your job', | |||
| 'Challenging and diverse projects', | |||
| 'Support in your personal and professional growth', | |||
| 'Flexible working hours', | |||
| 'Private health insurance' | |||
| ], | |||
| } | |||
| const _card = { | |||
| role: '.Net Developer', | |||
| shortDetails: 'Team Diligent is constantly growing! We are looking for a team player that will work with experienced engineers. If technology is your passion and you are ready to move the boundaries of your knowledge every day, then, Diligent is the right place for you. If you are not from Niš, we are offering a full remote position.', | |||
| } | |||
| const ExpandedCard = ({card, setExpanded, setExpandedCard}) => { | |||
| const linkTo = useNavigate(); | |||
| return ( | |||
| <div | |||
| className={ | |||
| 'dark:text-white card-no-hover w-full h-fit shadow-md rounded-md px-12 lg:px-32 py-12 lg:py-16' | |||
| } | |||
| > | |||
| <div className="flex flex-col items-start justify-center text-left"> | |||
| <div className="flex flex-row items-center justify-start"> | |||
| <div className='mr-4 lg:hidden'> | |||
| <TriangleButton onClick={() => {setExpanded(false); setExpandedCard({})}} direction={'left'}/> | |||
| </div> | |||
| <div className='hidden lg:block absolute top-20 left-12'> | |||
| <TriangleButton onClick={() => {setExpanded(false); setExpandedCard({})}} direction={'left'}/> | |||
| </div> | |||
| <img | |||
| src={net} | |||
| className="ml-auto mr-auto block w-[70px] bg-baby-blue text-dark-gray" | |||
| /> | |||
| <h3 className="ml-6 w-full font-semibold text-2xl">{card.role}</h3> | |||
| </div> | |||
| <p className="mt-6 text-sm">{_card.shortDetails}</p> | |||
| <h4 className="mt-6 font-semibold text-lg">Key Responsibilities:</h4> | |||
| <ul> | |||
| {_data.key.map((item, index) => ( | |||
| <li className='list-disc ml-6' key={index}>{item}</li> | |||
| ))} | |||
| </ul> | |||
| <br /> | |||
| <h4 className="mt-6 font-semibold text-lg">Requirements:</h4> | |||
| <ul> | |||
| {_data.requirements.map((item, index) => ( | |||
| <li className='list-disc ml-6' key={index}>{item}</li> | |||
| ))} | |||
| </ul> | |||
| <br /> | |||
| <h4 className="mt-6 font-semibold text-lg">What We Offer:</h4> | |||
| <ul> | |||
| {_data.offer.map((item, index) => ( | |||
| <li className='list-disc ml-6' key={index}>{item}</li> | |||
| ))} | |||
| </ul> | |||
| <br /> | |||
| <div className="flex flex-row w-full items-center justify-end"> | |||
| <a | |||
| href="/contact" | |||
| className="btn btn_primary mt-8 transition-all hover:transition-all" | |||
| > | |||
| Apply | |||
| </a> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| ) | |||
| } | |||
| ExpandedCard.propTypes = {} | |||
| export default ExpandedCard | |||
| @@ -8,6 +8,7 @@ import PageTitle from './shared/PageTitle'; | |||
| import TestimonialCard from './shared/TestimonialCard'; | |||
| import Boza from './../assets/boza.jpg'; | |||
| import Peter from './../assets/peter1.png'; | |||
| import Nick from './../assets/nick.jpg'; | |||
| import ns from './../assets/ns.png'; | |||
| const _data = { | |||
| @@ -37,6 +38,13 @@ const _data = { | |||
| clientImg: ns, | |||
| alt: 'Niš Ekspres', | |||
| }, | |||
| { | |||
| clientName: 'Nick Pericle', | |||
| paragraph: `We've partnered with the team at Diligent Software for 3 years. We've built over a dozen apps together, and each time we're impressed by Diligent's dedicated approach, and end result. We consider Diligent Software a trusted partner - the trust we share, the flexibility, and the quality we get are just what we need. I can't recommend Diligent enough as a partner.`, | |||
| clientRole: 'VP of Operations @ Profit Optics', | |||
| clientImg: Nick, | |||
| alt: 'Nick', | |||
| }, | |||
| ], | |||
| }; | |||
| @@ -79,6 +87,13 @@ export default function Testimonials({ noTitle }) { | |||
| imageAlt={_data.cards[2].alt} | |||
| paragraph={_data.cards[2].paragraph} | |||
| /> | |||
| <TestimonialCard | |||
| clientName={_data.cards[3].clientName} | |||
| clientRole={_data.cards[3].clientRole} | |||
| clientImg={_data.cards[3].clientImg} | |||
| imageAlt={_data.cards[3].alt} | |||
| paragraph={_data.cards[3].paragraph} | |||
| /> | |||
| </div> | |||
| {/* | |||
| <TestimonialCard/> | |||
| @@ -108,6 +123,13 @@ export default function Testimonials({ noTitle }) { | |||
| imageAlt={_data.cards[2].alt} | |||
| paragraph={_data.cards[2].paragraph} | |||
| /> | |||
| <TestimonialCard | |||
| clientName={_data.cards[3].clientName} | |||
| clientRole={_data.cards[3].clientRole} | |||
| clientImg={_data.cards[3].clientImg} | |||
| imageAlt={_data.cards[3].alt} | |||
| paragraph={_data.cards[3].paragraph} | |||
| /> | |||
| </FMCarousel> | |||
| )} | |||
| </div> | |||
| @@ -9,7 +9,7 @@ const CustomLink = ({href, downloadFile, bg, txt, children}) => { | |||
| // {context} | |||
| // </a> | |||
| <Link {...{ | |||
| className: 'flex gap-2 items-center px-[16px] py-[12px] text-p font-medium bg-[#8568BF] text-white rounded-full' , | |||
| className: 'btn-primary w-fit items-center n-paragraph-title text-white rounded-[16px]' , | |||
| to: href, | |||
| target: '_blank', | |||
| ...(downloadFile && {download: downloadFile}), | |||
| @@ -1,3 +1,4 @@ | |||
| import React, { useRef } from 'react'; | |||
| import TagInput from '../TagInput'; | |||
| import img from '../../assets/images/Inqueries.png'; | |||
| import * as Yup from 'yup'; | |||
| @@ -6,16 +7,16 @@ import { ClientFormContext } from '../../context'; | |||
| import { useContext, useState } from 'react'; | |||
| import * as emailjs from 'emailjs-com'; | |||
| import { motion } from 'framer-motion'; | |||
| import ReactGA from 'react-ga4'; | |||
| import ReCAPTCHA from 'react-google-recaptcha'; | |||
| import axios from 'axios'; | |||
| const api_url = 'http://localhost:1337'; | |||
| export default function ClientForm() { | |||
| export default function ClientForm({ mg }) { | |||
| //search context for prevous entry TODO | |||
| const { clientForm, setClientForm } = useContext(ClientFormContext); | |||
| const [sucMsg, setSucMsg] = useState(false); | |||
| const [errorMsg, setErrorMsg] = useState(''); | |||
| const captchaRef = useRef(null); | |||
| const [msgText, setMsgText] = useState(''); | |||
| const changeFormHandler = event => { | |||
| const { name, value } = event.target; | |||
| setClientForm({ | |||
| @@ -60,82 +61,46 @@ export default function ClientForm() { | |||
| <Formik | |||
| initialValues={clientForm} | |||
| validationSchema={validationSchema} | |||
| onSubmit={values => { | |||
| let data = {}; | |||
| const fetchData = async () => { | |||
| axios.get(`${api_url}/api/client-submissions?filters[Email][$eq]=${values.email}`) | |||
| .then((res) => { | |||
| data = res.data.data[0]; | |||
| if (typeof data == 'undefined') { | |||
| } | |||
| const submitDate = new Date(data.attributes.SubmitDate); | |||
| const now = new Date(); | |||
| if ((now.getMonth() - submitDate.getMonth()) < 1) | |||
| { | |||
| setErrorMsg('You Already sent an email'); | |||
| //console.log('email already sent'); | |||
| return false; | |||
| } | |||
| else { | |||
| fetch(`${api_url}/api/client-submissions/${data.id}`, { | |||
| method: "PUT", | |||
| headers: { | |||
| "Content-type": "application/json; charset=UTF-8", | |||
| }, | |||
| body: JSON.stringify({ | |||
| data: { | |||
| SubmitDate: now, | |||
| } | |||
| }) | |||
| }).then(r => r.json()).then(d => { | |||
| setErrorMsg(''); | |||
| const val = { | |||
| Tag: values.tag, | |||
| Subject: values.subject, | |||
| Email: values.email, | |||
| Firstname: values.firstName, | |||
| Lastname: values.lastName, | |||
| Description: values.description, | |||
| } | |||
| // emailjs | |||
| // .send( | |||
| // process.env.REACT_APP_SERVICE_ID, | |||
| // process.env.REACT_APP_CLIENT_TEMPLATE_ID, | |||
| // val, | |||
| // process.env.REACT_APP_USER_ID, | |||
| // ) | |||
| // .then( | |||
| // result => { | |||
| // console.log(result.text); | |||
| // setSucMsg(true); | |||
| // }, | |||
| // error => { | |||
| // console.log(error.text); | |||
| // }, | |||
| // ); | |||
| }).catch(err => { | |||
| console.log(err) | |||
| return false | |||
| }); | |||
| } | |||
| }) | |||
| } | |||
| fetchData(); | |||
| }} | |||
| onSubmit={async values => { | |||
| const data = { | |||
| Tag: values.tag, | |||
| Subject: values.subject, | |||
| Email: values.email, | |||
| Firstname: values.firstName, | |||
| Lastname: values.lastName, | |||
| Description: values.description, | |||
| }; | |||
| const token = captchaRef.current.getValue(); | |||
| captchaRef.current.reset(); | |||
| if (token.length === 0) { | |||
| setSucMsg(true); | |||
| setMsgText('Please fill reCAPTCHA and try again. Thank you!'); | |||
| } else { | |||
| await axios | |||
| .post(`${process.env.REACT_APP_CAPTCHA_API}/verify-token`, { token }) | |||
| .then(res => { | |||
| setSucMsg(true); | |||
| if (res.data.data.success) { | |||
| setMsgText('Submission Succesful! Thank you!'); | |||
| mg.messages.create('dilig.net', { | |||
| from: `${values.firstName} ${values.lastName} <${values.email}>`, | |||
| to: ['hr@dilig.net'], | |||
| subject: `${values.subject}`, | |||
| text: `${values.description}`, | |||
| html: `<p>${values.description}</p>`, | |||
| }); | |||
| } else setMsgText('Please fill reCAPTCHA and try again. Thank you!'); | |||
| }) | |||
| .catch(error => { | |||
| console.log(error); | |||
| }); | |||
| } | |||
| ReactGA.event('contact', { | |||
| category: 'Contact', | |||
| action: 'Business Inquiry', | |||
| }); | |||
| }} | |||
| > | |||
| {props => ( | |||
| <Form onSubmit={props.handleSubmit}> | |||
| @@ -261,7 +226,12 @@ export default function ClientForm() { | |||
| /> | |||
| </div> | |||
| </div> | |||
| <div className="items-center justify-end flex"> | |||
| <ReCAPTCHA | |||
| sitekey={process.env.REACT_APP_SITE_KEY} | |||
| ref={captchaRef} | |||
| /> | |||
| </div> | |||
| <div className=" py-3 text-right"> | |||
| <button | |||
| type="submit" | |||
| @@ -270,13 +240,11 @@ export default function ClientForm() { | |||
| Submit | |||
| </button> | |||
| </div> | |||
| {sucMsg && <div className={'text-sm text-right text-dg-primary-900'}> | |||
| Submission Succesful! Thank you! | |||
| </div> } | |||
| {errorMsg !== '' && <div className={'text-sm text-right text-red-700'}> | |||
| {errorMsg} | |||
| </div> } | |||
| {sucMsg && ( | |||
| <div className={'text-sm text-right text-dg-primary-900'}> | |||
| {msgText} | |||
| </div> | |||
| )} | |||
| </div> | |||
| <div className="col-span-1 sm:col-span-1 lg:col-span-1"></div> | |||
| @@ -14,6 +14,17 @@ import { ClientFormContext } from '../../context'; | |||
| import { JobFormContext } from '../../context'; | |||
| import PageTitle from './PageTitle'; | |||
| import Wrapper from '../../layout/Wrapper'; | |||
| import { UIContext } from './../../context/index'; | |||
| import Mailgun from 'mailgun.js'; | |||
| import FormData from 'form-data'; | |||
| const mailgun = new Mailgun(FormData); | |||
| const mg = mailgun.client({ | |||
| username: 'api', | |||
| key: process.env.REACT_APP_MAILGUN_API_KEY, | |||
| url: 'https://api.eu.mailgun.net', | |||
| }); | |||
| export default function Contact(props) { | |||
| const [tab, setTab] = useState(true); | |||
| @@ -27,7 +38,7 @@ export default function Contact(props) { | |||
| //if (event.button !== 0) | |||
| event.preventDefault(); | |||
| } | |||
| const { uiContext, setUiContext } = useContext(UIContext); | |||
| const clientContext = useContext(ClientFormContext); | |||
| const jobContext = useContext(JobFormContext); | |||
| @@ -107,14 +118,25 @@ export default function Contact(props) { | |||
| <OrbitOnClick tab={tab} /> | |||
| </div> | |||
| <div className="py-16 relative"> | |||
| <div className="flex justify-end flex-col" > | |||
| <div className="flex justify-end flex-col"> | |||
| <Tab.Group | |||
| defaultIndex={props.defaultIndex} | |||
| onChange={index => handleTab(index)} | |||
| > | |||
| <div className="flex flex-col md:flex-row items-start md:items-baseline md:justify-between" onMouseDown={handleTabClick}> | |||
| {tab ? <PageTitle left heading={"Tell Us About Your Idea!"} subheading={'Contact us'} /> : <PageTitle left heading={"Join Diligent!"} subheading={'Cotact us'} />} | |||
| <div | |||
| className="flex flex-col md:flex-row items-start md:items-baseline md:justify-between" | |||
| onMouseDown={handleTabClick} | |||
| > | |||
| {tab ? ( | |||
| <PageTitle | |||
| left | |||
| heading={'Tell Us About Your Idea!'} | |||
| subheading={'Contact us'} | |||
| /> | |||
| ) : ( | |||
| <PageTitle left heading={'Join Diligent!'} subheading={'Cotact us'} /> | |||
| )} | |||
| <Tab.List className="flex flex-row items-center md:flex-col lg:flex-row h-fit w-fit max-w-max md:ml-auto z-20 p-1 min-h-12 space-x-1 bg-dg-primary-400 rounded-xl my-4 align-middle"> | |||
| <Tab | |||
| className={({ selected }) => | |||
| @@ -148,7 +170,7 @@ export default function Contact(props) { | |||
| <Tab.Panels className="w-full mt-2 mx-auto"> | |||
| <Tab.Panel className={classNames('py-3', 'outline-none')}> | |||
| <ClientFormContext.Provider value={{ clientForm, setClientForm }}> | |||
| <ClientForm /> | |||
| <ClientForm mg={mg} /> | |||
| </ClientFormContext.Provider> | |||
| </Tab.Panel> | |||
| <Tab.Panel className={classNames('py-3', 'outline-none')}> | |||
| @@ -156,6 +178,7 @@ export default function Contact(props) { | |||
| <JobForm | |||
| cntCareers={cntCareers} | |||
| defaultPositionSelection={defaultPositionSelection} | |||
| mg={mg} | |||
| /> | |||
| </JobFormContext.Provider> | |||
| </Tab.Panel> | |||
| @@ -0,0 +1,46 @@ | |||
| import '../../App.css'; | |||
| import Wrapper from '../../layout/Wrapper'; | |||
| import Cookie from './../../assets/Cookie.png'; | |||
| const cookie_p = | |||
| 'We use cookies to personalise content and ads, to provide social media features and to analyse our traffic. We also share information about your use of our site with our social media, advertising and analytics partners who may combine it with other information that you’ve provided to them or that they’ve collected from your use of their services.'; | |||
| const CookieBanner = ({ handleAccept, handleDecline }) => { | |||
| return ( | |||
| <Wrapper> | |||
| <div className="flex flex-row items-start gap-8 xl:mr-0 mr-4 md:p-8 px-2 py-4 isolate max-w-banner fixed bg-dg-primary-75 shadow-custom z-50 bottom-0 rounded-2xl mb-3"> | |||
| <img | |||
| src={Cookie} | |||
| alt="Diligent Cookie" | |||
| className="hidden md:block w-44 h-48 flex-none z-0 grow-0 order-none" | |||
| /> | |||
| <div className="flex flex-col items-start p-0 gap-2.5 max-w-banner"> | |||
| <div className="flex flex-col items-start p-0 gap-4 max-w-banner "> | |||
| <p className="md:text-title text-banner-mobile text-dark-gray font-secondary font-semibold"> | |||
| Our Website uses Cookies | |||
| </p> | |||
| <p className="flex items-center text-dark-gray font-secondary md:text-banner-p text-banner-p-mobile"> | |||
| {cookie_p} | |||
| </p> | |||
| </div> | |||
| <div className="max-w-banner w-full flex items-center justify-end p-0 md:gap-2.5"> | |||
| <button | |||
| onClick={handleDecline} | |||
| className="flex items-start p-0 text-dg-primary-900 bg-dg-primary-75 font-semibold font-secondary md:px-64p px-42p md:py-20p py-15p md:w-max w-36 whitespace-nowrap" | |||
| > | |||
| DECLINE | |||
| </button> | |||
| <button | |||
| onClick={handleAccept} | |||
| className="btn-primary flex flex-row items-start md:px-64p px-42p md:py-20p py-15p md:w-max w-36 whitespace-nowrap" | |||
| > | |||
| Accept | |||
| </button> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </Wrapper> | |||
| ); | |||
| }; | |||
| export default CookieBanner; | |||
| @@ -0,0 +1,15 @@ | |||
| import React from 'react'; | |||
| const GradientWrapper = ({ children, padding }) => { | |||
| return ( | |||
| <div | |||
| className={ | |||
| 'px-[16px] md:px-0 bg-gradient-to-r from-[#90278F] to-[#8468BF]' | |||
| } | |||
| > | |||
| <div className={'max-w-custom md:text-center mx-auto flex flex-col gap-[16px]' + (padding ? ` ${padding}` : null) }>{children}</div> | |||
| </div> | |||
| ); | |||
| }; | |||
| export default GradientWrapper; | |||
| @@ -4,7 +4,7 @@ import propTypes from 'prop-types'; | |||
| const _data = { | |||
| job: [{ | |||
| id:0, | |||
| id:1, | |||
| position: ".Net" | |||
| }, | |||
| ] | |||
| @@ -7,16 +7,23 @@ import { JobFormContext } from '../../context'; | |||
| import { useContext, useState, useRef, useEffect } from 'react'; | |||
| import * as emailjs from 'emailjs-com'; | |||
| import { motion } from 'framer-motion'; | |||
| import ReactGA from 'react-ga4'; | |||
| import MyDropzone from './MyDropzone'; | |||
| import HashPositions from './HashPositions'; | |||
| <<<<<<< HEAD | |||
| import useDataApi from '../../hooks/useDataApi'; | |||
| import axios from 'axios'; | |||
| const api_url = 'http://localhost:1337'; | |||
| ======= | |||
| import ReCAPTCHA from 'react-google-recaptcha'; | |||
| import axios from 'axios'; | |||
| >>>>>>> staging | |||
| export default function JobForm(props) { | |||
| const [sucMsg, setSucMsg] = useState(false); | |||
| const captchaRef = useRef(null); | |||
| const [msgText, setMsgText] = useState(''); | |||
| const cntCareersJobs = props.cntCareers; | |||
| let defaultPositionSelection = props.defaultPositionSelection; | |||
| //search context for prevous entry TODO | |||
| @@ -25,7 +32,7 @@ export default function JobForm(props) { | |||
| const [otherInputState, setOtherInputState] = useState(true); | |||
| const [selectedPosition, setSelectedPosition] = useState(''); | |||
| const [errorMsg, setErrorMsg] = useState(''); | |||
| const [errorMsgPosition, setErrorMsgPosition] = useState(''); | |||
| const fileInput = useRef(); | |||
| function changeFormHandler(event) { | |||
| @@ -73,6 +80,7 @@ export default function JobForm(props) { | |||
| .trim() | |||
| .min(2, 'Cover Letter too short') | |||
| .required('Cover Letter is Required'), | |||
| other: Yup.string(), | |||
| }); | |||
| return ( | |||
| @@ -89,11 +97,15 @@ export default function JobForm(props) { | |||
| initialValues={jobForm} | |||
| validationSchema={validationSchema} | |||
| onChange={changeFormHandler} | |||
| <<<<<<< HEAD | |||
| onSubmit={values => { | |||
| setSucMsg(false); | |||
| //prep file | |||
| ======= | |||
| onSubmit={async values => { | |||
| >>>>>>> staging | |||
| const prepFile = async file => { | |||
| if (file.size >= 2000000) { | |||
| setErrorMsg('File too large!'); | |||
| @@ -107,8 +119,8 @@ export default function JobForm(props) { | |||
| const convertBase64 = file => { | |||
| return new Promise((resolve, reject) => { | |||
| const fileReader = new FileReader(); | |||
| fileReader.readAsDataURL(file); | |||
| fileReader.readAsDataURL(file); | |||
| fileReader.onload = () => { | |||
| resolve(fileReader.result); | |||
| }; | |||
| @@ -118,6 +130,7 @@ export default function JobForm(props) { | |||
| }; | |||
| }); | |||
| }; | |||
| <<<<<<< HEAD | |||
| let data = {}; | |||
| @@ -199,7 +212,64 @@ export default function JobForm(props) { | |||
| } | |||
| ======= | |||
| if ( | |||
| selectedPosition === '' || | |||
| (otherInputState === false && values.other === '') | |||
| ) | |||
| setErrorMsgPosition('Position is Required'); | |||
| else { | |||
| setErrorMsgPosition(''); | |||
| if (jobForm.file === '') { | |||
| setErrorMsg('CV is Required'); | |||
| } else { | |||
| setErrorMsg(''); | |||
| if (jobForm.file.size >= 2000000) { | |||
| setErrorMsg('File too large!'); | |||
| } else { | |||
| const file = { | |||
| filename: 'CV.pdf', | |||
| data: jobForm.file, | |||
| }; | |||
| const token = captchaRef.current.getValue(); | |||
| captchaRef.current.reset(); | |||
| if (token.length === 0) { | |||
| setSucMsg(true); | |||
| setMsgText('Please fill reCAPTCHA and try again. Thank you!'); | |||
| } else { | |||
| await axios | |||
| .post(`${process.env.REACT_APP_CAPTCHA_API}/verify-token`, { | |||
| token, | |||
| }) | |||
| .then(res => { | |||
| setSucMsg(true); | |||
| if (res.data.data.success) { | |||
| setMsgText('Submission Succesful! Thank you!'); | |||
| props.mg.messages.create('dilig.net', { | |||
| from: `${values.firstName} ${values.lastName} <${values.email}>`, | |||
| to: ['hr@dilig.net'], | |||
| subject: 'Applying for a position', | |||
| text: `Email: ${values.email}, Position:${values.position} ${values.other}, Cover letter: ${values.coverLetter}, Link: ${values.link} `, | |||
| html: `<p>Email: ${values.email}</p><p>Position: ${selectedPosition} ${values.other}</p><p>Cover letter: ${values.coverLetter}</p><p>Link (optional): ${values.link}</p>`, | |||
| attachment: file, | |||
| }); | |||
| } else | |||
| setMsgText('Please fill reCAPTCHA and try again. Thank you!'); | |||
| }) | |||
| .catch(error => { | |||
| console.log(error); | |||
| }); | |||
| } | |||
| } | |||
| } | |||
| >>>>>>> staging | |||
| } | |||
| ReactGA.event('contact', { | |||
| category: 'Contact', | |||
| action: 'Job application', | |||
| }); | |||
| }} | |||
| > | |||
| {props => ( | |||
| @@ -258,14 +328,14 @@ export default function JobForm(props) { | |||
| onChange={props.handleChange} | |||
| className="mt-1 disabled:bg-gray-100 disabled:border-gray-300 dark:disabled:bg-gray-400 dark:disabled:border-gray-600 focus:ring-dg-primary-600 focus:border-dg-primary-900 dark:bg-dg-primary-1500 dark:text-white block w-full shadow-sm sm:text-sm border-dg-primary-600 rounded-md transition duration-200" | |||
| /> | |||
| </div> | |||
| {errorMsgPosition != '' ? ( | |||
| <div className="h-4"> | |||
| <ErrorMessage | |||
| name="other" | |||
| component="div" | |||
| className="text-sm text-right text-red-600" | |||
| /> | |||
| <div className="text-sm text-right text-red-600"> | |||
| {errorMsgPosition} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| ) : null} | |||
| <div className="py-1"> | |||
| <label | |||
| htmlFor="first-name" | |||
| @@ -420,7 +490,12 @@ export default function JobForm(props) { | |||
| <div className="text-sm text-right">{errorMsg}</div> | |||
| </div> | |||
| </div> | |||
| <div className="items-center justify-end flex"> | |||
| <ReCAPTCHA | |||
| sitekey={process.env.REACT_APP_SITE_KEY} | |||
| ref={captchaRef} | |||
| /> | |||
| </div> | |||
| <div className=" py-3 text-right"> | |||
| <button | |||
| type="submit" | |||
| @@ -431,7 +506,7 @@ export default function JobForm(props) { | |||
| </div> | |||
| {sucMsg && ( | |||
| <div className={'text-sm text-right text-dg-primary-900'}> | |||
| Submission Succesful! Thank you! | |||
| {msgText} | |||
| </div> | |||
| )} | |||
| </div> | |||
| @@ -8,7 +8,6 @@ export default function MyDropzone(props) { | |||
| const [file, setFile] = useState(''); | |||
| const [empty, setEmpty] = useState(true); | |||
| function emptyFiles() { | |||
| const newFile = []; | |||
| setFile(newFile); | |||
| @@ -28,13 +27,13 @@ export default function MyDropzone(props) { | |||
| </svg> | |||
| ); | |||
| const onDrop = useCallback(acceptedFiles => { | |||
| const onDrop = useCallback(async acceptedFiles => { | |||
| if (acceptedFiles && acceptedFiles.length > 0) { | |||
| if (acceptedFiles[0] !== 'undefined' && acceptedFiles[0].type !== 'undefined') { | |||
| if (acceptedFiles[0].type === 'application/pdf') { | |||
| acceptedFiles.map(file => { | |||
| setFile(file); | |||
| }); | |||
| const files = Array.from(acceptedFiles); | |||
| const fileBuffer = await files[0]; | |||
| setFile(fileBuffer); | |||
| setEmpty(false); | |||
| } | |||
| } | |||
| @@ -1,7 +1,7 @@ | |||
| import React from "react"; | |||
| import PropTypes from 'prop-types' | |||
| const PageTitle = ({heading, subheading, left, color,pb}) => { | |||
| 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 ? " text-[#9B32CE]" : " ") + (pb ? ' pb-2' :' ')}> | |||
| <h6 className={"subheading" + (left ? " text-left":" text-center")}>{subheading}</h6> | |||
| @@ -0,0 +1,21 @@ | |||
| import React from "react"; | |||
| import PropTypes from 'prop-types' | |||
| const PageTitleOneFont = ({heading, subheading, left, color, pb }) => { | |||
| return ( | |||
| <div className={"flex flex-col gap-8p"+ (left ? " text-left items-start":" text-center items-center") + (color ? " text-[#9B32CE]" : " ") + (pb ? ' pb-2' :' ')}> | |||
| <h6 className={"n-subheading" + (left ? " text-left":" text-center")}>{subheading}</h6> | |||
| <h1 className={"n-heading" + (left ? " text-left":" text-center")}>{heading}</h1> | |||
| </div> | |||
| ) | |||
| } | |||
| PageTitleOneFont.propTypes = { | |||
| heading: PropTypes.string, | |||
| subheading: PropTypes.string, | |||
| left: PropTypes.bool, | |||
| color: PropTypes.bool, | |||
| } | |||
| export default PageTitleOneFont; | |||
| @@ -0,0 +1,33 @@ | |||
| import { Helmet } from 'react-helmet-async'; | |||
| import PropTypes from 'prop-types'; | |||
| import '../../styles/cards.css'; | |||
| const api_url = process.env.REACT_APP_API_URL; | |||
| const ReactHelmet = ({ seo }) => { | |||
| console.log(seo); | |||
| return ( | |||
| <Helmet> | |||
| <title>{seo.metaTitle}</title> | |||
| <meta name="description" content={seo.metaDescription} /> | |||
| <link rel="canonical" href={seo.canonicalURL} /> | |||
| <meta name="keywords" content={seo.keywords} /> | |||
| <meta name="viewport" content={seo.metaViewport} /> | |||
| <meta name="robots" content={seo.metaRobots} /> | |||
| <meta property="og:title" content={seo.metaSocial[0].title} /> | |||
| <meta | |||
| property="og:image" | |||
| content={`${api_url}${seo.metaSocial[0].image.data.attributes.url}`} | |||
| /> | |||
| <meta property="og:description" content={seo.metaSocial[0].description} /> | |||
| <meta property="twitter:title" content={seo.metaSocial[1].title} /> | |||
| <meta | |||
| property="twitter:image" | |||
| content={`${api_url}${seo.metaSocial[1].image.data.attributes.url}`} | |||
| /> | |||
| <meta property="twitter:description" content={seo.metaSocial[1].description} /> | |||
| </Helmet> | |||
| ); | |||
| }; | |||
| export default ReactHelmet; | |||
| @@ -21,6 +21,7 @@ export const JobFormContext = React.createContext({ | |||
| }); | |||
| export const UIContext = React.createContext({ | |||
| tab: '', | |||
| tab: true, | |||
| contactRef: '', | |||
| position: 0, | |||
| }) | |||
| @@ -1,16 +1,13 @@ | |||
| import React, { useEffect } from "react"; | |||
| import { useLocation } from "react-router-dom"; | |||
| import { useEffect } from 'react'; | |||
| import { useCookies } from 'react-cookie'; | |||
| import ReactGA from 'react-ga4'; | |||
| 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]); | |||
| } | |||
| const useAnalytics = pageTitle => { | |||
| const [cookies] = useCookies(['user']); | |||
| useEffect(() => { | |||
| if (cookies.diligent_ga === 'true') | |||
| ReactGA.send({ hitType: 'pageview', page: pageTitle }); | |||
| }, []); | |||
| }; | |||
| export default useAnalytics; | |||
| @@ -38,6 +38,23 @@ const useDataApi = (initialUrl, initialData) => { | |||
| isError: false, | |||
| data: initialData, | |||
| }); | |||
| //getData | |||
| useEffect(() => { | |||
| const fetchData = async () => { | |||
| dispatch({ type: 'FETCH_INIT' }); | |||
| try { | |||
| const result = await axios(url); | |||
| dispatch({ type: 'FETCH_SUCCESS', payload: result.data.data.attributes }); | |||
| } catch (error) { | |||
| dispatch({ type: 'FETCH_FAILURE' }); | |||
| } | |||
| }; | |||
| fetchData(); | |||
| }, [url]); | |||
| useEffect(() => { | |||
| let didCancel = false; | |||
| @@ -3,23 +3,25 @@ import ReactDOM from 'react-dom'; | |||
| import './index.css'; | |||
| import App from './App'; | |||
| import reportWebVitals from './reportWebVitals'; | |||
| import { CookiesProvider } from 'react-cookie'; | |||
| import { BrowserRouter } from 'react-router-dom'; | |||
| import { HelmetProvider } from 'react-helmet-async'; | |||
| if (module.hot) module.hot.accept() | |||
| if (module.hot) module.hot.accept(); | |||
| ReactDOM.render( | |||
| <React.StrictMode> | |||
| <BrowserRouter> | |||
| <App /> | |||
| <CookiesProvider> | |||
| <HelmetProvider> | |||
| <App /> | |||
| </HelmetProvider> | |||
| </CookiesProvider> | |||
| </BrowserRouter> | |||
| </React.StrictMode>, | |||
| document.getElementById('root'), | |||
| ); | |||
| // If you want to start measuring performance in your app, pass a function | |||
| // to log results (for example: reportWebVitals(console.log)) | |||
| // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals | |||
| @@ -23,7 +23,9 @@ 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'; | |||
| import useAnalytics from '../hooks/useAnalytics'; | |||
| import ReactHelmet from '../components/shared/ReactHelmet'; | |||
| const _data = { | |||
| heading: { | |||
| subheading: 'About Us', | |||
| @@ -185,16 +187,46 @@ const _data = { | |||
| }, | |||
| }; | |||
| const api_url = process.env.REACT_APP_API_URL; | |||
| export default function About() { | |||
| const [cnt, setCnt] = useState(''); | |||
| const [isLoaded, setIsLoaded] = useState(''); | |||
| useEffect(() => { | |||
| useEffect(async () => { | |||
| document.title = 'About Us'; | |||
| var vid = document.getElementById('animation'); | |||
| vid.playbackRate = 2; | |||
| await axios | |||
| .get( | |||
| `${api_url}/api/aboutpage?populate[0]=SEO&populate[1]=SEO.metaSocial&populate[2]=SEO.metaImage&populate[3]=SEO.metaSocial.image`, | |||
| ) | |||
| .then(res => { | |||
| setCnt(res.data.data.attributes); | |||
| setIsLoaded(true); | |||
| }) | |||
| .catch(err => { | |||
| console.log(err); | |||
| setIsLoaded(false); | |||
| }); | |||
| }, []); | |||
| //useAnalytics(); | |||
| useAnalytics('About Us'); | |||
| 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> | |||
| ); | |||
| } | |||
| return ( | |||
| <PageLayout> | |||
| {cnt.SEO && <ReactHelmet seo={cnt.SEO} />} | |||
| <div className="bg-white dark:bg-dg-primary-1700 w-full pt-32"> | |||
| {/* Heading Section */} | |||
| <section | |||
| @@ -1,9 +1,6 @@ | |||
| import { useState, useEffect } from 'react'; | |||
| import axios from 'axios'; | |||
| import CardCareers from '../components/CardCareers'; | |||
| import Contact from '../components/shared/Contact'; | |||
| import Animation_Diligent from '../assets/animation_diligent.webm'; | |||
| import Wrapper from '../layout/Wrapper'; | |||
| import PageTitle from '../components/shared/PageTitle'; | |||
| @@ -12,10 +9,10 @@ import CardValues from '../components/shared/CardValues'; | |||
| import CardLife from '../components/shared/CardLife'; | |||
| import ActionCard from '../components/shared/ActionCard'; | |||
| import AboutUsSlider from '../components/shared/AboutUsSlider'; | |||
| import CardCareers2 from '../components/CardCareers2'; | |||
| import CardCareers2 from '../components/CareerCardsTemplates/CardCareers2'; | |||
| import OrbitOnScroll from '../components/shared/graphics/OrbitOnScroll'; | |||
| import PageLayout from '../layout/PageLayout'; | |||
| //import useAnalytics from '../hooks/useAnalytics'; | |||
| import useAnalytics from '../hooks/useAnalytics'; | |||
| // eslint-disable-next-line no-underscore-dangle | |||
| const _data = { | |||
| @@ -24,14 +21,83 @@ const _data = { | |||
| subheading: 'Careers', | |||
| }, | |||
| job: { | |||
| cards: [ | |||
| { | |||
| 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.', | |||
| NetDev: { | |||
| id: 1, | |||
| templateFlag: 1, | |||
| role: '.Net Developer', | |||
| nugget: '.Net', | |||
| 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.', | |||
| extended: { | |||
| paragraph: | |||
| 'Team Diligent is constantly growing! We are looking for a team player that will work with experienced engineers. If technology is your passion and you are ready to move the boundaries of your knowledge every day, then, Diligent is the right place for you. If you are not from Niš, we are offering a full remote position.', | |||
| requirements: [ | |||
| 'Good software development fundamentals and knowledge of .NET architecture concepts & patterns', | |||
| 'Good knowledge of software design patterns', | |||
| 'Good knowledge of databases and database design', | |||
| 'Experience in working with microservices is a big plus', | |||
| 'The ability to work in a big team but also to work independently', | |||
| 'Excellent communication skills', | |||
| ], | |||
| key: [ | |||
| 'Working as a full-stack developer on various project and products', | |||
| 'Working with 3rd-party APIs', | |||
| 'Working on different integration scenarios', | |||
| 'Setting up project structure and architecture', | |||
| 'Being involved in full project development, from writing a specification to deploying a finished product', | |||
| ], | |||
| offer: [ | |||
| 'Full Remote position', | |||
| 'A fast-growth company with stable projects and strong international clients', | |||
| 'Opportunity to work in teams with experienced engineers', | |||
| 'Competitive employment conditions', | |||
| 'An environment that will make you feel good about your job', | |||
| 'Challenging and diverse projects', | |||
| 'Support in your personal and professional growth', | |||
| 'Flexible working hours', | |||
| 'Private health insurance', | |||
| ], | |||
| }, | |||
| ], | |||
| }, | |||
| // NetDevIntern: { | |||
| // id: 2, | |||
| // templateFlag: 2, | |||
| // role: '.Net Developer Internship', | |||
| // nugget: '.NetInernship', | |||
| // 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.', | |||
| // extended: { | |||
| // paragraph: | |||
| // 'Team Diligent is constantly growing! We are looking for a team player that will work with experienced engineers. If technology is your passion and you are ready to move the boundaries of your knowledge every day, then, Diligent is the right place for you. If you are not from Niš, we are offering a full remote position.', | |||
| // offer: [ | |||
| // 'Paid internship', | |||
| // 'Full Remote position', | |||
| // 'A fast-growth company with stable projects and strong international clients', | |||
| // 'Experience of working in a team', | |||
| // 'Work on real project with real clients', | |||
| // 'Mentorship from industry leaders', | |||
| // 'Support in your personal and professional growth', | |||
| // 'Lots of team activities and perks', | |||
| // 'Modern working place with a positive and fun atmosphere', | |||
| // ], | |||
| // requirements: [ | |||
| // 'Fundamentals of data structures ', | |||
| // 'Fundamentals and knowledge of .NET architecture concepts & patterns', | |||
| // 'Fundamentals of databases and database design', | |||
| // 'Team player and fast learner', | |||
| // 'Analytical and problem-solving skills', | |||
| // ], | |||
| // selectionProcess: [ | |||
| // 'Application', | |||
| // 'CV Screening', | |||
| // 'HR Interview', | |||
| // 'Technical Interview', | |||
| // 'Internship - offer & contract', | |||
| // ], | |||
| // conslusionParagraph: | |||
| // 'At the end of the selection process, we will select interns able to join our team for a 3 months internship and arrange the beginning of the practice personally with you.', | |||
| // }, | |||
| // }, | |||
| }, | |||
| life: { | |||
| heading: 'A Culture That’s Serious About Work and Fun', | |||
| @@ -93,13 +159,11 @@ export default function Careers({ forwardedRef }) { | |||
| const api_url = process.env.REACT_APP_API_URL; | |||
| useEffect(() => { | |||
| document.title = 'Careers'; | |||
| }, []); | |||
| //useAnalytics(); | |||
| useAnalytics('Careers'); | |||
| useEffect(async () => { | |||
| var vid = document.getElementById('animation'); | |||
| @@ -151,28 +215,11 @@ export default function Careers({ forwardedRef }) { | |||
| className="flex items-center justify-center max-w-custom m-auto" | |||
| > | |||
| <div className="w-full"> | |||
| {/* {cntCareers.job.map(job => ( | |||
| <div key={job.id}> | |||
| <CardCareers | |||
| image={job.icon.data.attributes.url} | |||
| heading={job.heading} | |||
| paragraph={job.paragraph} | |||
| requirements_heading={job.requirements_heading} | |||
| requirements_paragraph={job.requirements_paragraph} | |||
| expectations_heading={job.expectations_heading} | |||
| expectations_paragraph={job.expectations_paragraph} | |||
| benefits_heading={job.benefits_heading} | |||
| benefits_paragraph={job.benefits_paragraph} | |||
| hash_position={job.position} | |||
| setClickedPosition={setClickedPosition} | |||
| /> | |||
| </div> | |||
| ))} */} | |||
| <CardCareers2 cards={_data.job.cards} /> | |||
| <CardCareers2 cards={_data.job} /> | |||
| </div> | |||
| </section> | |||
| </Wrapper> | |||
| <div className='mt-90p'> | |||
| <Wrapper bg padding={' py-90p'}> | |||
| <PageTitle | |||
| left | |||
| @@ -218,6 +265,8 @@ export default function Careers({ forwardedRef }) { | |||
| </section> | |||
| </div> | |||
| </Wrapper> | |||
| </div> | |||
| <Wrapper padding={' py-90p'}> | |||
| <PageTitle heading={_data.connect.heading} color /> | |||
| <p className="paragraph my-32p">{_data.connect.paragraph}</p> | |||
| @@ -1,5 +1,5 @@ | |||
| import ActionCard from '../components/shared/ActionCard'; | |||
| //import useAnalytics from '../hooks/useAnalytics'; | |||
| import useAnalytics from '../hooks/useAnalytics'; | |||
| import PageLayout from '../layout/PageLayout'; | |||
| import { useEffect } from 'react'; | |||
| @@ -41,163 +41,164 @@ const technologies = [ | |||
| export default function CaseStudy() { | |||
| useEffect(() => { | |||
| document.title = 'Case Studies'; | |||
| },[]); | |||
| }, []); | |||
| useAnalytics('Case Studies'); | |||
| //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://images.unsplash.com/photo-1619252584172-a83a949b6efd')] bg-fixed 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">Case Study</h6> | |||
| <h1 className="heading text-dg-secondary mt-2">BI Healthcare Solution </h1> | |||
| <p className="paragraph mt-4"> | |||
| BI Solution that provides an uncommon level of insights into the healing | |||
| process. | |||
| </p> | |||
| <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://images.unsplash.com/photo-1619252584172-a83a949b6efd')] bg-fixed 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">Case Study</h6> | |||
| <h1 className="heading text-dg-secondary mt-2">BI Healthcare Solution </h1> | |||
| <p className="paragraph mt-4"> | |||
| BI Solution that provides an uncommon level of insights into the healing | |||
| process. | |||
| </p> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </section> | |||
| </section> | |||
| {/* 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">About the Client</h3> | |||
| <p className="paragraph mt-4"> | |||
| Healthcare company has a centralized IT solution for tracking every aspect | |||
| of their own business, especially services provided to clients and working | |||
| times of their clinicians in all clinics they own all around the USA. | |||
| </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">Country</h5> | |||
| <p className="mt-4">USA</p> | |||
| {/* 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">About the Client</h3> | |||
| <p className="paragraph mt-4"> | |||
| Healthcare company has a centralized IT solution for tracking every aspect | |||
| of their own business, especially services provided to clients and working | |||
| times of their clinicians in all clinics they own all around the USA. | |||
| </p> | |||
| </div> | |||
| <div className="float-left md:float-right text-left md:text-right"> | |||
| <h5 className="text-teal-600 font-semibold">Industry</h5> | |||
| <p className="mt-4">Healthcare</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"> | |||
| <h5 className="text-teal-600 font-semibold">Country</h5> | |||
| <p className="mt-4">USA</p> | |||
| </div> | |||
| <div className="float-left md:float-right text-left md:text-right"> | |||
| <h5 className="text-teal-600 font-semibold">Industry</h5> | |||
| <p className="mt-4">Healthcare</p> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </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">Domain</h3> | |||
| <p className="paragraph mt-4"> | |||
| BI Solution helps clinicians to improve their work and create a wider | |||
| picture of client progress during the healing process. The solution offers | |||
| our customers a high level of insight into their cash flows and workforce | |||
| organization. In one word, this is a fully customizable solution for a | |||
| comprehensive business process. | |||
| </p> | |||
| </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">Challanges</h3> | |||
| <p className="text-sm text-dark-gray dark:text-white mt-4"> | |||
| The main objective is to create a solution that meets the requirements of | |||
| stakeholders while integrating with existing IT systems to get data | |||
| without impacting the system. The solution should use only an MS stack of | |||
| technologies while taking care of sensitive data, and maintaining and | |||
| providing up-to-date data. The solution should also be a comfortable and | |||
| reliable, user-friendly solution for everyday work. | |||
| </p> | |||
| </div> | |||
| <div className="mt-8"> | |||
| <h3 className="h3-heading">Solution</h3> | |||
| <p className="text-sm text-dark-gray dark:text-white mt-4"> | |||
| The purpose of interactive data visualization is to allow users to explore | |||
| and understand data. We used the Power BI analytics service to accomplish | |||
| this. Azure has several features that automate data processing and ensure | |||
| the reliability and security of the data. | |||
| {/* 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">Domain</h3> | |||
| <p className="paragraph mt-4"> | |||
| BI Solution helps clinicians to improve their work and create a wider | |||
| picture of client progress during the healing process. The solution offers | |||
| our customers a high level of insight into their cash flows and workforce | |||
| organization. In one word, this is a fully customizable solution for a | |||
| comprehensive business process. | |||
| </p> | |||
| </div> | |||
| </div> | |||
| <img | |||
| src="https://drive.google.com/uc?export=view&id=1TDOQDUkH4dDnjx2x5DJkDpi5xEHrbCvS" | |||
| 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">Results</h3> | |||
| <ul className="list-disc paragraph mt-2 pl-8"> | |||
| <li>Visualize information to ensure better data understanding </li> | |||
| <li> | |||
| Deliver the product within an established amount of time and defined | |||
| budgets | |||
| </li> | |||
| <li> Be up to date with the latest stack of technologies</li> | |||
| <li> | |||
| Offer services from ETL with complex data processing to data visualization | |||
| </li> | |||
| </ul> | |||
| {/* 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">Challanges</h3> | |||
| <p className="text-sm text-dark-gray dark:text-white mt-4"> | |||
| The main objective is to create a solution that meets the requirements | |||
| of stakeholders while integrating with existing IT systems to get data | |||
| without impacting the system. The solution should use only an MS stack | |||
| of technologies while taking care of sensitive data, and maintaining and | |||
| providing up-to-date data. The solution should also be a comfortable and | |||
| reliable, user-friendly solution for everyday work. | |||
| </p> | |||
| </div> | |||
| <div className="mt-8"> | |||
| <h3 className="h3-heading">Solution</h3> | |||
| <p className="text-sm text-dark-gray dark:text-white mt-4"> | |||
| The purpose of interactive data visualization is to allow users to | |||
| explore and understand data. We used the Power BI analytics service to | |||
| accomplish this. Azure has several features that automate data | |||
| processing and ensure the reliability and security of the data. | |||
| </p> | |||
| </div> | |||
| </div> | |||
| <img | |||
| src="https://drive.google.com/uc?export=view&id=1TDOQDUkH4dDnjx2x5DJkDpi5xEHrbCvS" | |||
| alt="Case Study main image" | |||
| className="text-center w-full md:w-1/2" | |||
| /> | |||
| </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> | |||
| {/* 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">Results</h3> | |||
| <ul className="list-disc paragraph mt-2 pl-8"> | |||
| <li>Visualize information to ensure better data understanding </li> | |||
| <li> | |||
| Deliver the product within an established amount of time and defined | |||
| budgets | |||
| </li> | |||
| <li> Be up to date with the latest stack of technologies</li> | |||
| <li> | |||
| Offer services from ETL with complex data processing to data | |||
| visualization | |||
| </li> | |||
| </ul> | |||
| </div> | |||
| </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"> | |||
| {technologies.map(technology => ( | |||
| <img | |||
| key={technology.id} | |||
| src={technology.link} | |||
| alt="Technology's image" | |||
| className="w-12 md:w-16 lg:w-20" | |||
| /> | |||
| ))} | |||
| </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"> | |||
| {technologies.map(technology => ( | |||
| <img | |||
| key={technology.id} | |||
| src={technology.link} | |||
| alt="Technology's image" | |||
| className="w-12 md:w-16 lg:w-20" | |||
| /> | |||
| ))} | |||
| </div> | |||
| </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="Grow faster with a dedicated team of .NET & JS experts." | |||
| btn1="More Projects" | |||
| btn2="Contact Us" | |||
| link1={'/portfolio'} | |||
| link2={'/contact'} | |||
| /> | |||
| </div> | |||
| </section> | |||
| </div> | |||
| </PageLayout> | |||
| ); | |||
| } | |||
| @@ -10,7 +10,7 @@ import { useEffect } from 'react'; | |||
| import Wrapper from '../layout/Wrapper'; | |||
| import TechNuggets from '../components/shared/TechNuggets'; | |||
| import { motion } from 'framer-motion'; | |||
| //import useAnalytics from '../hooks/useAnalytics'; | |||
| import useAnalytics from '../hooks/useAnalytics'; | |||
| const numbers = [ | |||
| { | |||
| @@ -117,12 +117,11 @@ const _data = { | |||
| }; | |||
| export default function CaseStudyBI() { | |||
| useEffect(() => { | |||
| document.title = 'Case Study: BI Healthcare Solution'; | |||
| }, []); | |||
| //useAnalytics(); | |||
| useAnalytics('Case Study: BI Healthcare Solution'); | |||
| return ( | |||
| <PageLayout> | |||
| @@ -245,7 +244,16 @@ export default function CaseStudyBI() { | |||
| <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']} | |||
| 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> | |||
| </section> | |||
| @@ -255,7 +263,7 @@ export default function CaseStudyBI() { | |||
| <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." | |||
| text="Grow faster with a dedicated team of .NET & JS experts." | |||
| btn1="More Projects" | |||
| btn2="Contact Us" | |||
| link1={'/portfolio'} | |||
| @@ -10,7 +10,7 @@ import { useEffect } from 'react'; | |||
| import Wrapper from '../layout/Wrapper'; | |||
| import { motion } from 'framer-motion'; | |||
| import TechNuggets from '../components/shared/TechNuggets'; | |||
| //import useAnalytics from '../hooks/useAnalytics'; | |||
| import useAnalytics from '../hooks/useAnalytics'; | |||
| const numbers = [ | |||
| { | |||
| @@ -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 our biggest challenges were connected with the actual diversity of systems that we needed to integrate. Some of them didn't even have open API-s, some required an extra set of rules, and some 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,12 +120,11 @@ const _data = { | |||
| }; | |||
| export default function CaseStudyCentralized() { | |||
| useEffect(() => { | |||
| document.title = 'Case Study: Centralized Monitoring System'; | |||
| }, []); | |||
| //useAnalytics(); | |||
| useAnalytics('Case Study: Centralized Monitoring System'); | |||
| return ( | |||
| <PageLayout> | |||
| @@ -146,26 +145,25 @@ export default function CaseStudyCentralized() { | |||
| </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' }} | |||
| > | |||
| {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> | |||
| <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"> | |||
| @@ -250,7 +248,7 @@ export default function CaseStudyCentralized() { | |||
| <div className="w-full"> | |||
| <h3 className="h3-heading">Technologies</h3> | |||
| </div> | |||
| <TechNuggets tech={['.Net','MS SQL Server','JQuery','Power BI']} /> | |||
| <TechNuggets tech={['.Net', 'MS SQL Server', 'JQuery', 'Power BI']} /> | |||
| </div> | |||
| </section> | |||
| @@ -259,7 +257,7 @@ export default function CaseStudyCentralized() { | |||
| <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." | |||
| text="Grow faster with a dedicated team of .NET & JS experts." | |||
| btn1="More Projects" | |||
| btn2="Contact Us" | |||
| link1={'/portfolio'} | |||
| @@ -8,7 +8,7 @@ import { useEffect } from 'react'; | |||
| import { motion } from 'framer-motion'; | |||
| import Wrapper from '../layout/Wrapper'; | |||
| import TechNuggets from '../components/shared/TechNuggets'; | |||
| //import useAnalytics from '../hooks/useAnalytics'; | |||
| import useAnalytics from '../hooks/useAnalytics'; | |||
| const numbers = [ | |||
| { | |||
| value: 5, | |||
| @@ -113,7 +113,7 @@ export default function CaseStudyFinantial() { | |||
| document.title = 'Case Study: Financial Engine'; | |||
| }, []); | |||
| //useAnalytics(); | |||
| useAnalytics('Case Study: Financial Engine'); | |||
| return ( | |||
| <PageLayout> | |||
| @@ -229,14 +229,20 @@ export default function CaseStudyFinantial() { | |||
| </div> | |||
| </section> | |||
| {/* Technologies Section */} | |||
| <section id="technologies" className="flex flex-col mt-16"> | |||
| {/* 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)']} | |||
| tech={[ | |||
| '.Net', | |||
| 'Service-Oriented Architecture (SOA)', | |||
| 'MS SQL Server', | |||
| 'MS MVC', | |||
| 'Event-Driven Architecture (EDA)', | |||
| ]} | |||
| /> | |||
| </div> | |||
| </section> | |||
| @@ -246,7 +252,7 @@ export default function CaseStudyFinantial() { | |||
| <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." | |||
| text="Grow faster with a dedicated team of .NET & JS experts." | |||
| btn1="More Projects" | |||
| btn2="Contact Us" | |||
| link1={'/portfolio'} | |||
| @@ -10,7 +10,7 @@ import { useEffect } from 'react'; | |||
| import { motion } from 'framer-motion'; | |||
| import Wrapper from '../layout/Wrapper'; | |||
| import TechNuggets from '../components/shared/TechNuggets'; | |||
| //import useAnalytics from '../hooks/useAnalytics'; | |||
| import useAnalytics from '../hooks/useAnalytics'; | |||
| const numbers = [ | |||
| { | |||
| @@ -115,13 +115,11 @@ const _data = { | |||
| }; | |||
| export default function CaseStudyResource() { | |||
| useEffect(() => { | |||
| document.title = 'Case Study: Resource Planning System'; | |||
| }, []); | |||
| //useAnalytics(); | |||
| useAnalytics('Case Study: Resource Planning System'); | |||
| return ( | |||
| <PageLayout> | |||
| @@ -243,9 +241,7 @@ export default function CaseStudyResource() { | |||
| <div className="w-full"> | |||
| <h3 className="h3-heading">Technologies</h3> | |||
| </div> | |||
| <TechNuggets | |||
| tech={['.Net', 'MS SQL Server', 'React Native', 'React.JS']} | |||
| /> | |||
| <TechNuggets tech={['.Net', 'MS SQL Server', 'React Native', 'React.JS']} /> | |||
| </div> | |||
| </section> | |||
| @@ -254,7 +250,7 @@ export default function CaseStudyResource() { | |||
| <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." | |||
| text="Grow faster with a dedicated team of .NET & JS experts." | |||
| btn1="More Projects" | |||
| btn2="Contact Us" | |||
| link1={'/portfolio'} | |||
| @@ -11,7 +11,7 @@ import { useEffect } from 'react'; | |||
| import { motion } from 'framer-motion'; | |||
| import Wrapper from '../layout/Wrapper'; | |||
| import TechNuggets from '../components/shared/TechNuggets'; | |||
| //import useAnalytics from '../hooks/useAnalytics'; | |||
| import useAnalytics from '../hooks/useAnalytics'; | |||
| const numbers = [ | |||
| { | |||
| @@ -111,13 +111,12 @@ const _data = { | |||
| }; | |||
| export default function CaseStudyStrata() { | |||
| useEffect(() => { | |||
| document.title = 'Case Study: Healthcare Tracking Software'; | |||
| }, []); | |||
| //useAnalytics(); | |||
| useAnalytics('Case Study: Healthcare Tracking Software'); | |||
| return ( | |||
| <PageLayout> | |||
| <div className="bg-baby-blue dark:bg-dg-primary-1700 w-full pt-20 md:pt-24"> | |||
| @@ -240,9 +239,7 @@ export default function CaseStudyStrata() { | |||
| <div className="w-full"> | |||
| <h3 className="h3-heading">Technologies</h3> | |||
| </div> | |||
| <TechNuggets | |||
| tech={['C#', 'MVC', 'SQL','Ajax','React Native']} | |||
| /> | |||
| <TechNuggets tech={['C#', 'MVC', 'SQL', 'Ajax', 'React Native']} /> | |||
| </div> | |||
| </section> | |||
| @@ -251,7 +248,7 @@ export default function CaseStudyStrata() { | |||
| <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." | |||
| text="Grow faster with a dedicated team of .NET & JS experts." | |||
| btn1="More Projects" | |||
| btn2="Contact Us" | |||
| link1={'/portfolio'} | |||
| @@ -10,7 +10,7 @@ import ionic from './../assets/icons/caseStudy/ionic.svg'; | |||
| import { useEffect } from 'react'; | |||
| import { motion } from 'framer-motion'; | |||
| import TechNuggets from '../components/shared/TechNuggets'; | |||
| //import useAnalytics from '../hooks/useAnalytics'; | |||
| import useAnalytics from '../hooks/useAnalytics'; | |||
| const numbers = [ | |||
| { | |||
| value: 10, | |||
| @@ -57,7 +57,7 @@ const _data = { | |||
| challanges: { | |||
| heading: 'Challanges', | |||
| paragraph: | |||
| 'There are many different types of applications based on a platform where they will be executed. There is a lot of specific hardware system (ex. Cameras, Barcode scanner, etc.) that needed to be connected with some parts of our system. Data between components must be shared in real-time.', | |||
| 'There are many different types of applications based on a platform where they will be executed. There are a lot of specific hardware systems (ex. Cameras, Barcode scanner, etc.) that needed to be connected with some parts of our system. Data between components must be shared in real-time.', | |||
| }, | |||
| solution: { | |||
| @@ -73,7 +73,7 @@ const _data = { | |||
| list: [ | |||
| { | |||
| id: 1, | |||
| text: 'Uploading documents for every case and for every hearing', | |||
| text: 'Innovations introduced with the latest hardware in the industry', | |||
| }, | |||
| { | |||
| id: 2, | |||
| @@ -123,13 +123,11 @@ const _data = { | |||
| }; | |||
| export default function CaseStudyTicketing() { | |||
| useEffect(() => { | |||
| document.title = 'Case Study: Ticketing System For Passengers'; | |||
| }, []); | |||
| //useAnalytics(); | |||
| useAnalytics('Case Study: Ticketing System For Passengers'); | |||
| return ( | |||
| <PageLayout> | |||
| @@ -246,10 +244,7 @@ export default function CaseStudyTicketing() { | |||
| </section> | |||
| {/* Technologies Section */} | |||
| <section | |||
| id="technologies" | |||
| className="flex flex-col mt-16" | |||
| > | |||
| <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> | |||
| @@ -265,7 +260,7 @@ export default function CaseStudyTicketing() { | |||
| <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." | |||
| text="Grow faster with a dedicated team of .NET & JS experts." | |||
| btn1="More Projects" | |||
| btn2="Contact Us" | |||
| link1={'/portfolio'} | |||
| @@ -1,22 +1,26 @@ | |||
| import React, { useEffect, useState } from 'react'; | |||
| import Contact from '../components/shared/Contact'; | |||
| import { UIContext } from '../context'; | |||
| import PageLayout from '../layout/PageLayout'; | |||
| //import useAnalytics from '../hooks/useAnalytics'; | |||
| import useAnalytics from '../hooks/useAnalytics'; | |||
| function ContactPage() { | |||
| const [data, setData] = useState(''); | |||
| const [isLoaded, setIsLoaded] = useState(''); | |||
| useEffect(() => { | |||
| document.title = 'Contact Us'; | |||
| }, []); | |||
| useAnalytics('Contact Us'); | |||
| return ( | |||
| <PageLayout> | |||
| <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} /> | |||
| <UIContext.Provider value={UIContext}> | |||
| <Contact /> | |||
| </UIContext.Provider> | |||
| </section> | |||
| </PageLayout> | |||
| ); | |||
| @@ -30,8 +30,23 @@ import PortfolioSection from '../components/PortfolioSection'; | |||
| import PageLayout from '../layout/PageLayout'; | |||
| import MapDilig from '../components/Map'; | |||
| import useDataApi from '../hooks/useDataApi'; | |||
| import useAnalytics from '../hooks/useAnalytics'; | |||
| import ReactHelmet from '../components/shared/ReactHelmet'; | |||
| const api_url = process.env.REACT_APP_API_URL; | |||
| // const fieldArray = [ | |||
| // 'landing', | |||
| // 'why', | |||
| // 'why.heading', | |||
| // 'why.card_left.icon', | |||
| // 'why.card_mid.icon', | |||
| // 'why.card_right.icon', | |||
| // 'landing.heading', | |||
| // 'SEO', | |||
| // 'SEO.metaSocial', | |||
| // 'SEO.metaImage', | |||
| // 'SEO.metaSocial.image', | |||
| // ]; | |||
| const strapiPopulate = [ | |||
| @@ -59,7 +74,7 @@ const stringBuilder = () => { | |||
| return stringQuery; | |||
| }; | |||
| export default function Home({forwardedRef}) { | |||
| export default function Home({ forwardedRef }) { | |||
| const [cnt, setCnt] = useState(''); | |||
| const [landingData, setLandingData] = useState(null); | |||
| const [cardData, setCardData] = useState(null); | |||
| @@ -69,6 +84,9 @@ export default function Home({forwardedRef}) { | |||
| const [{ data, isLoading, isError }, doFetch] = useDataApi( | |||
| `${api_url}/api/w-home-page?${stringBuilder()}`, | |||
| ); | |||
| const [contactElement, setContactElement] = useState(0); | |||
| useAnalytics('Home page'); | |||
| useEffect(() => { | |||
| document.title = 'Diligent Software'; | |||
| @@ -115,6 +133,7 @@ export default function Home({forwardedRef}) { | |||
| } else { | |||
| return ( | |||
| <PageLayout> | |||
| {cnt.SEO && <ReactHelmet seo={cnt.SEO} />} | |||
| <div className="bg-white dark:bg-dg-primary-1700 w-full pt-32 overflow-hidden"> | |||
| {/* <FormSwitch /> */} | |||
| @@ -130,10 +149,10 @@ export default function Home({forwardedRef}) { | |||
| </Tab.Group> */} | |||
| {/* Landing Section */} | |||
| {data && <Landing heading={data.Heading} numbers={data.HeroNumbers.number} button={data.button} paragraph={data.paragraph} />} | |||
| <Landing data={cnt.landing.heading} /> | |||
| {/* Why Us Section */} | |||
| {data && <WhySection heading={data.WhyUsHeading} cards={data.Cards} p1={data.WhyUsParagraph1} p2={data.WhyUsParagraph2} />} | |||
| <WhySection data={cnt.why} /> | |||
| {/* Our Services Section */} | |||
| {/* <ServicesHome /> */} | |||
| @@ -13,7 +13,8 @@ import CardsGrid from '../components/CardsGrid'; | |||
| import PageLayout from '../layout/PageLayout'; | |||
| import StrataThumb from './../assets/images/CaseStudy/StrataThumb.jpg'; | |||
| //import useAnalytics from '../hooks/useAnalytics'; | |||
| import useAnalytics from '../hooks/useAnalytics'; | |||
| import ReactHelmet from '../components/shared/ReactHelmet'; | |||
| const _data = { | |||
| heading: { | |||
| @@ -73,16 +74,46 @@ const _data = { | |||
| ], | |||
| }; | |||
| const api_url = process.env.REACT_APP_API_URL; | |||
| export default function Portfolio() { | |||
| const [cnt, setCnt] = useState(''); | |||
| const [isLoaded, setIsLoaded] = useState(''); | |||
| useEffect(() => { | |||
| useEffect(async () => { | |||
| document.title = 'Case Studies'; | |||
| var vid = document.getElementById('animation'); | |||
| vid.playbackRate = 2; | |||
| await axios | |||
| .get( | |||
| `${api_url}/api/portfoliopage?populate[0]=SEO&populate[1]=SEO.metaSocial&populate[2]=SEO.metaImage&populate[3]=SEO.metaSocial.image`, | |||
| ) | |||
| .then(res => { | |||
| setCnt(res.data.data.attributes); | |||
| setIsLoaded(true); | |||
| }) | |||
| .catch(err => { | |||
| console.log(err); | |||
| setIsLoaded(false); | |||
| }); | |||
| }, []); | |||
| //useAnalytics(); | |||
| useAnalytics('Case Studies'); | |||
| 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> | |||
| ); | |||
| } | |||
| return ( | |||
| <PageLayout> | |||
| {cnt.SEO && <ReactHelmet seo={cnt.SEO} />} | |||
| <div className="flex flex-col gap-90p pt-32"> | |||
| <Wrapper> | |||
| <h1 className="hidden">Our Work - Case Studies</h1> | |||
| @@ -16,7 +16,7 @@ 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'; | |||
| import useAnalytics from '../hooks/useAnalytics'; | |||
| const _data = { | |||
| heading: { | |||
| @@ -115,14 +115,13 @@ const _data = { | |||
| 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.', | |||
| 'Grow faster with a dedicated team of .NET & JS experts.', | |||
| primaryBtn: 'Contact Us', | |||
| secondaryBtn: 'Portfolio', | |||
| }, | |||
| }; | |||
| const ProcessPage = () => { | |||
| const [isMobile, setIsMobile] = useState(false); | |||
| const windowInfo = useWindowSize(); | |||
| @@ -131,14 +130,12 @@ const ProcessPage = () => { | |||
| document.title = 'Process'; | |||
| }, []); | |||
| //useAnalytics(); | |||
| useAnalytics('Process'); | |||
| useEffect(() => { | |||
| if (windowInfo.width < 1000) | |||
| setIsMobile(true); | |||
| else | |||
| setIsMobile(false); | |||
| },[windowInfo]); | |||
| if (windowInfo.width < 1000) setIsMobile(true); | |||
| else setIsMobile(false); | |||
| }, [windowInfo]); | |||
| return ( | |||
| <PageLayout> | |||
| @@ -160,7 +157,7 @@ const ProcessPage = () => { | |||
| </div> */} | |||
| <div className="relative mx-auto my-32p md:my-90p"> | |||
| {!isMobile ? ( | |||
| <div className="w-full"> | |||
| <div className="flex w-full"> | |||
| <ProcessSvg className="" /> | |||
| </div> | |||
| ) : ( | |||
| @@ -1,219 +1,277 @@ | |||
| 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' | |||
| import React, { Children, Fragment, useEffect } from 'react'; | |||
| import CustomLink from '../components/root/CustomLink'; | |||
| import ActionCard from '../components/shared/ActionCard'; | |||
| 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.' | |||
| } | |||
| ] | |||
| import useDataApi from '../hooks/useDataApi'; | |||
| import Animation_Diligent from '../assets/animation_diligent.webm'; | |||
| import Wrapper from '../layout/Wrapper'; | |||
| import PageLayout from '../layout/PageLayout'; | |||
| import PageTitleOneFont from '../components/shared/PageTitleOneFont'; | |||
| import GradientWrapper from '../components/shared/GradientWrapper'; | |||
| import '../App.css'; | |||
| import useAnalytics from './../hooks/useAnalytics'; | |||
| const api_url = process.env.REACT_APP_API_URL; | |||
| const download = { | |||
| downloadFilePath: `${process.env.PUBLIC_URL}/DiligentCompanyOverview.pdf`, | |||
| downloadFileName: 'Diligent Company Overview.pdf', | |||
| }; | |||
| const Segment = ({children}) => { | |||
| return ( | |||
| <div className='py-[48px] mx-auto w-full text-center'> | |||
| {children} | |||
| </div> | |||
| ); | |||
| } | |||
| const strapiPopulate = [ | |||
| 'Heading', | |||
| 'Heading.subtitle', | |||
| 'Heading.title', | |||
| 'Problems', | |||
| 'Highlighted', | |||
| 'Highlighted.title', | |||
| 'Highlighted.paragraph', | |||
| 'WhyWork', | |||
| 'WhyWork.img', | |||
| 'Stats', | |||
| 'SucessParagraph', | |||
| 'Spec', | |||
| 'Download', | |||
| 'OfficeImg', | |||
| 'WorkTogether', | |||
| ]; | |||
| 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}) => { | |||
| const stringBuilder = () => { | |||
| let stringQuery = ''; | |||
| strapiPopulate.map((item, index) => { | |||
| if (index !== 0) stringQuery += '&'; | |||
| stringQuery += `populate=${item}`; | |||
| }); | |||
| return stringQuery; | |||
| }; | |||
| const NumberIcon = ({ number }) => { | |||
| return ( | |||
| <div> | |||
| <h4 className='font-semibold text-title'>{title}</h4> | |||
| <p>{paragraph}</p> | |||
| <div className="bg-baby-blue rounded-[6px] h-[48px] w-[48px] flex justify-center items-center text-center font-semibold text-dg-primary-900 text-n-h3-heading-mobile md:n-h3-heading"> | |||
| <h4>{number}.</h4> | |||
| </div> | |||
| ) | |||
| } | |||
| ); | |||
| }; | |||
| const WorkWithUs = () => { | |||
| //useAnalytics(); | |||
| useAnalytics('Work With Us'); | |||
| const [{ data, isLoading, isError }, doFetch] = useDataApi( | |||
| `${api_url}/api/work-with-us-page?${stringBuilder()}`, | |||
| ); | |||
| 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} | |||
| /> | |||
| if (isLoading) { | |||
| return ( | |||
| <div className="z-50 w-full h-screen bg-white dark:bg-dg-primary-1700 overflow-hidden 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> | |||
| ); | |||
| } else { | |||
| return ( | |||
| <PageLayout> | |||
| <div className="mt-[48px] md:mt-[180px]"> | |||
| <Wrapper padding={' py-[48px]'}> | |||
| {data ? ( | |||
| <Fragment> | |||
| <PageTitleOneFont | |||
| heading={data.Heading.title} | |||
| subheading={data.Heading.subtitle} | |||
| left | |||
| /> | |||
| <p className="mt-[16px] mr-0 md:mr-[400px] n-paragraph"> | |||
| {data.HeadingParagraph} | |||
| </p> | |||
| </Fragment> | |||
| ) : null} | |||
| </Wrapper> | |||
| <div className="mx-auto md:mx-2/5 pb-90p"> | |||
| <Wrapper padding={' md:py-[48px]'}> | |||
| {data ? ( | |||
| <h2 className="n-h3-heading md:text-center">{data.ProblemsTitle}</h2> | |||
| ) : null} | |||
| </Wrapper> | |||
| <Wrapper padding={' py-[48px]'}> | |||
| {data ? ( | |||
| <div className="flex flex-col gap-90p max-w-[860px] mx-auto"> | |||
| {data.Problems.map((item, index) => ( | |||
| <div key={index} className="flex flex-col md:flex-row gap-[32px]"> | |||
| <div> | |||
| <NumberIcon number={index + 1} /> | |||
| </div> | |||
| <div className="flex flex-col gap-[4px]"> | |||
| <h6 className="n-paragraph-title">{item.title}</h6> | |||
| <p className="n-paragraph">{item.paragraph}</p> | |||
| </div> | |||
| </div> | |||
| ))} | |||
| </div> | |||
| ) : null} | |||
| </Wrapper> | |||
| </div> | |||
| {data ? ( | |||
| <GradientWrapper padding={'py-32p md:py-90p'}> | |||
| <h6 className="n-h3-heading text-white">{data.Highlighted.title}</h6> | |||
| <p className="n-paragraph text-white md:max-w-[800px] mx-0 md:mx-auto"> | |||
| {data.Highlighted.paragraph} | |||
| </p> | |||
| </GradientWrapper> | |||
| ) : null} | |||
| {data ? ( | |||
| <Wrapper padding={' py-[32px] md:py-[200px]'}> | |||
| <div className="flex flex-col gap-[64px] md:gap-[120px]"> | |||
| {data.WhyWork.map((item, index) => ( | |||
| <div | |||
| key={index} | |||
| className={ | |||
| (index % 2 | |||
| ? 'flex flex-col md:flex-row-reverse ' | |||
| : 'flex flex-col md:flex-row ') + | |||
| 'w-full justify-between items-center gap-[24px] md:gap-0' | |||
| } | |||
| > | |||
| <div> | |||
| <img src={api_url + item.img.data.attributes.url}></img> | |||
| </div> | |||
| <div className="flex flex-col gap-[8px] md:gap-[16px] max-w-[520px]"> | |||
| <h6 className="n-h3-heading text-dark-gray">{item.title}</h6> | |||
| <p className="n-paragraph">{item.paragraph}</p> | |||
| </div> | |||
| </div> | |||
| ))} | |||
| </div> | |||
| </Wrapper> | |||
| ) : null} | |||
| {data ? ( | |||
| <GradientWrapper padding={'py-32p md:py-90p'}> | |||
| <div className="max-w-custom flex flex-col md:flex-row md:justify-between gap-[64px] md:gap-0"> | |||
| {data.Stats.map((item, index) => ( | |||
| <div key={index} className="flex flex-col gap-[8px] text-center"> | |||
| <h6 className="n-heading text-white">{item.value}</h6> | |||
| <p className="n-paragraph-title text-white">{item.title}</p> | |||
| </div> | |||
| ))} | |||
| </div> | |||
| </GradientWrapper> | |||
| ) : null} | |||
| <Wrapper padding={' py-[48px] md:py-[200px]'}> | |||
| {data ? ( | |||
| <div className="flex flex-col gap-[16px]"> | |||
| <h6 className="n-h3-heading text-dark-gray">{data.SuccessTitle}</h6> | |||
| {data.SucessParagraph.map((item, index) => ( | |||
| <p key={index} className="n-paragraph"> | |||
| {item.ParagraphElement} | |||
| </p> | |||
| ))} | |||
| </div> | |||
| ) : null} | |||
| </Wrapper> | |||
| <div className="mx-auto md:mx-2/5 pb-90p"> | |||
| <Wrapper padding={' md:py-[48px]'}> | |||
| {data ? ( | |||
| <h6 className="n-h3-heading md:text-center text-dark-gray"> | |||
| {data.SpecTitle} | |||
| </h6> | |||
| ) : null} | |||
| </Wrapper> | |||
| <Wrapper padding={' py-[48px]'}> | |||
| {data ? ( | |||
| <div className="flex flex-col sm:flex-row gap-[48px] mx-auto justify-center z-10 opacity-100 font-semibold"> | |||
| <div className="flex flex-col gap-32p sm:mb-8"> | |||
| <div className="bg-white py-32p px-[24px] rounded-[8px] text-center shadow-[0_3px_10px_rgb(0,0,0,0.2)]"> | |||
| {data.Spec[0].title} | |||
| </div> | |||
| <div className="bg-white py-32p px-[24px] rounded-[8px] text-center shadow-[0_3px_10px_rgb(0,0,0,0.2)]"> | |||
| {data.Spec[1].title} | |||
| </div> | |||
| <div className="bg-white py-32p px-[24px] rounded-[8px] text-center shadow-[0_3px_10px_rgb(0,0,0,0.2)]"> | |||
| {data.Spec[2].title} | |||
| </div> | |||
| </div> | |||
| <div className="flex flex-col gap-32p sm:mt-8"> | |||
| <div className="bg-white py-32p px-[24px] rounded-[8px] text-center shadow-[0_3px_10px_rgb(0,0,0,0.2)]"> | |||
| {data.Spec[3].title} | |||
| </div> | |||
| <div className="bg-white py-32p px-[24px] rounded-[8px] text-center shadow-[0_3px_10px_rgb(0,0,0,0.2)]"> | |||
| {data.Spec[4].title} | |||
| </div> | |||
| <div className="bg-white py-32p px-[24px] rounded-[8px] text-center shadow-[0_3px_10px_rgb(0,0,0,0.2)]"> | |||
| {data.Spec[5].title} | |||
| </div> | |||
| </div> | |||
| <div className="flex flex-col gap-32p sm:mb-8"> | |||
| <div className="bg-white py-32p px-[24px] rounded-[8px] text-center shadow-[0_3px_10px_rgb(0,0,0,0.2)]"> | |||
| {data.Spec[6].title} | |||
| </div> | |||
| <div className="bg-white py-32p px-[24px] rounded-[8px] text-center shadow-[0_3px_10px_rgb(0,0,0,0.2)]"> | |||
| {data.Spec[7].title} | |||
| </div> | |||
| <div className="bg-white py-32p px-[24px] rounded-[8px] text-center shadow-[0_3px_10px_rgb(0,0,0,0.2)]"> | |||
| {data.Spec[8].title} | |||
| </div> | |||
| </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} | |||
| /> | |||
| ))} | |||
| ) : null} | |||
| <div className="flex absolute w-full top-0 z-[-1]"> | |||
| <div className="w-[624px] h-[624px] bg-indigo-500 opacity-25 rounded-full mx-auto blur-[100px]"></div> | |||
| </div> | |||
| </Wrapper> | |||
| </div> | |||
| {data ? ( | |||
| <div className="md:mb-[200px]"> | |||
| <div className="w-full relative mt-12 z-[-1]"> | |||
| <div className="radial-gradient absolute top-0 left-0 right-0 bottom-0"></div> | |||
| <div className="max-w-custom mx-auto"> | |||
| <img | |||
| src={api_url + data.OfficeImg.data.attributes.url} | |||
| alt={data.OfficeImgAlt} | |||
| ></img> | |||
| </div> | |||
| </div> | |||
| <div className="max-w-[600px] mx-[16px] md:mx-auto md:mt-[-320px] p-[24px] flex flex-col gap-[24px] z-20 bg-white rounded-[16px] shadow-[0_3px_10px_rgb(0,0,0,0.2)] md:shadow-none"> | |||
| <div className="flex flex-col gap-[8px]"> | |||
| <h6 className="n-h3-heading text-dark-gray font-bold"> | |||
| {data.Download.title} | |||
| </h6> | |||
| <p className="n-paragraph">{data.Download.paragraph}</p> | |||
| </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> | |||
| <CustomLink | |||
| href={download.downloadFilePath} | |||
| downloadFile={download.downloadFileName} | |||
| context={'Company Overview'} | |||
| > | |||
| <p>{data.Download.button}</p> | |||
| </CustomLink> | |||
| </div> | |||
| </div> | |||
| ) : null} | |||
| {data ? ( | |||
| <Wrapper padding={' py-90p'}> | |||
| <ActionCard | |||
| title={data.WorkTogether.title} | |||
| text={data.WorkTogether.paragraph} | |||
| btn2={data.WorkTogether.ButtonSecondary} | |||
| btn1={data.WorkTogether.ButtonPrimary} | |||
| link2={'/portfolio'} | |||
| link1={'/contact'} | |||
| /> | |||
| </Wrapper> | |||
| ) : null} | |||
| </div> | |||
| ) | |||
| } | |||
| </div> | |||
| </PageLayout> | |||
| ); | |||
| } | |||
| }; | |||
| export default WorkWithUs | |||
| export default WorkWithUs; | |||
| @@ -21,11 +21,11 @@ | |||
| } | |||
| .btn-primary { | |||
| @apply px-64p py-20p text-center | |||
| @apply px-32p py-20p sm:px-64p text-center | |||
| text-btn uppercase font-semibold rounded-16 border-transparent cursor-pointer bg-gradient-to-r from-dg-secondary to-dg-primary-900 transition-all hover:bg-gradient-to-r hover:to-dg-secondary hover:from-dg-primary-900 hover:transition-all text-white; | |||
| } | |||
| .btn-secondary { | |||
| @apply px-64p py-20p text-center | |||
| @apply px-32p py-20p sm:px-64p text-center | |||
| text-btn uppercase font-semibold rounded-16 cursor-pointer border-2 border-dg-primary-400 transition-all hover:transition-all text-dg-primary-900; | |||
| } | |||
| .contact-us-link { | |||
| @@ -4,7 +4,7 @@ | |||
| @layer components { | |||
| .heading { | |||
| @apply font-primary text-dark-gray dark:text-white text-head-mobile md:text-head; | |||
| @apply font-secondary font-bold text-dark-gray dark:text-white text-n-head-mobile md:text-n-head; | |||
| } | |||
| .subheading { | |||
| @@ -43,6 +43,22 @@ | |||
| .title-italic { | |||
| @apply text-italic-title text-dg-primary-400 font-semibold italic my-8p capitalize; | |||
| } | |||
| .n-heading { | |||
| @apply font-secondary font-bold text-dark-gray dark:text-white text-n-head-mobile md:text-n-head; | |||
| } | |||
| .n-subheading{ | |||
| @apply text-n-subhead-mobile md:text-n-subhead font-secondary uppercase text-dg-secondary font-semibold; | |||
| } | |||
| .n-h3-heading{ | |||
| @apply text-n-h3-heading-mobile md:text-n-h3-heading font-secondary text-dg-primary-900 font-bold; | |||
| } | |||
| .n-paragraph { | |||
| @apply text-n-paragraph-mobile md:text-n-paragraph font-secondary text-dark-gray font-normal | |||
| } | |||
| .n-paragraph-title { | |||
| @apply text-n-paragraph-title-mobile md:text-n-paragraph-title font-secondary text-dark-gray font-semibold | |||
| } | |||
| } | |||
| .no-wrap { | |||
| @@ -0,0 +1,13 @@ | |||
| const api_url = process.env.REACT_APP_API_URL; | |||
| export const strapiApiBuilder = (page, stringArray) => { | |||
| const api = `${api_url}/api/${page}`; | |||
| let query = ''; | |||
| stringArray.map((field, index) => { | |||
| if (index === 0) query += `?populate[${index}]=${field}`; | |||
| else { | |||
| query += `&populate[${index}]=${field}`; | |||
| } | |||
| }); | |||
| return api + query; | |||
| }; | |||
| @@ -3,8 +3,8 @@ module.exports = { | |||
| darkMode: 'class', | |||
| theme: { | |||
| fontFamily: { | |||
| 'primary' : ['"Abril Fatface"','serif'], | |||
| 'secondary' : ['"Poppins"', 'sans-serif'], | |||
| primary: ['"Abril Fatface"', 'serif'], | |||
| secondary: ['"Poppins"', 'sans-serif'], | |||
| }, | |||
| fontSize: { | |||
| 'head' : ['56px', { | |||
| @@ -74,17 +74,83 @@ module.exports = { | |||
| 'subtitle-48' : ['48px', { | |||
| letterSpacing: '0px', | |||
| lineHeight: 'normal' | |||
| }] | |||
| }], | |||
| // | |||
| 'n-head' : ['54.00px', { | |||
| letterSpacing: '-0.6%', | |||
| lineHeight: '125%', | |||
| }], | |||
| 'n-subhead' : ['16px', { | |||
| letterSpacing: '1.5px', | |||
| lineHeight: '24px', | |||
| }], | |||
| 'n-head-mobile' : ['24px', { | |||
| letterSpacing: '-0.6%', | |||
| lineHeight: '32px', | |||
| }], | |||
| 'n-subhead-mobile' : ['10.5px', { | |||
| letterSpacing: '1.5px', | |||
| lineHeight: '28px', | |||
| }], | |||
| 'n-paragraph' : ['16px', { | |||
| letterSpacing: '0%', | |||
| lineHeight: '28px', | |||
| }], | |||
| 'n-paragraph-mobile' : ['14px', { | |||
| letterSpacing: '0%', | |||
| lineHeight: '24px', | |||
| }], | |||
| 'n-h3-heading' : ['24px', { | |||
| letterSpacing: '-0.6%', | |||
| lineHeight: '32px', | |||
| }], | |||
| 'n-h3-heading-mobile' : ['18.66px', { | |||
| letterSpacing: '0%', | |||
| lineHeight: '24px', | |||
| }], | |||
| 'n-paragraph-title-mobile' : ['14px', { | |||
| letterSpacing: '0%', | |||
| lineHeight: '24px', | |||
| }], | |||
| 'n-paragraph-title' : ['18px', { | |||
| letterSpacing: '0%', | |||
| lineHeight: 'normal', | |||
| }], | |||
| 'banner-mobile': [ | |||
| '18.66px', | |||
| { | |||
| letterSpacing: '0px', | |||
| lineHeight: '24px', | |||
| }, | |||
| ], | |||
| 'banner-p': [ | |||
| '14px', | |||
| { | |||
| letterSpacing: '0px', | |||
| lineHeight: '21px', | |||
| }, | |||
| ], | |||
| 'banner-p-mobile': [ | |||
| '12px', | |||
| { | |||
| letterSpacing: '0px', | |||
| lineHeight: '18px', | |||
| }, | |||
| ], | |||
| }, | |||
| minHeight: { | |||
| '12': '3rem', | |||
| 12: '3rem', | |||
| }, | |||
| maxWidth: { | |||
| '780p':'780px', | |||
| 'wrapper': '1150px', | |||
| 'custom': '1150px', | |||
| 'dropzone': '110px', | |||
| '780p': '780px', | |||
| wrapper: '1150px', | |||
| custom: '1150px', | |||
| dropzone: '110px', | |||
| banner: '1118px', | |||
| banner_m: '309px', | |||
| }, | |||
| transitionDuration: { | |||
| DEFAULT: '300ms', | |||
| @@ -97,6 +163,7 @@ module.exports = { | |||
| 'baby-blue': '#f0f3f9', | |||
| 'dg-primary': { | |||
| 50: '#f4e9f4', | |||
| 75: '#fafafa', | |||
| 100: '#e9d4e9', | |||
| 200: '#debedd', | |||
| 300: '#d3a9d2', | |||
| @@ -121,29 +188,32 @@ module.exports = { | |||
| black: '#000000', | |||
| }, | |||
| spacing: { | |||
| '2p': "2px", | |||
| '4p':'4px', | |||
| '2p': '2px', | |||
| '4p': '4px', | |||
| '8p': '8px', | |||
| '12p':'12px', | |||
| '12p': '12px', | |||
| '15p': '15px', | |||
| '16p': '16px', | |||
| '20p':'20px', | |||
| '32p':'32px', | |||
| '48p':'48px', | |||
| '64p':'64px', | |||
| '72p':'72px', | |||
| '90p':'90px', | |||
| '140p':'140px', | |||
| '20p': '20px', | |||
| '32p': '32px', | |||
| '42p': '42px', | |||
| '48p': '48px', | |||
| '64p': '64px', | |||
| '72p': '72px', | |||
| '90p': '90px', | |||
| '140p': '140px', | |||
| '164p': '164px', | |||
| '200p': '200px', | |||
| '240p':'240px' | |||
| '240p': '240px', | |||
| }, | |||
| borderRadius: { | |||
| '8': '8px', | |||
| '16': '16px', | |||
| '32' : '32px' | |||
| } | |||
| 8: '8px', | |||
| 16: '16px', | |||
| 32: '32px', | |||
| }, | |||
| boxShadow: { | |||
| custom: '0 0px 9px 9px rgba(0, 0, 0, 0.09)', | |||
| }, | |||
| }, | |||
| }, | |||
| plugins: [ | |||
| @@ -1791,6 +1791,11 @@ | |||
| dependencies: | |||
| "@types/node" "*" | |||
| "@types/cookie@^0.3.3": | |||
| "integrity" "sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow==" | |||
| "resolved" "https://registry.npmjs.org/@types/cookie/-/cookie-0.3.3.tgz" | |||
| "version" "0.3.3" | |||
| "@types/debug@^4.0.0": | |||
| "integrity" "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==" | |||
| "resolved" "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz" | |||
| @@ -1862,6 +1867,14 @@ | |||
| dependencies: | |||
| "@types/unist" "*" | |||
| "@types/hoist-non-react-statics@^3.0.1": | |||
| "integrity" "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==" | |||
| "resolved" "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz" | |||
| "version" "3.3.1" | |||
| dependencies: | |||
| "@types/react" "*" | |||
| "hoist-non-react-statics" "^3.3.0" | |||
| "@types/html-minifier-terser@^6.0.0": | |||
| "integrity" "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" | |||
| "resolved" "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz" | |||
| @@ -1973,7 +1986,7 @@ | |||
| "resolved" "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz" | |||
| "version" "1.2.4" | |||
| "@types/react@>=16": | |||
| "@types/react@*", "@types/react@>=16": | |||
| "integrity" "sha512-7QUCOxvFgnD5Jk8ZKlUAhVcRj7GuJRjnjjiY/IUBWKgOlnvDvTMLD4RTF7NPyVmbRhNrbomZiOepg7M/2Kj1mA==" | |||
| "resolved" "https://registry.npmjs.org/@types/react/-/react-18.0.21.tgz" | |||
| "version" "18.0.21" | |||
| @@ -2643,6 +2656,14 @@ | |||
| dependencies: | |||
| "follow-redirects" "^1.14.8" | |||
| "axios@^0.27.2": | |||
| "integrity" "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==" | |||
| "resolved" "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz" | |||
| "version" "0.27.2" | |||
| dependencies: | |||
| "follow-redirects" "^1.14.9" | |||
| "form-data" "^4.0.0" | |||
| "axobject-query@^2.2.0": | |||
| "integrity" "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==" | |||
| "resolved" "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz" | |||
| @@ -2835,6 +2856,11 @@ | |||
| "resolved" "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" | |||
| "version" "1.0.2" | |||
| "base-64@^1.0.0": | |||
| "integrity" "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==" | |||
| "resolved" "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz" | |||
| "version" "1.0.0" | |||
| "batch@0.6.1": | |||
| "integrity" "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=" | |||
| "resolved" "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz" | |||
| @@ -3297,7 +3323,7 @@ | |||
| "resolved" "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" | |||
| "version" "1.0.6" | |||
| "cookie@0.4.1": | |||
| "cookie@^0.4.0", "cookie@0.4.1": | |||
| "integrity" "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" | |||
| "resolved" "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz" | |||
| "version" "0.4.1" | |||
| @@ -4645,10 +4671,10 @@ | |||
| "resolved" "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz" | |||
| "version" "3.2.4" | |||
| "follow-redirects@^1.0.0", "follow-redirects@^1.14.8": | |||
| "integrity" "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==" | |||
| "resolved" "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz" | |||
| "version" "1.14.8" | |||
| "follow-redirects@^1.0.0", "follow-redirects@^1.14.8", "follow-redirects@^1.14.9": | |||
| "integrity" "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" | |||
| "resolved" "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz" | |||
| "version" "1.15.2" | |||
| "fork-ts-checker-webpack-plugin@^6.5.0": | |||
| "integrity" "sha512-cS178Y+xxtIjEUorcHddKS7yCMlrDPV31mt47blKKRfMd70Kxu5xruAFE2o9sDY6wVC5deuob/u/alD04YYHnw==" | |||
| @@ -4678,6 +4704,15 @@ | |||
| "combined-stream" "^1.0.8" | |||
| "mime-types" "^2.1.12" | |||
| "form-data@^4.0.0": | |||
| "integrity" "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==" | |||
| "resolved" "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz" | |||
| "version" "4.0.0" | |||
| dependencies: | |||
| "asynckit" "^0.4.0" | |||
| "combined-stream" "^1.0.8" | |||
| "mime-types" "^2.1.12" | |||
| "formik@^2.2.9": | |||
| "integrity" "sha512-LQLcISMmf1r5at4/gyJigGn0gOwFbeEAlji+N9InZF6LIMXnFNkO42sCI8Jt84YZggpD4cPWObAZaxpEFtSzNA==" | |||
| "resolved" "https://registry.npmjs.org/formik/-/formik-2.2.9.tgz" | |||
| @@ -5241,7 +5276,7 @@ | |||
| "resolved" "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz" | |||
| "version" "2.2.0" | |||
| "invariant@2.2.4": | |||
| "invariant@^2.2.4", "invariant@2.2.4": | |||
| "integrity" "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==" | |||
| "resolved" "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz" | |||
| "version" "2.2.4" | |||
| @@ -6292,6 +6327,15 @@ | |||
| dependencies: | |||
| "sourcemap-codec" "^1.4.4" | |||
| "mailgun.js@^8.0.6": | |||
| "integrity" "sha512-b+c7QO1T4oFsudEcRB2H7oZKth8ZDeYRW4xjW12QQVNYDSJCVxqSQfps6ofcH8fqcCMJdzc76HVNGdnUZgBPCw==" | |||
| "resolved" "https://registry.npmjs.org/mailgun.js/-/mailgun.js-8.0.6.tgz" | |||
| "version" "8.0.6" | |||
| dependencies: | |||
| "axios" "^0.27.2" | |||
| "base-64" "^1.0.0" | |||
| "url-join" "^4.0.1" | |||
| "make-dir@^3.0.0", "make-dir@^3.0.2", "make-dir@^3.1.0": | |||
| "integrity" "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==" | |||
| "resolved" "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz" | |||
| @@ -7726,7 +7770,7 @@ | |||
| "kleur" "^3.0.3" | |||
| "sisteransi" "^1.0.5" | |||
| "prop-types@^15.0.0", "prop-types@^15.5.10", "prop-types@^15.7.2", "prop-types@^15.8.1": | |||
| "prop-types@^15.0.0", "prop-types@^15.5.0", "prop-types@^15.5.10", "prop-types@^15.6.0", "prop-types@^15.7.2", "prop-types@^15.8.1": | |||
| "integrity" "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==" | |||
| "resolved" "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" | |||
| "version" "15.8.1" | |||
| @@ -7824,6 +7868,23 @@ | |||
| "regenerator-runtime" "^0.13.9" | |||
| "whatwg-fetch" "^3.6.2" | |||
| "react-async-script@^1.1.1": | |||
| "integrity" "sha512-bCpkbm9JiAuMGhkqoAiC0lLkb40DJ0HOEJIku+9JDjxX3Rcs+ztEOG13wbrOskt3n2DTrjshhaQ/iay+SnGg5Q==" | |||
| "resolved" "https://registry.npmjs.org/react-async-script/-/react-async-script-1.2.0.tgz" | |||
| "version" "1.2.0" | |||
| dependencies: | |||
| "hoist-non-react-statics" "^3.3.0" | |||
| "prop-types" "^15.5.0" | |||
| "react-cookie@^4.1.1": | |||
| "integrity" "sha512-ffn7Y7G4bXiFbnE+dKhHhbP+b8I34mH9jqnm8Llhj89zF4nPxPutxHT1suUqMeCEhLDBI7InYwf1tpaSoK5w8A==" | |||
| "resolved" "https://registry.npmjs.org/react-cookie/-/react-cookie-4.1.1.tgz" | |||
| "version" "4.1.1" | |||
| dependencies: | |||
| "@types/hoist-non-react-statics" "^3.0.1" | |||
| "hoist-non-react-statics" "^3.0.0" | |||
| "universal-cookie" "^4.0.0" | |||
| "react-dev-utils@^12.0.0": | |||
| "integrity" "sha512-xBQkitdxozPxt1YZ9O1097EJiVpwHr9FoAuEVURCKV0Av8NBERovJauzP7bo1ThvuhZ4shsQ1AJiu4vQpoT1AQ==" | |||
| "resolved" "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.0.tgz" | |||
| @@ -7854,7 +7915,7 @@ | |||
| "strip-ansi" "^6.0.1" | |||
| "text-table" "^0.2.0" | |||
| "react-dom@*", "react-dom@^16 || ^17 || ^18", "react-dom@^16.8 || ^17 || ^18", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^17.0.2", "react-dom@>= 16.8.0", "react-dom@>=16.8", "react-dom@>=16.8 || ^17.0.0 || ^18.0.0": | |||
| "react-dom@*", "react-dom@^16 || ^17 || ^18", "react-dom@^16.6.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8 || ^17 || ^18", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^17.0.2", "react-dom@>= 16.8.0", "react-dom@>=16.8", "react-dom@>=16.8 || ^17.0.0 || ^18.0.0": | |||
| "integrity" "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==" | |||
| "resolved" "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz" | |||
| "version" "17.0.2" | |||
| @@ -7882,6 +7943,40 @@ | |||
| "resolved" "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz" | |||
| "version" "2.0.4" | |||
| "react-fast-compare@^3.2.0": | |||
| "integrity" "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" | |||
| "resolved" "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz" | |||
| "version" "3.2.0" | |||
| "react-ga@^3.3.1": | |||
| "integrity" "sha512-4Vc0W5EvXAXUN/wWyxvsAKDLLgtJ3oLmhYYssx+YzphJpejtOst6cbIHCIyF50Fdxuf5DDKqRYny24yJ2y7GFQ==" | |||
| "resolved" "https://registry.npmjs.org/react-ga/-/react-ga-3.3.1.tgz" | |||
| "version" "3.3.1" | |||
| "react-ga4@^1.4.1": | |||
| "integrity" "sha512-ioBMEIxd4ePw4YtaloTUgqhQGqz5ebDdC4slEpLgy2sLx1LuZBC9iYCwDymTXzcntw6K1dHX183ulP32nNdG7w==" | |||
| "resolved" "https://registry.npmjs.org/react-ga4/-/react-ga4-1.4.1.tgz" | |||
| "version" "1.4.1" | |||
| "react-google-recaptcha@^2.1.0": | |||
| "integrity" "sha512-K9jr7e0CWFigi8KxC3WPvNqZZ47df2RrMAta6KmRoE4RUi7Ys6NmNjytpXpg4HI/svmQJLKR+PncEPaNJ98DqQ==" | |||
| "resolved" "https://registry.npmjs.org/react-google-recaptcha/-/react-google-recaptcha-2.1.0.tgz" | |||
| "version" "2.1.0" | |||
| dependencies: | |||
| "prop-types" "^15.5.0" | |||
| "react-async-script" "^1.1.1" | |||
| "react-helmet-async@^1.3.0": | |||
| "integrity" "sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==" | |||
| "resolved" "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz" | |||
| "version" "1.3.0" | |||
| dependencies: | |||
| "@babel/runtime" "^7.12.5" | |||
| "invariant" "^2.2.4" | |||
| "prop-types" "^15.7.2" | |||
| "react-fast-compare" "^3.2.0" | |||
| "shallowequal" "^1.1.0" | |||
| "react-is@^16.13.1", "react-is@^16.7.0", "react-is@>= 16.8.0": | |||
| "integrity" "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" | |||
| "resolved" "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" | |||
| @@ -8001,7 +8096,7 @@ | |||
| optionalDependencies: | |||
| "fsevents" "^2.3.2" | |||
| "react@*", "react@^16 || ^17 || ^18", "react@^16.8 || ^17 || ^18", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^17.0.2", "react@>= 16", "react@>= 16.8", "react@>= 16.8.0", "react@>=15", "react@>=16", "react@>=16.8", "react@>=16.8 || ^17.0.0 || ^18.0.0", "react@>=16.8.0", "react@17.0.2": | |||
| "react@*", "react@^15.6.2 || ^16.0 || ^17 || ^18", "react@^16 || ^17 || ^18", "react@^16.6.0 || ^17.0.0 || ^18.0.0", "react@^16.8 || ^17 || ^18", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^17.0.2", "react@>= 16", "react@>= 16.3.0", "react@>= 16.8", "react@>= 16.8.0", "react@>=15", "react@>=16", "react@>=16.4.1", "react@>=16.8", "react@>=16.8 || ^17.0.0 || ^18.0.0", "react@>=16.8.0", "react@17.0.2": | |||
| "integrity" "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==" | |||
| "resolved" "https://registry.npmjs.org/react/-/react-17.0.2.tgz" | |||
| "version" "17.0.2" | |||
| @@ -9338,6 +9433,14 @@ | |||
| "unist-util-is" "^5.0.0" | |||
| "unist-util-visit-parents" "^5.0.0" | |||
| "universal-cookie@^4.0.0": | |||
| "integrity" "sha512-lbRVHoOMtItjWbM7TwDLdl8wug7izB0tq3/YVKhT/ahB4VDvWMyvnADfnJI8y6fSvsjh51Ix7lTGC6Tn4rMPhw==" | |||
| "resolved" "https://registry.npmjs.org/universal-cookie/-/universal-cookie-4.0.4.tgz" | |||
| "version" "4.0.4" | |||
| dependencies: | |||
| "@types/cookie" "^0.3.3" | |||
| "cookie" "^0.4.0" | |||
| "universalify@^0.1.2": | |||
| "integrity" "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" | |||
| "resolved" "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz" | |||
| @@ -9370,6 +9473,11 @@ | |||
| dependencies: | |||
| "punycode" "^2.1.0" | |||
| "url-join@^4.0.1": | |||
| "integrity" "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" | |||
| "resolved" "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz" | |||
| "version" "4.0.1" | |||
| "util-deprecate@^1.0.1", "util-deprecate@^1.0.2", "util-deprecate@~1.0.1": | |||
| "integrity" "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" | |||
| "resolved" "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" | |||