diff --git a/package-lock.json b/package-lock.json index 65ced778448e2601bbacd882cf3c4d12eaf65ccd..f883b2a735ed8a37c3268d3b0adc0ade74f66ea3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,9 @@ "prism-react-renderer": "^1.3.5", "react": "^17.0.2", "react-dom": "^17.0.2", - "react-icons": "^4.7.1" + "react-icons": "^4.7.1", + "react-slick": "^0.29.0", + "slick-carousel": "^1.8.1" }, "devDependencies": { "@babel/eslint-parser": "^7.19.1", @@ -4739,6 +4741,11 @@ "node": ">=8" } }, + "node_modules/classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, "node_modules/clean-css": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz", @@ -5895,6 +5902,11 @@ "node": ">=10.13.0" } }, + "node_modules/enquire.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/enquire.js/-/enquire.js-2.1.6.tgz", + "integrity": "sha512-/KujNpO+PT63F7Hlpu4h3pE3TokKRHN26JYmQpPyjkRD/N57R7bPDNojMXdi7uveAKjYB7yQnartCxZnFWr0Xw==" + }, "node_modules/entities": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", @@ -8571,6 +8583,14 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/json2mq": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz", + "integrity": "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==", + "dependencies": { + "string-convert": "^0.2.0" + } + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -10818,6 +10838,22 @@ "react": ">=15" } }, + "node_modules/react-slick": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/react-slick/-/react-slick-0.29.0.tgz", + "integrity": "sha512-TGdOKE+ZkJHHeC4aaoH85m8RnFyWqdqRfAGkhd6dirmATXMZWAxOpTLmw2Ll/jPTQ3eEG7ercFr/sbzdeYCJXA==", + "dependencies": { + "classnames": "^2.2.5", + "enquire.js": "^2.1.6", + "json2mq": "^0.2.0", + "lodash.debounce": "^4.0.8", + "resize-observer-polyfill": "^1.5.0" + }, + "peerDependencies": { + "react": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-textarea-autosize": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.4.0.tgz", @@ -11304,6 +11340,11 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, + "node_modules/resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -11921,6 +11962,14 @@ "node": ">=8" } }, + "node_modules/slick-carousel": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/slick-carousel/-/slick-carousel-1.8.1.tgz", + "integrity": "sha512-XB9Ftrf2EEKfzoQXt3Nitrt/IPbT+f1fgqBdoxO3W/+JYvtEOW6EgxnWfr9GH6nmULv7Y2tPmEX3koxThVmebA==", + "peerDependencies": { + "jquery": ">=1.8.0" + } + }, "node_modules/sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -12042,6 +12091,11 @@ "safe-buffer": "~5.2.0" } }, + "node_modules/string-convert": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", + "integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==" + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -17295,6 +17349,11 @@ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.1.tgz", "integrity": "sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w==" }, + "classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, "clean-css": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz", @@ -18115,6 +18174,11 @@ "tapable": "^2.2.0" } }, + "enquire.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/enquire.js/-/enquire.js-2.1.6.tgz", + "integrity": "sha512-/KujNpO+PT63F7Hlpu4h3pE3TokKRHN26JYmQpPyjkRD/N57R7bPDNojMXdi7uveAKjYB7yQnartCxZnFWr0Xw==" + }, "entities": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", @@ -20044,6 +20108,14 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "json2mq": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz", + "integrity": "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==", + "requires": { + "string-convert": "^0.2.0" + } + }, "json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -21602,6 +21674,18 @@ "tiny-warning": "^1.0.0" } }, + "react-slick": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/react-slick/-/react-slick-0.29.0.tgz", + "integrity": "sha512-TGdOKE+ZkJHHeC4aaoH85m8RnFyWqdqRfAGkhd6dirmATXMZWAxOpTLmw2Ll/jPTQ3eEG7ercFr/sbzdeYCJXA==", + "requires": { + "classnames": "^2.2.5", + "enquire.js": "^2.1.6", + "json2mq": "^0.2.0", + "lodash.debounce": "^4.0.8", + "resize-observer-polyfill": "^1.5.0" + } + }, "react-textarea-autosize": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.4.0.tgz", @@ -21970,6 +22054,11 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, + "resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, "resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -22440,6 +22529,11 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, + "slick-carousel": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/slick-carousel/-/slick-carousel-1.8.1.tgz", + "integrity": "sha512-XB9Ftrf2EEKfzoQXt3Nitrt/IPbT+f1fgqBdoxO3W/+JYvtEOW6EgxnWfr9GH6nmULv7Y2tPmEX3koxThVmebA==" + }, "sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -22537,6 +22631,11 @@ "safe-buffer": "~5.2.0" } }, + "string-convert": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", + "integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==" + }, "string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", diff --git a/package.json b/package.json index 021e014b521dc384705fcea7eda1eb138680b06d..877706ac2eeeb779d9e6a194a6ecf9acf8930739 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,9 @@ "prism-react-renderer": "^1.3.5", "react": "^17.0.2", "react-dom": "^17.0.2", - "react-icons": "^4.7.1" + "react-icons": "^4.7.1", + "react-slick": "^0.29.0", + "slick-carousel": "^1.8.1" }, "devDependencies": { "@babel/eslint-parser": "^7.19.1", diff --git a/src/components/TestimoniesCarousel/index.js b/src/components/TestimoniesCarousel/index.js new file mode 100644 index 0000000000000000000000000000000000000000..72cf506df68490bedd745bdcde3e166d119513ca --- /dev/null +++ b/src/components/TestimoniesCarousel/index.js @@ -0,0 +1,55 @@ +import React from 'react'; +import Slider from "react-slick"; +import "slick-carousel/slick/slick.css"; +import "slick-carousel/slick/slick-theme.css"; +import Card from '../TestimonyCard' +import testimoniesList from '@site/static/testimoniesList.json' +import styles from './styles.module.css' + +function SampleNextArrow(props) { + const { onClick } = props; + return ( + <div + className={styles.arrow + ' ' + styles.right} + onClick={onClick} + /> + ); +} + +function SamplePrevArrow(props) { + const { onClick } = props; + return ( + <div + className={styles.arrow + ' ' + styles.left} + onClick={onClick} + /> + ) +} +export default function TestimoniesCarousel() { + // https://react-slick.neostack.com/docs/api/ + const settings = { + accessibility: true, + nextArrow: <SampleNextArrow />, + prevArrow: <SamplePrevArrow />, + infinite: false, + autoplay: true, + dots: true, + speed: 500, + centerMode: true, + slidesToShow: 1, + slidesToScroll: 1, + }; + + return ( + <section > + <div className={styles.section}> + <h2 className={styles.title}> Clients</h2> + <Slider {...settings}> + {testimoniesList.map((props, idx) => ( + <Card key={idx} {...props} /> + ))} + </Slider> + </div> + </section> + ); +} diff --git a/src/components/TestimoniesCarousel/styles.module.css b/src/components/TestimoniesCarousel/styles.module.css new file mode 100644 index 0000000000000000000000000000000000000000..d1a74394cb9b027ba9e15c86c211491f2a247fb5 --- /dev/null +++ b/src/components/TestimoniesCarousel/styles.module.css @@ -0,0 +1,55 @@ +.section { + max-width: 980px; + margin: auto; + margin-bottom: 2rem; +} + +.title { + text-align: center; + margin: 2rem auto +} + +.right { + right: 0; +} + +.left { + left: 0; +} + +.arrow { + z-index: 5; + cursor: pointer; + border: none; + width: 32px; + aspect-ratio: 1; + border-radius: 50%; + position: absolute; + top: 64px; + margin: 0 18px; + background-color: transparent; +} + +.left::after, .right::after { + opacity: 0.4; + content: ''; + position: absolute; + top: 50%; + left: 50%; + width: 12px; + height: 12px; + border: solid var(--ifm-color-primary); + border-width: 0 5px 5px 0; +} + +.left:hover::after, .right:hover::after { + opacity: 1; +} + +.left::after { + transform: translate(-50%, -50%) rotate(135deg); +} + +.right::after { + transform: translate(-50%, -50%) rotate(-45deg); +} diff --git a/src/components/TestimonyCard/index.js b/src/components/TestimonyCard/index.js new file mode 100644 index 0000000000000000000000000000000000000000..37f6f99d3ecfa101f47b458a13ab7cf5fa4ba7cb --- /dev/null +++ b/src/components/TestimonyCard/index.js @@ -0,0 +1,15 @@ +import React from 'react'; +import styles from './styles.module.css' +import useBaseUrl from "@docusaurus/useBaseUrl"; + +export default function HomepageList(props) { + return ( + <div className={styles.wholeCard}> + <p>{props.text}</p> + <img className='margin-vert--md' src={useBaseUrl(props.img)} /> + + <h3 className='margin-bottom--xs'>{props.title}</h3> + <span>{props.subtitle}</span> + </div> + ) +} diff --git a/src/components/TestimonyCard/styles.module.css b/src/components/TestimonyCard/styles.module.css new file mode 100644 index 0000000000000000000000000000000000000000..bc8193c248532cb4780e8173954b90e31e9c9193 --- /dev/null +++ b/src/components/TestimonyCard/styles.module.css @@ -0,0 +1,16 @@ +.wholeCard { + display: flex; + flex-direction: column; + align-items: center; + margin: 0 1rem; +} + +p { + text-align: center; + max-width: 680px; +} + +img { + width: 140px; + border-radius: 100px; +} diff --git a/src/css/custom.css b/src/css/custom.css index 578df39b212e33388bbd79086eb0bf0daf9a7384..9c7fe85fe4b5b6b945df5d2e181d767fa7729310 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -24,6 +24,7 @@ --ifm-color-highlight-dark: #a81279; --ifm-footer-background-color: var(--ifm-color-primary-darker) !important; --ifm-footer-color: #ffffff; + --alterning-bkg: #70707011; /* FONTS */ --ifm-font-family-base: 'asap_regular'; --ifm-font-family-bold: 'asap_semi'; @@ -50,6 +51,7 @@ --ifm-color-primary-lighter: #f37749; --ifm-color-primary-lightest: #f69470; --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); + } h1, h2, h3 { @@ -91,3 +93,12 @@ i, em { width: 100%; box-shadow: none; } + +.slick-dots li button::before { + color: var(--ifm-color-primary) !important; +} + +section:nth-child(even) { + background-color: var(--alterning-bkg); + padding: 2rem 0; +} diff --git a/src/pages/index.js b/src/pages/index.js index b51c592d80433a3df6aa9a5ca563e2437fa7af1a..a9545aa475610d881af1aa65b6bc631d5ffebca5 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -5,6 +5,7 @@ import Layout from '@theme/Layout'; import HomepageFeatures from '@site/src/components/HomepageFeatures'; import styles from './index.module.css'; import useBaseUrl from "@docusaurus/useBaseUrl"; +import TestimoniesCarousel from '@site/src/components/TestimoniesCarousel'; const pageTitle = "Home" @@ -39,6 +40,7 @@ export default function Home() { <HomepageHeader /> <main> <HomepageFeatures /> + <TestimoniesCarousel/> </main> </Layout> ); diff --git a/static/img/clients/bpi.png b/static/img/clients/bpi.png new file mode 100644 index 0000000000000000000000000000000000000000..71c2436178bc54825303c618585fef0fe4365686 Binary files /dev/null and b/static/img/clients/bpi.png differ diff --git a/static/img/clients/funmoocfp.png b/static/img/clients/funmoocfp.png new file mode 100644 index 0000000000000000000000000000000000000000..1622a85e99692454c0567f8adbaf3f99de41e88b Binary files /dev/null and b/static/img/clients/funmoocfp.png differ diff --git a/static/img/clients/nightswapping.png b/static/img/clients/nightswapping.png new file mode 100644 index 0000000000000000000000000000000000000000..bdac0986d586fa4a56d3798004f4f8acac5d9ede Binary files /dev/null and b/static/img/clients/nightswapping.png differ diff --git a/static/testimoniesList.json b/static/testimoniesList.json new file mode 100644 index 0000000000000000000000000000000000000000..ebd31726c7ba4af35d043a72ffa9c6da4e358121 --- /dev/null +++ b/static/testimoniesList.json @@ -0,0 +1,20 @@ +[ + { + "title": "BPIfrance - le Hub", + "subtitle": "Prestation Ops", + "text" : "Installation et infogérance de 3 plateformes OpenShift. Mise en place du déploiement continue.", + "img" : "img/clients/bpi.png" + }, + { + "title": "NightSwapping", + "subtitle": "Samuel Paccoud (CTO)", + "text" : "Christophe a mis en place avec succès notre infrastructure technique sur Amazon AWS. Ses solides compétences en administration Linux et Bash, lui ont permis d'apprendre vite toutes les nouvelles technologies que nous utilisions. Son attitude volontaire lui a permis de résoudre tous les problèmes rencontrés, y compris les plus complexes.", + "img" : "img/clients/nightswapping.png" + }, + { + "title": "FUN Mooc", + "subtitle": "Prestation Ops", + "text" : "Mise en place d'une plateforme d'intégration et de déploiement continue GitLab-ci. Participation au projet open source Arnold (https://github.com/openfun/arnold).", + "img" : "img/clients/funmoocfp.png" + } +]