diff --git a/package.json b/package.json index 8ad1736..33c3b9f 100644 --- a/package.json +++ b/package.json @@ -6,12 +6,16 @@ "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "fs-extra": "^11.2.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", "web-vitals": "^2.1.4" }, + "devDependencies": { + }, "scripts": { + "nc": "node scripts/new-component.mjs", "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", diff --git a/public/index.html b/public/index.html index aa069f2..427f402 100644 --- a/public/index.html +++ b/public/index.html @@ -29,15 +29,5 @@
- diff --git a/scripts/new-component.mjs b/scripts/new-component.mjs new file mode 100644 index 0000000..9680977 --- /dev/null +++ b/scripts/new-component.mjs @@ -0,0 +1,63 @@ +import { dirname } from "path"; +import { fileURLToPath } from "url"; +import { outputFile } from "fs-extra"; + +const componentName = process.argv[2]; +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +// Note for later use // +// To use this script : +// yarn nc / +// Exemple : "yarn nc components/MyComponent" will create +// a folder MyComponent (and all the basic) within the components folder + +function lowerCaseFirstLetter(string) { + return string.charAt(0).toLowerCase() + string.slice(1); +} + +function returnComponentPath(cpt, fileType) { + if (cpt.includes("/")) { + const pathName = cpt.split("/")[0]; + const component = cpt.split("/")[1]; + return `${pathName}/${component}/${fileType}`; + } + return `${cpt}/${fileType}`; +} + +function checkComponentName(cpt) { + if (cpt.includes("/")) { + return cpt.split("/")[1]; + } + return cpt; +} + +// Create the default index.js file +outputFile( + `${__dirname}/../src/${returnComponentPath(componentName, "index.js")}`, + `import './styles.css'; + +const ${checkComponentName(componentName)} = () => { + return
; +}; + +export default ${checkComponentName(componentName)};`, + function (err) { + if (err) { + return console.log(err); + } + // Create the default styles.css file + outputFile( + `${__dirname}/../src/${returnComponentPath(componentName, "styles.css")}`, + `.${lowerCaseFirstLetter(checkComponentName(componentName))} {}`, + function (err) { + if (err) { + return console.log(err); + } + console.log("The file was saved!"); + } + ); + } +); diff --git a/src/assets/img/logo512.png b/src/assets/img/logo512.png new file mode 100644 index 0000000..a4e47a6 Binary files /dev/null and b/src/assets/img/logo512.png differ diff --git a/src/components/Heading/index.js b/src/components/Heading/index.js new file mode 100644 index 0000000..d9285fa --- /dev/null +++ b/src/components/Heading/index.js @@ -0,0 +1,28 @@ +import "./styles.css"; + +/** + * Heading component. + * + * This is a reusable heading component. It accepts a prop `As` which determines the HTML element to be used for the heading. + * It also accepts a prop `className` which is used to add a class to the heading. + * Some default className can be added such as : + * ```scss + * subtitle + * h2-like + * h3-like + * h4-like + * ``` + * + * Example usage: + * + * ```jsx + * Title + * ``` + */ +const Heading = ({ As, className, children }) => { + return ( + {children} + ); +}; + +export default Heading; diff --git a/src/components/Heading/styles.css b/src/components/Heading/styles.css new file mode 100644 index 0000000..a58e2fa --- /dev/null +++ b/src/components/Heading/styles.css @@ -0,0 +1,38 @@ +/* Reminder +The base font size is 16px. To use EM value for font size, +divide the pixel value by 16. +For example, 32px = 2em, 24px = 1.5em, 16px = 1em, 8px = 0.5em, etc. +*/ + +.heading { + font-family: "Poppins", "Arial", sans-serif; + font-size: 4em; + font-weight: 700; + line-height: 1; + color: var(--color-primary); +} + +.h2-like { + font-size: 3em; + font-weight: 600; +} + +.h3-like { + font-size: 2em; + font-weight: 600; +} + +.h4-like { + font-size: 1.5em; + font-weight: 400; +} + +.h5-like, +.h6-like { + font-size: 1em; + font-weight: 400; +} + +.subtitle { + color: var(--color-secondary); +} \ No newline at end of file diff --git a/src/components/Navbar/index.js b/src/components/Navbar/index.js new file mode 100644 index 0000000..a2acadd --- /dev/null +++ b/src/components/Navbar/index.js @@ -0,0 +1,7 @@ +import './styles.css'; + +const Navbar = () => { + return
; +}; + +export default Navbar; \ No newline at end of file diff --git a/src/components/Navbar/styles.css b/src/components/Navbar/styles.css new file mode 100644 index 0000000..e4f1885 --- /dev/null +++ b/src/components/Navbar/styles.css @@ -0,0 +1 @@ +.navbar {} \ No newline at end of file diff --git a/src/contexts/GlobalContext/index.js b/src/contexts/GlobalContext/index.js new file mode 100644 index 0000000..1d471ca --- /dev/null +++ b/src/contexts/GlobalContext/index.js @@ -0,0 +1,38 @@ +import { createContext, useReducer } from "react"; + +import closeModals from "../reducers/closeModal"; +import handleModal from "../reducers/handleModal"; + +const GlobalContext = createContext(); + +export const GlobalContextProvider = (props) => { + const openModalWithUrl = () => { + return null; + }; + + let initialState = { + modal: openModalWithUrl(), + }; + + const reducer = (state, action) => { + switch (action.type) { + case "HANDLE_MODAL": + return handleModal(state, action); + case "CLOSE_MODALS": + return closeModals(state); + + default: + return state; + } + }; + + const [state, dispatch] = useReducer(reducer, initialState); + + return ( + + {props.children} + + ); +}; + +export default GlobalContext; diff --git a/src/contexts/reducers/closeModal.js b/src/contexts/reducers/closeModal.js new file mode 100644 index 0000000..8a1aedc --- /dev/null +++ b/src/contexts/reducers/closeModal.js @@ -0,0 +1,12 @@ +// FYI : This reducer isn't used anymore unless +// you need to force close a modal. +// go to : hooks/useModal.js for the new usage. + +const closeModals = (state) => { + return { + ...state, + modal: null, + }; +}; + +export default closeModals; diff --git a/src/contexts/reducers/handleModal.js b/src/contexts/reducers/handleModal.js new file mode 100644 index 0000000..15a07a2 --- /dev/null +++ b/src/contexts/reducers/handleModal.js @@ -0,0 +1,10 @@ +const handleModal = (state, action) => { + const { payload } = action; + + return { + ...state, + modal: payload, + }; +}; + +export default handleModal; diff --git a/src/hooks/useModal.js b/src/hooks/useModal.js new file mode 100644 index 0000000..efdedb3 --- /dev/null +++ b/src/hooks/useModal.js @@ -0,0 +1,30 @@ +import { useContext } from "react"; + +import GlobalContext from "../components/contexts/GlobalContext"; + +const useModal = () => { + const { dispatch } = useContext(GlobalContext); + + // Open a Component modal + const openModal = (Modal) => { + dispatch({ + type: "HANDLE_MODAL", + payload: Modal, + }); + }; + + // Close a Modal + const closeModal = () => { + dispatch({ + type: "HANDLE_MODAL", + payload: null, + }); + }; + + return { + openModal, + closeModal, + }; +}; + +export default useModal; diff --git a/src/hooks/useResize.js b/src/hooks/useResize.js new file mode 100644 index 0000000..5119a7d --- /dev/null +++ b/src/hooks/useResize.js @@ -0,0 +1,30 @@ +import { useEffect, useState } from "react"; + +const useResize = () => { + // const isBrowser = typeof window !== "undefined"; + const [dimensions, setDimensions] = useState({ + width: window.innerWidth, + height: window.innerHeight, + }); + + const handleWindowResize = () => { + setDimensions({ + width: window.innerWidth, + height: window.innerHeight, + }); + }; + + useEffect(() => { + window.addEventListener("resize", handleWindowResize); + handleWindowResize(); + return () => { + window.removeEventListener("resize", handleWindowResize); + }; + }, [setDimensions]); + + return { + dimensions, + }; +}; + +export default useResize; diff --git a/src/index.js b/src/index.js index d563c0f..cdca195 100644 --- a/src/index.js +++ b/src/index.js @@ -1,13 +1,18 @@ -import React from 'react'; -import ReactDOM from 'react-dom/client'; -import './index.css'; -import App from './App'; -import reportWebVitals from './reportWebVitals'; +import "./index.css"; -const root = ReactDOM.createRoot(document.getElementById('root')); +import React from "react"; +import ReactDOM from "react-dom/client"; + +import App from "./App"; +import reportWebVitals from "./reportWebVitals"; +import { GlobalContextProvider } from "./contexts/GlobalContext"; + +const root = ReactDOM.createRoot(document.getElementById("root")); root.render( - + + + ); diff --git a/src/layouts/Footer/index.js b/src/layouts/Footer/index.js new file mode 100644 index 0000000..66c2e7e --- /dev/null +++ b/src/layouts/Footer/index.js @@ -0,0 +1,7 @@ +import './styles.css'; + +const Footer = () => { + return
; +}; + +export default Footer; \ No newline at end of file diff --git a/src/layouts/Footer/styles.css b/src/layouts/Footer/styles.css new file mode 100644 index 0000000..e246b7c --- /dev/null +++ b/src/layouts/Footer/styles.css @@ -0,0 +1 @@ +.footer {} \ No newline at end of file diff --git a/src/layouts/Modals/index.js b/src/layouts/Modals/index.js new file mode 100644 index 0000000..f3e1ab9 --- /dev/null +++ b/src/layouts/Modals/index.js @@ -0,0 +1,29 @@ +import "./_styles.scss"; + +import Container from "../Container"; +import Heading from "../../components/Heading"; +import { closeModal } from "../../hooks/useModal"; + +const Modals = ({ headingTitle, className, children }) => { + return ( +
+ +
+
+ + {headingTitle} + +
+ + Close SVG + +
+
+
{children}
+
+
+
+ ); +}; + +export default Modals; diff --git a/src/layouts/Modals/styles.css b/src/layouts/Modals/styles.css new file mode 100644 index 0000000..c04f7b8 --- /dev/null +++ b/src/layouts/Modals/styles.css @@ -0,0 +1 @@ +.modals {} \ No newline at end of file diff --git a/src/pages/Home/index.js b/src/pages/Home/index.js new file mode 100644 index 0000000..6e9df12 --- /dev/null +++ b/src/pages/Home/index.js @@ -0,0 +1,7 @@ +import './styles.css'; + +const Home = () => { + return
; +}; + +export default Home; \ No newline at end of file diff --git a/src/pages/Home/styles.css b/src/pages/Home/styles.css new file mode 100644 index 0000000..f8ab51b --- /dev/null +++ b/src/pages/Home/styles.css @@ -0,0 +1 @@ +.home {} \ No newline at end of file