Coder Social home page Coder Social logo

eps1lon / navbar Goto Github PK

View Code? Open in Web Editor NEW

This project forked from ndrean/navbar

0.0 1.0 0.0 19.22 MB

Skeleton React app routed by Universal Router, state managed by Mobx, dynamic forms with R-Hook-Forms,, designed with Material-UI, with form and modal login and Facebook Login

JavaScript 94.41% Dockerfile 0.54% HTML 2.59% CSS 2.04% Shell 0.03% Makefile 0.39%

navbar's Introduction

A React app skeleton using Mobx, Universal Router, Material-UI, React-Hook-Forms

Deploy

Netlify

Just go to https://netlify.com ....

Surge

Install the surge cli (https://surge.sh/), run yarn build, then surge in the "./build" folder: name it and view the app at: http://rmm.surge.sh/

Github pages

Install yarn add gh-pages --dev, then add to "package.json":

"homepage": "https://ndrean.github.io/navbar",
...
"scripts": {
  "predeploy": "yarn build",
  "deploy": "gh-pages -d build"
}

and run yarn deploy.

TODOs

  1. All Material-UI imports with rewired/custom-cra

  2. Modal for sign-in

  3. dynamic badges in navbar on #contacts & #pages-views

  4. Mobile format of navbar & drawer

  5. navigation with drawer

  6. Navigation with Universal Router:

    1. protected route with redirection with Univ Router
    2. Mode "admin" set with localStorage with lazy useState and change in useEffect
    3. nested dynamic route /contacts/:id
  7. Dynamic form: new + delete dynamic form user

  8. Implement fake POST and fake return token

  9. Suspense/lazy for code splitting

  10. Facebook login, in modal & login-form

  11. create Alert with the return token: FB-token & user created with fake-token

  12. Compare with React Router for passing props vs Universal Router - Mobx ??

CRA & Material-UI config (to use imports)

1- CRA with updated ServiceWorker: npx create-react-app my-app --template cra-template-pwa

2- Configure babel with babel-plugin-import, create a .babelrc.js file in the root directory of your project. Since we use CRA, we need react-app-rewired and customize-cra to be able to use .babelrc.js.

Notes

Difficulties code bugs to remove from Mobx

1- "Cannot update a component from inside the function body of a different component."

2- "Cannot update a component (_c) while rendering a different component (_c)"

Some recipies:

-> try put in useEffect for one,

-> perform action in navbar method calling the component rather than in the component,

-> use action on every event method.

But no solution found for Modal: (isSubmitSuccessful) store.setModalClose() <=> pb 2.

React-hook-forms & Material-UI

  • need to register the form fields TexField component with inputRef={register()}

  • need to control the form field Checkbox component with:

  • add inputs "on the fly". Take an array of data and map the indexed form. Note that the name should be something like: name={data[${i}].email}where i is the index of the mapping.

For the checkbox, needed below:

control={
   <Controller as={Checkbox} control={control}  defaultValue={false} name="remember"/>

Insert image in CardMedia - Material-UI from a folder

To insert several cards, map an array cards as shown in the example. Then needed to:

  1. import... (Webpack),
  2. use component="img"
  3. use image tag <=> background-image = url("...")

Code example

import imgReact from "../img/React.png";
import imgMobx from "../img/Mobx.jpeg";
...
const cards = [
  {
    name: "React",
    image: imgReact,
    url: "https://fr.reactjs.org/",
  },
  {
    name: "Mobx",
    image: imgMobx,
    url: "https://mobx.js.org/README.html",
  },
  [...]
}
{cards.map(({ name, image, url }) => (...
<CardMedia component="img" image={image} title={`tech: ${name}`} loading="lazy" />

To implement Cloudinary REST API to save pictures without back-end

72x72

  • Input:
import PhotoCameraOutlinedIcon from '@material-ui/icons/PhotoCameraOutlined';
<input type="file" accept="image/*" onClick={()=> setImageFile(e.target.files[0])}/>`
  • send to the cloud: direct call Cloudinary REST API
const formData = new FormData();
formData.append("file", fileCL);
formData.append("upload_preset", "ml_default");
fetch(`https://api.cloudinary.com/v1_1/${props.cloudname}/upload/`,
  {
    method: "POST",
    body: formData,
  }
)
  // CL response will be a SECURE_LINK and a unique ID
  .then((res) => res.json())
  .then((resCL) => {
    console.log(resCL.public_id);
    console.log(resCL.secure_url);

2- save into the Cloud or host file sytem

3- preview with URL.createObjectURL() or with readAsDataURL

<input type="file" accept="image/*" id="inputFile"/>
<img id="previewElt"/>
const previewImg = document.getElementById("previewElt")
const fileElt = document.getElementById("inputFile")

4- save an image into a file with a "fake" <a> where we simulate the click() and using new Blob:

https://robkendal.co.uk/blog/2020-04-17-saving-text-to-client-side-file-using-vanilla-js

const contentType = "image/*"; // or `text/plain" .or "text/html" or...
const a = document.createElement("a");
const blob = new Blob([content], { type: contentType });
a.href = URL.createObjectURL(blob);
a.download = "filename"; // the name given to the file: to be changed
a.click(); // simulate the click
URL.revokeObjectURL(a.href);

OR with new FileReader()

fileElt.addEventListener("change", () => {
  const file = e.target.files[0];
  const url = URL.createObjectURL(file);
  previewImg.scr = url;

4- Resize an image: canvas and readAsDataURL and canvasToBlob

https://htmldom.dev/resize-an-image/

4- display

Code notes

To view on mobile phone the dev stage

http-server ./build -a 0.0.0.0 -p 8090 and open 192.168.0.41:8090

Use formdata with RHF

const formRef = React.useRef(null)

const data = new FormData(formRef.current)
fetch("url", {
  method: "POST",
  mode: "cors",
  body: data,
  }
})
<form ... ref={formRef}>

!!!! NO CONTENT-TYPE ..... !!!!

Dynamic "on-the-fly" form creation with RHF

If we want to produce a payload like:

users: [{ email: "", password: ""},...,{ email: "", password: ""}]

then we will use const [users, setUSers]=React.useState("") and we use the naming:

{users.map((_,i)=> {
  <TextField key={i}
  ...
  name={users[${i}].email}
  />
  ...
})}

Note on Promise.all and useEffect with async

We will fetch several pages, so make several calls. Then we will run several json() calls. Use Promise.all.

useEffect(() => {
  async function fetchData(){
    const urlApi2 = "https://reqres.in/api/users";
    const requests = [1, 2].map((page) => fetch(`${urlApi2}?page=${page}`));
    const response = await Promise.all(requests);
    const users = await Promise.all(response.map((r) => r.json()));
    return users.flatMap((u) => u.data);
  }
  fetchData().then(....)
}, []);

https://javascript.info/promise-api

Note on arrays of objects

replace an object in the array on attribute change

const A = [{"a":1, "b":true},{"a":2,"b":false}]
const [values, setValues] = useState(A)
// we want to replace with newValue = {"a":2,"b":true}
setValues(prev => {
  return prev.map(obj=> {
    if (obj.a===newValue.a) return {...obj, newValue.b};
  return obj
  })
})

Append to an array of objects if not present

const store = [
  { a: 1, b: true },
  { a: 2, b: false },
];
const [values, setValues] = useState(store);
const result = [
  { a: 2, b: true },
  { a: 3, b: false },
];
const keysOfAs = Array.from(store, ({ a }) => a); // array of keys values
setValues((prev) => {
  for (const obj of result) {
    if (!keysOfAs.includes(obj.a)) [...prev, obj];
  }
});

a Loader/Spinner

.loader {
  display: inline-block;
  width: 40px;
  height: 40px;
}

.loader:after {
  content: " ";
  display: block;
  width: 30px;
  height: 30px;
  margin: 1px;
  border-radius: 50%;
  border: 5px solid #fff;
  border-color: #fff transparent #fff transparent;
  animation: loader 1.2s linear infinite;
}

@keyframes loader {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

Make a phone call

<a href="tel:60305520">Call me!</a>

Bundle analysis

yarn add source-map-explorer and add "analyze": "source-map-explorer 'build/static/js/*.js'" in package.json.

Available Scripts

yarn start yarn build yarn analyze static-server from the "/build" folder.

With the conflict of Ruby's serve, used static-server to run the build file from the folder "./build". https://www.npmjs.com/package/static-server

yarn eject

Note: this is a one-way operation. Once you eject, you can’t go back!

If you aren’t satisfied with the build tool and configuration choices, you can eject at any time. This command will remove the single build dependency from your project.

Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except eject will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.

You don’t have to ever use eject. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.

Learn More

You can learn more in the Create React App documentation.

To learn React, check out the React documentation.

Code Splitting

This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting

Analyzing the Bundle Size

This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size

Making a Progressive Web App

This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app

Advanced Configuration

This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration

Deployment

This section has moved here: https://facebook.github.io/create-react-app/docs/deployment

yarn build fails to minify

This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify


navbar's People

Contributors

ndrean avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.