diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index b2e4391..0000000 --- a/.eslintrc.js +++ /dev/null @@ -1,39 +0,0 @@ -module.exports = { - "env": { - "browser": true, - "es2021": true - }, - "extends": [ - "eslint:recommended", - "plugin:react/recommended", - "next/core-web-vitals" - ], - "parserOptions": { - "ecmaFeatures": { - "jsx": true - }, - "ecmaVersion": "latest", - "sourceType": "module" - }, - "plugins": [ - "react" - ], - "rules": { - "indent": [ - "error", - 2 - ], - "linebreak-style": [ - "error", - "unix" - ], - "quotes": [ - "error", - "double" - ], - "semi": [ - "error", - "always" - ] - } -}; diff --git a/.gitignore b/.gitignore index fc066fd..4d29575 100644 --- a/.gitignore +++ b/.gitignore @@ -13,28 +13,11 @@ # misc .DS_Store -*.pem +.env.local +.env.development.local +.env.test.local +.env.production.local -# debug npm-debug.log* yarn-debug.log* yarn-error.log* -.pnpm-debug.log* - -# next.js -/.next/ -/out/ - -# local env files -.env -.env.* - -# vercel -.vercel - -#pwa -**/public/workbox-*.js -**/public/workbox-*.js.map -**/public/worker-*.js -**/public/sw.js -**/public/sw.js.map \ No newline at end of file diff --git a/README.md b/README.md index d8eeed0..d88893a 100644 --- a/README.md +++ b/README.md @@ -1,202 +1 @@ -
- - - -[![Contributors][contributors-shield]][contributors-url] -[![Forks][forks-shield]][forks-url] -[![Stargazers][stars-shield]][stars-url] -[![Issues][issues-shield]][issues-url] -[![MIT License][license-shield]][license-url] - - -
-
- - Logo - - -

everything

- -

- An all-in-one tool interacting with the inventory of everything. -
- - -
- Use App - · - Report Bug - · - Request Feature -

-
- - -
- Table of Contents -
    -
  1. - About The Project -
  2. -
  3. - Getting Started - -
  4. -
  5. Usage
  6. -
  7. Roadmap
  8. -
  9. Contributing
  10. -
  11. License
  12. -
  13. Contact
  14. -
  15. Acknowledgments
  16. -
-
- - - -## About The Project - - - -everything is one of several applications to aid in the creation of the [inventory of everything](https://everything.dev): a centralized database of real, tangible assets that can then be used as the foundation for decentralized marketplaces, services, tools-- in the effort to create a circular economy that makes sense for everyone. - -

(back to top)

- -### Built With - -- [![Next][next.js]][next-url] -- [![React][react.js]][react-url] - -

(back to top)

- - - -## Getting Started - -### Prerequisites - -- npm - ```sh - npm install npm@latest -g - ``` - -### Installation - -1. Clone the repo - ```sh - git clone https://github.com/near-everything/app.git - ``` -2. Install NPM packages - ```sh - npm install - ``` - -

(back to top)

- - - -## Usage - -**Make sure you have the [everything-api](https://github.com/near-everything/api) running locally!** - -1. Run the app in development mode: - -```sh - npm run dev -``` - -2. Open [http://localhost:3000](http://localhost:3000) to view it in the browser. - - The page will reload if you make edits.
- You will also see any lint errors in the console. - -3. When prompted (/login), login with any phone number, real or fake. This will be saved locally to the firebase emulator and will not be available for anyone else to see. Once you enter in your phone number and submit, check the docker logs for container "firebase-emulator:firebase-emulator" and there should be a message "To verify the phone number \_**\_, use the code \_\_\_**". Enter in this code on the login page. - -![Logging in tutorial][logging-in-tutorial] - - - -

(back to top)

- - - -## Roadmap - -- [ ] TBD... - -See the [open issues](https://github.com/near-everything/app/issues) for a full list of proposed features (and known issues). - -

(back to top)

- - - -## Contributing - -Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. - -If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". -Don't forget to give the project a star! Thanks again! - -1. Fork the Project -2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) -3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) -4. Push to the Branch (`git push origin feature/AmazingFeature`) -5. Open a Pull Request - -

(back to top)

- - - -## License - -Distributed under the MIT License. See `LICENSE.txt` for more information. - -

(back to top)

- - - -## Contact - -Elliot Braem - elliot@everything.dev - -

(back to top)

- - - -## Acknowledgments - -- README adapted from [Best-README-Template](https://github.com/othneildrew/Best-README-Template/blob/master/BLANK_README.md). - -

(back to top)

- - - - -[contributors-shield]: https://img.shields.io/github/contributors/near-everything/app.svg?style=for-the-badge -[contributors-url]: https://github.com/near-everything/app/graphs/contributors -[forks-shield]: https://img.shields.io/github/forks/near-everything/app.svg?style=for-the-badge -[forks-url]: https://github.com/near-everything/app/network/members -[stars-shield]: https://img.shields.io/github/stars/near-everything/app.svg?style=for-the-badge -[stars-url]: https://github.com/near-everything/app/stargazers -[issues-shield]: https://img.shields.io/github/issues/near-everything/app.svg?style=for-the-badge -[issues-url]: https://github.com/near-everything/app/issues -[license-shield]: https://img.shields.io/github/license/near-everything/app.svg?style=for-the-badge -[license-url]: https://github.com/near-everything/app/blob/main/LICENSE.txt -[logging-in-tutorial]: docs/logging-in.gif -[next.js]: https://img.shields.io/badge/next.js-000000?style=for-the-badge&logo=nextdotjs&logoColor=white -[next-url]: https://nextjs.org/ -[react.js]: https://img.shields.io/badge/React-20232A?style=for-the-badge&logo=react&logoColor=61DAFB -[react-url]: https://reactjs.org/ +# everything app diff --git a/app/api.js b/app/api.js deleted file mode 100644 index fcba2c7..0000000 --- a/app/api.js +++ /dev/null @@ -1,5 +0,0 @@ -import { GraphQLClient } from "graphql-request"; - -export const BUCKET_URL = "https://everything-1.s3.us-east-1.amazonaws.com/"; - -export const graphqlClient = new GraphQLClient("/api/graphql"); diff --git a/components/AttributeField.js b/components/AttributeField.js deleted file mode 100644 index e10e253..0000000 --- a/components/AttributeField.js +++ /dev/null @@ -1,76 +0,0 @@ -import React, { useState } from "react"; -import { useQueryClient } from "@tanstack/react-query"; -import { - useAttributeById, - useProposeOption, -} from "../features/collect/collectApi"; -import CreatableSelect from "./CreatableSelect"; - -const AttributeField = React.forwardRef(function AttributeField({ attributeId, setAttributeOption, value }, ref) { - const { data, isLoading, isError } = useAttributeById(attributeId, { - enabled: !!attributeId, - }); - const proposeOption = useProposeOption(); - const [loading, setLoading] = useState(false); - const queryClient = useQueryClient(); - - const prepareOptions = () => { - return data?.attribute?.relationships?.edges?.map((option) => ({ - value: option?.node?.option?.id, - label: option?.node?.option?.value, - })); - }; - const handleOnChange = (value) => { - if (!value) { - value = {}; - } - value.attributeId = attributeId; - setAttributeOption(value); - }; - - const handleProposeOption = (value) => { - proposeOption.mutate( - { value: value, attributeId: attributeId }, - { - onSuccess: async (response) => { - setLoading(true); - const { - proposeOption: { option }, - } = response; - setAttributeOption({ - value: option.id, - label: option.value, - attributeId: attributeId, - }); - await queryClient.refetchQueries(["attributeById", attributeId]); - setLoading(false); - }, - onError: (error) => { - console.log(error.message); - }, - } - ); - }; - - return ( - <> - {loading ? ( - <>Loading - ) : ( - - )} - - ); -}); - -export default AttributeField; diff --git a/components/Avatar.js b/components/Avatar.js deleted file mode 100644 index 909b808..0000000 --- a/components/Avatar.js +++ /dev/null @@ -1,20 +0,0 @@ -import React, { useEffect, useRef } from "react"; - -function Avatar({ color }) { - const ref = useRef(); - - useEffect(() => { - if (ref.current == null) { - return; - } - ref.current.style.backgroundColor = color; - }, [ref, color]); - - return ( -
-
-
- ); -} - -export default Avatar; diff --git a/components/Characteristic.js b/components/Characteristic.js deleted file mode 100644 index 825556b..0000000 --- a/components/Characteristic.js +++ /dev/null @@ -1,63 +0,0 @@ -import { useQuery } from "@tanstack/react-query"; -import { gql } from "graphql-request"; -import React from "react"; -import { graphqlClient } from "../app/api"; - -function Characteristic({ char }) { - const { - data: attr, - isLoading: attributeIsLoading, - isError: attributeIsError, - } = useQuery(["attributeById", char.attributeId], async () => { - const { attribute } = await graphqlClient.request( - gql` - query attributeById($attributeId: Int!) { - attribute(id: $attributeId) { - name - } - } - `, - { attributeId: char.attributeId } - ); - return attribute; - }); - const { - data: opt, - isLoading: optionIsLoading, - isError: optionIsError, - } = useQuery(["optionById", char.optionId], async () => { - const { option } = await graphqlClient.request( - gql` - query optionById($optionId: Int!) { - option(id: $optionId) { - value - } - } - `, - { optionId: char.optionId } - ); - return option; - }); - - return ( - <> - - - ); -} - -export default Characteristic; diff --git a/components/CreatableSelect.js b/components/CreatableSelect.js deleted file mode 100644 index d817b6d..0000000 --- a/components/CreatableSelect.js +++ /dev/null @@ -1,62 +0,0 @@ -import React from "react"; -import { components } from "react-select"; -import Creatable from "react-select/creatable"; - -const CreatableSelect = React.forwardRef(function CreatableSelect(props, ref) { - const { ...other } = props; - const Input = ({ ...rest }) => ; - - const customStyles = { - control: (base) => ({ - ...base, - background: "#1f2937", - color: "#9ca3af", - border: 0, - boxShadow: "none" - }), - menu: base => ({ - ...base, - // override border radius to match the box - borderRadius: 0, - // kill the gap - marginTop: 0, - color: "#1f2937", - fontWeight: 600, - background: "9ca3af" - }), - menuList: base => ({ - ...base, - // kill the white space on first and last option - padding: 0 - }), - placeholder: base => ({ - ...base, - color: "#9ca3af", - fontWeight: 600 - }), - singleValue: base => ({ - ...base, - color: "#fff", - }), - input: base => ({ - ...base, - color: "#9ca3af" - }) - }; - - return ( - <> - - - ); -}); - -export default CreatableSelect; diff --git a/components/Create/Camera.jsx b/components/Create/Camera.jsx deleted file mode 100644 index 66c609d..0000000 --- a/components/Create/Camera.jsx +++ /dev/null @@ -1,57 +0,0 @@ -import { useRef, useState } from "react"; -import Webcam from "react-webcam"; -import Layout from "../../containers/Layout"; -import CameraOverlay from "./CameraOverlay"; - -function Camera({ hideCamera, images, setImages }) { - const [facingMode, setFacingMode] = useState({ exact: "environment" }); - const webcamRef = useRef(null); - - const capture = () => { - const imageSrc = webcamRef.current.getScreenshot(); - const base64Data = new Buffer.from( - imageSrc.replace(/^data:image\/\w+;base64,/, ""), - "base64" - ); - const file = { - data: { - type: "image/jpeg" - }, - base64: true, - body: base64Data, - url: imageSrc - }; - setImages([...images, file]); - }; - - const videoConstraints = { - facingMode: facingMode, - }; - - const swapFacingMode = () => { - setFacingMode(facingMode === "user" ? { exact: "environment" } : "user"); - }; - - return ( - <> - - - - ); -} - -export default Camera; - -Camera.getLayout = function getLayout(page) { - return {page}; -}; diff --git a/components/Create/CameraOverlay.jsx b/components/Create/CameraOverlay.jsx deleted file mode 100644 index 7542615..0000000 --- a/components/Create/CameraOverlay.jsx +++ /dev/null @@ -1,70 +0,0 @@ -import { - faArrowUpFromBracket, - faRotate -} from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import Image from "next/image"; - -const imagePositions = [ - "left-1", - "left-3", - "left-5", - "left-7", - "left-9", - "left-11", -]; - -function CameraOverlay({swapFacingMode, capture, hideCamera, images}) { - return ( -
-
-
-
- -
-
- -
-
- {images.length > 0 ? ( -
- {images.map((imgSrc, index) => ( -
-
- -
-
- ))} -
- ) : ( -
- -
- )} -
-
-
-
- ); -} - -export default CameraOverlay; diff --git a/components/Create/CreateThingForm.jsx b/components/Create/CreateThingForm.jsx deleted file mode 100644 index cf52762..0000000 --- a/components/Create/CreateThingForm.jsx +++ /dev/null @@ -1,132 +0,0 @@ -import { useUser } from "@auth0/nextjs-auth0"; -import axios from "axios"; -import { useState } from "react"; -import { toast } from "react-toastify"; -import { BUCKET_URL } from "../../app/api"; -import { - useCreateMedia, - useCreateThing, -} from "../../features/collect/collectApi"; -import Description from "./../Description"; -import MediaReel from "./../MediaReel"; -import LoadingOverlay from "./LoadingOverlay"; -import ShowCameraButton from "./ShowCameraButton"; - -function CreateThingForm({ - showCamera, - images, - setImages, - attributes, - setAttributes, -}) { - const [loading, setLoading] = useState(false); - const { user } = useUser(); - const createThing = useCreateThing(); - const createMedia = useCreateMedia(); - - const handleSubmit = async () => { - setLoading(true); - createThing.mutate( - { - attributes: attributes - ?.filter( - (it) => - it.options?.value !== undefined && it.options?.value !== null - ) - .map((attr) => { - return { - attributeId: parseInt(attr.value), - optionId: attr.options.value, - }; - }), - ownerId: user.sub, - privacyType: "PRIVATE", - }, - { - onSuccess: async (response) => { - toast.success( - `successfully created thing ${response.createThing.thing.id}` - ); - await associateMedia(response.createThing.thing.id); - setAttributes([]); - setImages([]); - setLoading(false); - }, - onError: (err) => { - toast.error("Error creating thing, please try again."); - console.log(err.message); - setLoading(false); - }, - } - ); - }; - - const uploadFile = async (file, thingId) => { - let { data } = await axios.post("/api/s3/uploadFile", { - nickname: user.nickname, - type: file.data.type, - base64: file.base64 || false, - }); - - const url = data.url; - await axios.put(url, file.base64 ? file.body : file.data, { - headers: { - "Content-Type": file.data.type, - "Content-Encoding": file.base64 ? "base64" : null, - "Access-Control-Allow-Origin": "*", - }, - }); - - createMedia.mutate( - { - mediaUrl: BUCKET_URL + data.name, - thingId: thingId, - }, - { - onSuccess: async () => { - toast.success("created media successfully"); - }, - onError: () => { - toast.error("error creating media, please try again."); - }, - } - ); - }; - - const associateMedia = async (thingId) => { - for (const img of images) { - await uploadFile(img, thingId); - } - }; - - return ( - <> -
- - {loading ? null : } -
-
-
- -
-
-
- -
- {loading ? : null} - - ); -} - -export default CreateThingForm; diff --git a/components/Create/LoadingOverlay.jsx b/components/Create/LoadingOverlay.jsx deleted file mode 100644 index c247972..0000000 --- a/components/Create/LoadingOverlay.jsx +++ /dev/null @@ -1,18 +0,0 @@ -import { PulseLoader } from "react-spinners"; - -function LoadingOverlay() { - return ( -
-
- -
-
- ); -} - -export default LoadingOverlay; diff --git a/components/Create/ShowCameraButton.jsx b/components/Create/ShowCameraButton.jsx deleted file mode 100644 index 17589a1..0000000 --- a/components/Create/ShowCameraButton.jsx +++ /dev/null @@ -1,21 +0,0 @@ -import { faCamera } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; - -function ShowCameraButton({ showCamera }) { - return ( -
-
-
- -
-
-
- ); -} - -export default ShowCameraButton; diff --git a/components/Description.js b/components/Description.js deleted file mode 100644 index 7ebba88..0000000 --- a/components/Description.js +++ /dev/null @@ -1,109 +0,0 @@ -import { useQueryClient } from "@tanstack/react-query"; -import { useState } from "react"; -import { - useAttributes, - useProposeAttribute, -} from "../features/collect/collectApi"; -import CreatableSelect from "./CreatableSelect"; -import AttributeField from "./AttributeField"; - -function Description({ attributes, setAttributes }) { - const { data, isLoading, isError } = useAttributes(); - const proposeAttribute = useProposeAttribute(); - const [loading, setLoading] = useState(false); - const queryClient = useQueryClient(); - - const prepareOptions = () => { - return data?.map((option) => ({ - value: option?.node?.id, - label: option?.node?.name, - // value: option?.node?.attribute?.name + option?.node?.option?.value, - // label: `${option?.node?.attribute?.name}: ${option?.node?.option?.value}`, - })); - }; - - const handleOnChange = (value) => { - setAttributes(value); - }; - - const handleProposeAttribute = (value) => { - proposeAttribute.mutate(value, { - onSuccess: async (response) => { - setLoading(true); - const { - proposeAttribute: { attribute }, - } = response; - - setAttributes([ - ...attributes, - { value: attribute.id, label: attribute.name }, - ]); - await queryClient.refetchQueries(["attributes"]); - setLoading(false); - }, - onError: (error) => { - console.log(error.message); - }, - }); - }; - - const setAttributeOption = (value) => { - setAttributes( - attributes.map((attribute) => - attribute.value === value.attributeId - ? { ...attribute, options: value } - : attribute - ) - ); - }; - - const handleValue = (attributeId) => { - const match = attributes.find((it) => it.value === attributeId); - if (match.options?.value === undefined) { - return null; - } else { - return match.options; - } - }; - - return ( - <> - {loading ? ( - <>Loading... - ) : ( -
-

enter details below

- "not showing up? create new option"} - /> -
- )} - {attributes?.length > 0 ? ( -
- {attributes.map((attr) => ( - - ))} -
- ) : null} - - ); -} - -export default Description; diff --git a/components/DetailsModal.js b/components/DetailsModal.js deleted file mode 100644 index 969d168..0000000 --- a/components/DetailsModal.js +++ /dev/null @@ -1,93 +0,0 @@ -import { useEffect, useState } from "react"; -import collapse from "../utils/collapse"; -import MediaReel from "./MediaReel"; - -function DetailsModal({ thing }) { - const [images, setImages] = useState(); - - useEffect(() => { - if (thing.medias !== null && thing.medias !== undefined) { - const isolatedUrls = collapse(thing.medias).map( - (it) => (it.url = it.mediaUrl) - ); - setImages(isolatedUrls); - } - }, [thing]); - - return ( - <> - -