Test Prod
This commit is contained in:
parent
58cebe515b
commit
be832a244c
5
.idea/.gitignore
generated
vendored
Normal file
5
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
6
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
6
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
</profile>
|
||||
</component>
|
||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/portfolio.iml" filepath="$PROJECT_DIR$/.idea/portfolio.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
12
.idea/portfolio.iml
generated
Normal file
12
.idea/portfolio.iml
generated
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
5
debug.log
Normal file
5
debug.log
Normal file
@ -0,0 +1,5 @@
|
||||
[0620/155937.082:ERROR:(-1)] Check failed: false.
|
||||
[0620/174810.676:ERROR:(-1)] Check failed: false.
|
||||
[0620/174851.866:ERROR:(-1)] Check failed: false.
|
||||
[0620/213757.116:ERROR:(-1)] Check failed: false.
|
||||
[0621/002553.054:ERROR:(-1)] Check failed: false.
|
||||
100
package-lock.json
generated
100
package-lock.json
generated
@ -11,9 +11,15 @@
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"bulma": "^0.9.4",
|
||||
"localforage": "^1.10.0",
|
||||
"match-sorter": "^6.3.1",
|
||||
"prop-types": "^15.8.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.13.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"sort-by": "^1.2.0",
|
||||
"web-vitals": "^2.1.4"
|
||||
}
|
||||
},
|
||||
@ -3263,6 +3269,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@remix-run/router": {
|
||||
"version": "1.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.6.3.tgz",
|
||||
"integrity": "sha512-EXJysQ7J3veRECd0kZFQwYYd5sJMcq2O/m60zu1W2l3oVQ9xtub8jTOtYRE0+M2iomyG/W3Ps7+vp2kna0C27Q==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/plugin-babel": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
|
||||
@ -5735,6 +5749,11 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/bulma": {
|
||||
"version": "0.9.4",
|
||||
"resolved": "https://registry.npmjs.org/bulma/-/bulma-0.9.4.tgz",
|
||||
"integrity": "sha512-86FlT5+1GrsgKbPLRRY7cGDg8fsJiP/jzTqXXVqiUZZ2aZT8uemEOHlU1CDU+TxklPEZ11HZNNWclRBBecP4CQ=="
|
||||
},
|
||||
"node_modules/bytes": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
|
||||
@ -9162,6 +9181,11 @@
|
||||
"node": ">= 4"
|
||||
}
|
||||
},
|
||||
"node_modules/immediate": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
|
||||
"integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="
|
||||
},
|
||||
"node_modules/immer": {
|
||||
"version": "9.0.21",
|
||||
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz",
|
||||
@ -11928,6 +11952,14 @@
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lie": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
|
||||
"integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==",
|
||||
"dependencies": {
|
||||
"immediate": "~3.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/lilconfig": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
|
||||
@ -11962,6 +11994,14 @@
|
||||
"node": ">=8.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/localforage": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz",
|
||||
"integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==",
|
||||
"dependencies": {
|
||||
"lie": "3.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/locate-path": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
||||
@ -12079,6 +12119,15 @@
|
||||
"tmpl": "1.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/match-sorter": {
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.1.tgz",
|
||||
"integrity": "sha512-mxybbo3pPNuA+ZuCUhm5bwNkXrJTbsk5VWbR5wiwz/GC6LIiegBGn2w3O08UG/jdbYLinw51fSQ5xNU1U3MgBw==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"remove-accents": "0.4.2"
|
||||
}
|
||||
},
|
||||
"node_modules/mdn-data": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz",
|
||||
@ -12484,6 +12533,14 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/object-path": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/object-path/-/object-path-0.6.0.tgz",
|
||||
"integrity": "sha512-fxrwsCFi3/p+LeLOAwo/wyRMODZxdGBtUlWRzsEpsUVrisZbEfZ21arxLGfaWfcnqb8oHPNihIb4XPE8CQPN5A==",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/object.assign": {
|
||||
"version": "4.1.4",
|
||||
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
|
||||
@ -14548,6 +14605,36 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.13.0.tgz",
|
||||
"integrity": "sha512-Si6KnfEnJw7gUQkNa70dlpI1bul46FuSxX5t5WwlUBxE25DAz2BjVkwaK8Y2s242bQrZPXCpmwLPtIO5pv4tXg==",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.6.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-router-dom": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.13.0.tgz",
|
||||
"integrity": "sha512-6Nqoqd7fgwxxVGdbiMHTpDHCYPq62d7Wk1Of7B82vH7ZPwwsRaIa22zRZKPPg413R5REVNiyuQPKDG1bubcOFA==",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.6.3",
|
||||
"react-router": "6.13.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8",
|
||||
"react-dom": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-scripts": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
|
||||
@ -14768,6 +14855,11 @@
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/remove-accents": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz",
|
||||
"integrity": "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA=="
|
||||
},
|
||||
"node_modules/renderkid": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz",
|
||||
@ -15411,6 +15503,14 @@
|
||||
"websocket-driver": "^0.7.4"
|
||||
}
|
||||
},
|
||||
"node_modules/sort-by": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/sort-by/-/sort-by-1.2.0.tgz",
|
||||
"integrity": "sha512-aRyW65r3xMnf4nxJRluCg0H/woJpksU1dQxRtXYzau30sNBOmf5HACpDd9MZDhKh7ALQ5FgSOfMPwZEtUmMqcg==",
|
||||
"dependencies": {
|
||||
"object-path": "0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/source-list-map": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
|
||||
|
||||
@ -6,9 +6,15 @@
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"bulma": "^0.9.4",
|
||||
"localforage": "^1.10.0",
|
||||
"match-sorter": "^6.3.1",
|
||||
"prop-types": "^15.8.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.13.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"sort-by": "^1.2.0",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@ -10,34 +10,11 @@
|
||||
content="Web site created using create-react-app"
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
<title>Ewen Horville | Portfolio</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
|
||||
47
src/App.css
47
src/App.css
@ -1,38 +1,27 @@
|
||||
.App {
|
||||
text-align: center;
|
||||
.blurred {
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
filter: blur(7px) grayscale(50%);
|
||||
object-fit: cover;
|
||||
transform: scale(1.04);
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.App-logo {
|
||||
height: 40vmin;
|
||||
pointer-events: none;
|
||||
.soft-shadow {
|
||||
box-shadow: 0 0.5em .25em -0.125em rgba(10,10,10,.1), 0 0 0 1px rgba(10,10,10,.1);;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.App-logo {
|
||||
animation: App-logo-spin infinite 20s linear;
|
||||
}
|
||||
.rounded {
|
||||
border-radius: 1em;
|
||||
}
|
||||
|
||||
.App-header {
|
||||
background-color: #282c34;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: calc(10px + 2vmin);
|
||||
color: white;
|
||||
.is-carousel-focused {
|
||||
max-height: .8em;
|
||||
transition: max-height .15s;
|
||||
}
|
||||
|
||||
.App-link {
|
||||
color: #61dafb;
|
||||
}
|
||||
|
||||
@keyframes App-logo-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
.is-carousel {
|
||||
max-height: .5em;
|
||||
transition: max-height .15s;
|
||||
}
|
||||
39
src/App.js
39
src/App.js
@ -1,23 +1,30 @@
|
||||
import logo from './logo.svg';
|
||||
import './App.css';
|
||||
import Homepage from "./Pages/Homepage/Homepage";
|
||||
import Project, {projectLoader} from "./Pages/Project/Project";
|
||||
import {createBrowserRouter, Navigate, RouterProvider} from "react-router-dom";
|
||||
import React from "react";
|
||||
import Navbar from "./Components/Navbar";
|
||||
import Footer from "./Components/Footer";
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
path: "/",
|
||||
element: <Homepage/>,
|
||||
errorElement: <Navigate to="/"/>
|
||||
},
|
||||
{
|
||||
path: "projects/:projectId",
|
||||
loader: projectLoader,
|
||||
element: <Project/>
|
||||
}
|
||||
]);
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="App">
|
||||
<header className="App-header">
|
||||
<img src={logo} className="App-logo" alt="logo" />
|
||||
<p>
|
||||
Edit <code>src/App.js</code> and save to reload.
|
||||
</p>
|
||||
<a
|
||||
className="App-link"
|
||||
href="https://reactjs.org"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Learn React
|
||||
</a>
|
||||
</header>
|
||||
<div className="App has-background-white-bis is-flex-direction-column" style={{minHeight: "100vh"}}>
|
||||
<Navbar/>
|
||||
<RouterProvider router={router} />
|
||||
<Footer/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
81
src/Components/Carousel.js
Normal file
81
src/Components/Carousel.js
Normal file
@ -0,0 +1,81 @@
|
||||
import {Component} from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
class Carousel extends Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
currentImage: 0
|
||||
}
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
images: PropTypes.array.isRequired
|
||||
}
|
||||
|
||||
handleNextImage = () => {
|
||||
this.setState({
|
||||
currentImage: (this.state.currentImage + 1) % this.props.images.length
|
||||
})
|
||||
}
|
||||
|
||||
handlePreviousImage = () => {
|
||||
if (this.state.currentImage === 0) {
|
||||
this.setState({
|
||||
currentImage: this.props.images.length - 1
|
||||
})
|
||||
} else {
|
||||
this.setState({
|
||||
currentImage: (this.state.currentImage - 1) % this.props.images.length
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
getMediaHTML(media) {
|
||||
switch (media.type) {
|
||||
case "youtube": {
|
||||
return <div style={{position: "relative", width: "100%", paddingBottom: "56.25%"}}>
|
||||
<iframe
|
||||
style={{
|
||||
width: "100%", height: "100%",
|
||||
borderRadius: ".5em",
|
||||
position: "absolute", top: "0", bottom: "0", left: "0", right: "0"
|
||||
}}
|
||||
src={media.value}
|
||||
title="Showcase media"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||
allowFullScreen>
|
||||
</iframe>
|
||||
</div>
|
||||
}
|
||||
case "picture": {
|
||||
return <img className="rounded" alt="Showcase media" src={media.value}/>
|
||||
}
|
||||
default: {
|
||||
return <div/>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div>
|
||||
{this.getMediaHTML(this.props.images[this.state.currentImage])}
|
||||
<div className="is-inline-flex mt-2" style={{width: "100%"}}>
|
||||
<div style={{flex: "1"}}/>
|
||||
<span className="button" onClick={this.handlePreviousImage}><</span>
|
||||
{this.props.images.map((image, index) => {
|
||||
let focused = this.state.currentImage === index ? "is-carousel-focused" : "is-carousel";
|
||||
return <img key={index} alt="" src="https://www.svgrepo.com/download/35641/dot.svg" className={"mr-1 ml-1 mt-auto mb-auto " + focused}/>;
|
||||
})}
|
||||
<span className="button" onClick={this.handleNextImage}>></span>
|
||||
<div style={{flex: "1"}}/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
export default Carousel;
|
||||
34
src/Components/Footer.js
Normal file
34
src/Components/Footer.js
Normal file
@ -0,0 +1,34 @@
|
||||
import {Component} from "react";
|
||||
|
||||
class Footer extends Component {
|
||||
|
||||
render() {
|
||||
return <footer className="footer has-background-grey-darker pl-6 pr-6">
|
||||
<div className="is-inline-flex" style={{width: "100%"}}>
|
||||
<div style={{flex: ".5"}}>
|
||||
<p><strong className="has-text-grey-lighter">Me Contacter :</strong></p>
|
||||
<ul>
|
||||
<li><a rel="noreferrer" className="has-text-info" target="_blank" href="mailto://ewen.horville3@gmail.com">ewen.horville3@gmail.com</a></li>
|
||||
<li className="has-text-grey-lighter">+33 6 59 18 31 92</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="content has-text-centered has-text-grey-lighter" style={{flex: "1"}}>
|
||||
<p>Portfolio créé avec
|
||||
<a rel="noreferrer" href="https://react.dev" target="_blank" className="has-text-info"> ReactJS </a>
|
||||
et
|
||||
<a rel="noreferrer" href="https://bulma.io" target="_blank" className="has-text-info"> Bulma CSS</a>.
|
||||
<br/>
|
||||
<a rel="noreferrer" href="https://github.com/The17thDoctor/portfolio" target="_blank" className="has-text-info">Code Source</a></p>
|
||||
</div>
|
||||
<div className="" style={{flex: ".5"}}>
|
||||
<p><strong className="has-text-grey-lighter">Liens :</strong></p>
|
||||
<ul>
|
||||
<li><a rel="noreferrer" href="https://github.com/The17thDoctor" target="_blank" className="has-text-info">Github</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
}
|
||||
}
|
||||
|
||||
export default Footer;
|
||||
20
src/Components/Navbar.js
Normal file
20
src/Components/Navbar.js
Normal file
@ -0,0 +1,20 @@
|
||||
import {Component} from "react";
|
||||
|
||||
class Navbar extends Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<nav className="navbar has-shadow" role="navigation" aria-label="main navigation">
|
||||
<div id="navbarBasicExample" className="navbar-menu">
|
||||
<div className="navbar-start">
|
||||
<a href="/" className="navbar-item title is-5 m-auto">
|
||||
Accueil
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Navbar;
|
||||
61
src/Pages/Homepage/Homepage.js
Normal file
61
src/Pages/Homepage/Homepage.js
Normal file
@ -0,0 +1,61 @@
|
||||
import video from "../../media/main_vid.mp4";
|
||||
import ProjectCard from "./ProjectCard";
|
||||
import projects from "../../Projects/manifest";
|
||||
|
||||
export default function Homepage() {
|
||||
return <div>
|
||||
<div className="is-flex is-flex-direction-column" style={{height: "30em", overflow: "hidden"}}>
|
||||
<div className="blurred" style={{height: "inherit"}}>
|
||||
<video className="crop" style={{height: "initial", margin: "auto"}} autoPlay={true} aria-disabled={true} loop="loop" muted={true}>
|
||||
<source src={video} type="video/mp4"/>
|
||||
</video>
|
||||
</div>
|
||||
<div style={{position: "absolute", height: "30em", width: "100%"}}>
|
||||
<h1 className="title is-1 has-text-white has-text-centered" style={{marginTop: "3.55em"}}>Ewen Horville</h1>
|
||||
<p className="title is-2 has-text-centered has-text-white">
|
||||
Étudiant et passionné en Informatique
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="is-flex is-flex-direction-column soft-shadow" style={{height: "30em"}}>
|
||||
<h1 className="title is-1 has-text-centered m-auto p-6">A Propos de moi</h1>
|
||||
<div className="tile is-ancestor m-auto" style={{paddingLeft: "10%", paddingRight: "10%"}}>
|
||||
<div className="tile p-4 is-align-items-center">
|
||||
<div className="mr-5">
|
||||
<figure className="image is-128x128">
|
||||
<img alt="placeholder" src="https://bulma.io/images/placeholders/128x128.png"/>
|
||||
</figure>
|
||||
</div>
|
||||
<div>
|
||||
<p className="has-text-justified">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer cursus mi lectus. Curabitur congue consectetur orci non consectetur. Donec at purus sodales, mollis dui ac, volutpat tellus. Nullam non pulvinar nisl. Maecenas fringilla auctor sem, vitae posuere turpis ultricies vitae. Nullam urna neque, accumsan nec ex eget, aliquet ultrices nulla. Aenean id nisl eu erat iaculis venenatis. Nullam semper sapien leo, vitae mollis augue auctor in. Donec at dui in orci varius placerat aliquet id neque.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="tile p-4 is-align-items-center">
|
||||
<div className="mr-5">
|
||||
<figure className="image is-128x128">
|
||||
<img alt="placeholder" src="https://bulma.io/images/placeholders/128x128.png"/>
|
||||
</figure>
|
||||
</div>
|
||||
<div>
|
||||
<p className="has-text-justified">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer cursus mi lectus. Curabitur congue consectetur orci non consectetur. Donec at purus sodales, mollis dui ac, volutpat tellus. Nullam non pulvinar nisl. Maecenas fringilla auctor sem, vitae posuere turpis ultricies vitae. Nullam urna neque, accumsan nec ex eget, aliquet ultrices nulla. Aenean id nisl eu erat iaculis venenatis. Nullam semper sapien leo, vitae mollis augue auctor in. Donec at dui in orci varius placerat aliquet id neque.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="tile is-ancestor is-white p-4 is-vertical">
|
||||
<div className="tile is-parent mr-auto ml-auto m-4">
|
||||
<h1 className="title is-1">Mes Projets</h1>
|
||||
</div>
|
||||
<div className="tile is-parent mr-auto ml-auto">
|
||||
<div className="tile p-4 is-black"><ProjectCard index={0} project={projects[0]}/></div>
|
||||
<div className="tile p-4 is-black"><ProjectCard index={1} project={projects[1]}/></div>
|
||||
<div className="tile p-4 is-black"><ProjectCard index={2} project={projects[2]}/></div>
|
||||
</div>
|
||||
<div className="tile is-parent">
|
||||
<div className="tile p-4 is-black"><ProjectCard index={3} project={projects[3]}/></div>
|
||||
<div className="tile p-4 is-black"><ProjectCard index={4} project={projects[4]}/></div>
|
||||
<div className="tile p-4 is-black"><ProjectCard index={5} project={projects[5]}/></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
36
src/Pages/Homepage/ProjectCard.js
Normal file
36
src/Pages/Homepage/ProjectCard.js
Normal file
@ -0,0 +1,36 @@
|
||||
import {Component} from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import {NavLink} from "react-router-dom";
|
||||
|
||||
class ProjectCard extends Component {
|
||||
|
||||
static propTypes = {
|
||||
project: PropTypes.object.isRequired,
|
||||
index: PropTypes.number.isRequired
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div className="card">
|
||||
<div className="card-image">
|
||||
<figure className="image is-4by3">
|
||||
<img alt={this.props.project.title} src={this.props.project.thumbnail}/>
|
||||
</figure>
|
||||
</div>
|
||||
<div className="card-content">
|
||||
<div className="media">
|
||||
<div className="media-content">
|
||||
<NavLink to={"projects/" + this.props.index} className="title has-text-link is-underlined is-4">{this.props.project.title}</NavLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="content">
|
||||
{this.props.project.shortDesc}
|
||||
<br/>
|
||||
<time>{this.props.project.date.toLocaleDateString("fr-FR")}</time>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
export default ProjectCard;
|
||||
58
src/Pages/Project/Project.js
Normal file
58
src/Pages/Project/Project.js
Normal file
@ -0,0 +1,58 @@
|
||||
import Carousel from "../../Components/Carousel";
|
||||
import {useLoaderData} from "react-router-dom";
|
||||
import projects from "../../Projects/manifest";
|
||||
|
||||
export async function projectLoader(request) {
|
||||
return projects[request.params.projectId];
|
||||
}
|
||||
|
||||
export default function Project() {
|
||||
|
||||
const project = useLoaderData();
|
||||
|
||||
function getMediaHTML(media) {
|
||||
switch (media.type) {
|
||||
case "youtube": {
|
||||
return <div style={{position: "relative", width: "100%", paddingBottom: "56.25%"}}>
|
||||
<iframe
|
||||
style={{
|
||||
width: "100%", height: "100%",
|
||||
borderRadius: ".5em",
|
||||
position: "absolute", top: "0", bottom: "0", left: "0", right: "0"
|
||||
}}
|
||||
src={media.value}
|
||||
title="Showcase media"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||
allowFullScreen>
|
||||
</iframe>
|
||||
</div>
|
||||
}
|
||||
case "picture": {
|
||||
return <img className="rounded" alt="Showcase media" src={media.value}/>
|
||||
}
|
||||
default: {
|
||||
return <div/>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="pt-5 pb-5" style={{marginLeft: "10%", marginRight: "10%"}}>
|
||||
<div className="box">
|
||||
<div className="is-inline-flex" style={{width: "100%"}}>
|
||||
<div className="m-2" style={{flex: "1"}}>
|
||||
{getMediaHTML(project.mainMedia)}
|
||||
</div>
|
||||
<div className="m-2" style={{width: ".5fr", flex: "1.2"}}>
|
||||
<h1 className="title is-1">{project.title}</h1>
|
||||
<p className="has-text-justified">{project.longDesc}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="m-auto box" style={{paddingLeft: "7%", paddingRight: "7%"}}>
|
||||
<h1 className="title is-1 has-text-centered">Plus d'images</h1>
|
||||
<Carousel images={project.secondaryMedia}></Carousel>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
76
src/Projects/manifest.js
Normal file
76
src/Projects/manifest.js
Normal file
@ -0,0 +1,76 @@
|
||||
const projectData = [
|
||||
{
|
||||
title: "AquaticWeb v1",
|
||||
shortDesc: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nec iaculis mauris.",
|
||||
longDesc: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nec iaculis mauris.",
|
||||
thumbnail: "https://bulma.io/images/placeholders/1280x960.png",
|
||||
mainMedia: {type: "youtube", value: "https://youtube.com/embed/3Okx0T5vpFc"},
|
||||
secondaryMedia: [
|
||||
{type: "youtube", value: "https://youtube.com/embed/3Okx0T5vpFc"},
|
||||
{type: "picture", value: "https://www.jacksonsquareshopping.co.uk/wp-content/uploads/2016/12/placeholder-1920x1080-copy.png"}
|
||||
],
|
||||
date: new Date(Date.UTC(2023, 5, 29))
|
||||
},
|
||||
{
|
||||
title: "AquaticWeb v2",
|
||||
shortDesc: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nec iaculis mauris.",
|
||||
longDesc: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nec iaculis mauris.",
|
||||
thumbnail: "https://bulma.io/images/placeholders/1280x960.png",
|
||||
mainMedia: {type: "youtube", value: "https://youtube.com/embed/3Okx0T5vpFc"},
|
||||
secondaryMedia: [
|
||||
{type: "youtube", value: "https://youtube.com/embed/3Okx0T5vpFc"},
|
||||
{type: "picture", value: "https://www.jacksonsquareshopping.co.uk/wp-content/uploads/2016/12/placeholder-1920x1080-copy.png"}
|
||||
],
|
||||
date: new Date(Date.UTC(2023, 5, 29))
|
||||
},
|
||||
{
|
||||
title: "AquaticWeb v3",
|
||||
shortDesc: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nec iaculis mauris.",
|
||||
longDesc: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nec iaculis mauris.",
|
||||
thumbnail: "https://bulma.io/images/placeholders/1280x960.png",
|
||||
mainMedia: {type: "youtube", value: "https://youtube.com/embed/3Okx0T5vpFc"},
|
||||
secondaryMedia: [
|
||||
{type: "youtube", value: "https://youtube.com/embed/3Okx0T5vpFc"},
|
||||
{type: "picture", value: "https://www.jacksonsquareshopping.co.uk/wp-content/uploads/2016/12/placeholder-1920x1080-copy.png"}
|
||||
],
|
||||
date: new Date(Date.UTC(2023, 5, 29))
|
||||
},
|
||||
{
|
||||
title: "AquaticWeb v4",
|
||||
shortDesc: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nec iaculis mauris.",
|
||||
longDesc: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nec iaculis mauris.",
|
||||
thumbnail: "https://bulma.io/images/placeholders/1280x960.png",
|
||||
mainMedia: {type: "picture", value: "https://www.jacksonsquareshopping.co.uk/wp-content/uploads/2016/12/placeholder-1920x1080-copy.png"},
|
||||
secondaryMedia: [
|
||||
{type: "youtube", value: "https://youtube.com/embed/3Okx0T5vpFc"},
|
||||
{type: "picture", value: "https://www.jacksonsquareshopping.co.uk/wp-content/uploads/2016/12/placeholder-1920x1080-copy.png"}
|
||||
],
|
||||
date: new Date(Date.UTC(2023, 5, 29))
|
||||
},
|
||||
{
|
||||
title: "AquaticWeb v5",
|
||||
shortDesc: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nec iaculis mauris.",
|
||||
longDesc: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nec iaculis mauris.",
|
||||
thumbnail: "https://www.jacksonsquareshopping.co.uk/wp-content/uploads/2016/12/placeholder-1920x1080-copy.png",
|
||||
mainMedia: {type: "picture", value: "https://www.jacksonsquareshopping.co.uk/wp-content/uploads/2016/12/placeholder-1920x1080-copy.png"},
|
||||
secondaryMedia: [
|
||||
{type: "youtube", value: "https://youtube.com/embed/3Okx0T5vpFc"},
|
||||
{type: "picture", value: "https://www.jacksonsquareshopping.co.uk/wp-content/uploads/2016/12/placeholder-1920x1080-copy.png"}
|
||||
],
|
||||
date: new Date(Date.UTC(2023, 5, 29))
|
||||
},
|
||||
{
|
||||
title: "AquaticWeb v6",
|
||||
shortDesc: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nec iaculis mauris.",
|
||||
longDesc: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nec iaculis mauris.",
|
||||
thumbnail: "https://bulma.io/images/placeholders/1280x960.png",
|
||||
mainMedia: {type: "picture", value: "https://www.jacksonsquareshopping.co.uk/wp-content/uploads/2016/12/placeholder-1920x1080-copy.png"},
|
||||
secondaryMedia: [
|
||||
{type: "youtube", value: "https://youtube.com/embed/3Okx0T5vpFc"},
|
||||
{type: "picture", value: "https://www.jacksonsquareshopping.co.uk/wp-content/uploads/2016/12/placeholder-1920x1080-copy.png"}
|
||||
],
|
||||
date: new Date(Date.UTC(2023, 5, 29))
|
||||
}
|
||||
]
|
||||
|
||||
export default projectData;
|
||||
@ -1,13 +1 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
||||
@import "https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css";
|
||||
@ -1,8 +1,10 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import './index.css';
|
||||
import App from './App';
|
||||
import './App.css';
|
||||
import reportWebVitals from './reportWebVitals';
|
||||
import App from "./App";
|
||||
|
||||
|
||||
const root = ReactDOM.createRoot(document.getElementById('root'));
|
||||
root.render(
|
||||
|
||||
BIN
src/media/main_vid.mp4
Normal file
BIN
src/media/main_vid.mp4
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user