Merge branch 'main' into adding-logo

This commit is contained in:
pratskalive08
2020-10-31 00:37:25 +05:30
committed by GitHub
19 changed files with 389 additions and 63 deletions

View File

@@ -1,8 +1,12 @@
# CadHub
CadHub aims to be a community website for javascript based code-cad. Currently trying to integrate [cascadeStudio](https://zalo.github.io/CascadeStudio/), but if successful plan to also integrate [jsCad](https://openjscad.org/).
CadHub aims to be a community website for javascript based code-cad. Currently trying to integrate [cascadeStudio](https://zalo.github.io/CascadeStudio/), but if successful plan to also integrate [JSCAD](https://openjscad.org/).
OpenScad has proven code-cad a much loved formate for cad-modeling. Joining code-cad to a mature language like javascript that has a package manager (npm) plus a community hub for sharing cad models like CadHub, we're going to build a thriving community.
<img src="https://raw.githubusercontent.com/Irev-Dev/repo-images/main/images/Parts%20Page.jpg">
<img src="https://raw.githubusercontent.com/Irev-Dev/repo-images/main/images/Part%20IDE%20-%20export%20expand%20state.jpg">
## Getting Started
Because we're integrating cascadeStudio, this is done some what crudely for the time being, so you'll need to clone the repo with submodules.
@@ -18,6 +22,11 @@ Install dependencies
yarn install
```
Initialise the db
``` terminal
yarn rw db up
```
### Fire up dev
```terminal
yarn rw dev
@@ -25,7 +34,7 @@ yarn rw dev
Your browser should open automatically to `http://localhost:8910` to see the web app. Lambda functions run on `http://localhost:8911` and are also proxied to `http://localhost:8910/.redwood/functions/*`.
You may need to register a account depending on what issue you are trying to tackle, This can be done by clicking the login button on the top right.
You may need to register a account depending on what issue you are trying to tackle, This can be done by clicking the login button on the top right. This will open up netlify's idenitiy modal asking for the websites url, since it will notice you developing locally. Enter `https://cadhub.xyz/` than use you email, verify your email and you should be set.
(some routes are protected, but permissions is a big area that needs a lot of work in the near future, so it's in a very incomplete state atm)
### Note:
@@ -40,3 +49,11 @@ If you not familiar with Redwood, never fear the main bit of tech it uses is Rea
## Styles
We're using tailwind utility classes so please try and use them as much as possible. Again if you not familiar, the [tailwind search](https://tailwindcss.com/) is fantastic, so searching for the css property you want to use will lead you to the correct class 99% of the time.
## Designs
In progress, though can be [seen on Figma](https://www.figma.com/file/VUh53RdncjZ7NuFYj0RGB9/CadHub?node-id=0%3A1)
<img src="https://raw.githubusercontent.com/Irev-Dev/repo-images/main/images/Part%20Page(1).jpg">
<img src="https://raw.githubusercontent.com/Irev-Dev/repo-images/main/images/User%20Page%20Edit.jpg">

View File

@@ -15,14 +15,14 @@ export const schema = gql`
input CreateUserInput {
email: String!
issuer: String!
# issuer: String!
image: String
bio: String
}
input UpdateUserInput {
email: String
issuer: String
# issuer: String
image: String
bio: String
}

View File

@@ -18,6 +18,7 @@
"@redwoodjs/forms": "^0.19.2",
"@redwoodjs/router": "^0.19.2",
"@redwoodjs/web": "^0.19.2",
"cloudinary-react": "^1.6.7",
"controlkit": "^0.1.9",
"golden-layout": "^1.5.9",
"jquery": "^3.5.1",
@@ -28,6 +29,8 @@
"prop-types": "^15.7.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-dropzone": "^11.2.1",
"react-image-crop": "^8.6.6",
"rich-markdown-editor": "^11.0.2",
"styled-components": "^5.2.0",
"three": "^0.118.3"

View File

@@ -0,0 +1,76 @@
import { useState } from 'react'
import Fab from '@material-ui/core/Fab'
import IconButton from '@material-ui/core/IconButton'
import Popover from '@material-ui/core/Popover'
import Svg from 'src/components/Svg'
const emojiMenu = ['🏆', '❤️', '👍', '😊', '😄', '🚀', '👏', '🙌']
const EmojiReaction = ({ emotes, callback = () => {} }) => {
const [isOpen, setIsOpen] = useState(false)
const [anchorEl, setAnchorEl] = useState(null)
const [popoverId, setPopoverId] = useState(undefined)
const openPopover = (target) => {
setAnchorEl(target)
setPopoverId('simple-popover')
setIsOpen(true)
}
const closePopover = () => {
setAnchorEl(null)
setPopoverId(undefined)
setIsOpen(false)
}
const togglePopover = ({ currentTarget }) => {
if (isOpen) {
return closePopover()
}
openPopover(currentTarget)
}
const handleEmojiClick = (emoji) => {
callback(emoji)
closePopover()
}
return [
<div className="flex justify-between">
<Fab size="medium" variant="round" aria-describedby={popoverId} onClick={togglePopover}>
<div className="bg-gray-200 border-2 m-px border-gray-300 text-gray-500 absolute inset-0 rounded-full flex justify-center items-center">
<Svg name="dots-vertical" />
</div>
</Fab>
<div>
{emotes.map((emote, i) => (
<IconButton key={`${emote.emoji}--${i}`} onClick={() => handleEmojiClick(emote.emoji)}>
{emote.emoji} <span>{emote.count}</span>
</IconButton>
))}
</div>
</div>,
<Popover
id={popoverId}
open={isOpen}
anchorEl={anchorEl}
onClose={closePopover}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'right',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center',
}}
>
{emojiMenu.map((emoji, i) => (
<IconButton key={`${emoji}-${i}}`} onClick={() => handleEmojiClick(emoji)}>{emoji}</IconButton>
))}
</Popover>,
]
}
export default EmojiReaction

View File

@@ -0,0 +1,7 @@
import EmojiReaction from './EmojiReaction'
export const generated = () => {
return <EmojiReaction />
}
export default { title: 'Components/EmojiReaction' }

View File

@@ -0,0 +1,11 @@
import { render } from '@redwoodjs/testing'
import EmojiReaction from './EmojiReaction'
describe('EmojiReaction', () => {
it('renders successfully', () => {
expect(() => {
render(<EmojiReaction />)
}).not.toThrow()
})
})

View File

@@ -0,0 +1,120 @@
import React, { useCallback, useState } from "react";
import { useDropzone } from "react-dropzone";
import Button from "@material-ui/core/Button";
import axios from 'axios'
import ReactCrop from 'react-image-crop'
import { Dialog } from '@material-ui/core'
import { Image as CloudinaryImage } from 'cloudinary-react'
import 'react-image-crop/dist/ReactCrop.css'
import Svg from 'src/components/Svg/Svg.js'
const CLOUDINARY_UPLOAD_PRESET = "CadHub_project_images";
const CLOUDINARY_UPLOAD_URL = "https://api.cloudinary.com/v1_1/irevdev/upload";
export default function ImageUploader({ onImageUpload, imageUrl }) {
const [isModalOpen, setIsModalOpen] = useState(false)
const [file, setFile] = useState()
const [cloudinaryId, setCloudinaryId] = useState(imageUrl)
const [imageObj, setImageObj] = useState()
const [crop, setCrop] = useState({
aspect: 16 / 9,
unit: '%',
width: 100,
});
async function handleImageUpload() {
const croppedFile = await getCroppedImg(imageObj, crop, 'avatar')
console.log(croppedFile)
const imageData = new FormData();
imageData.append('upload_preset', CLOUDINARY_UPLOAD_PRESET);
imageData.append('file', croppedFile);
let upload = axios.post(CLOUDINARY_UPLOAD_URL, imageData)
try {
const { data } = await upload
if (data && data.public_id !== "") {
onImageUpload({cloudinaryPublicId: data.public_id})
setCloudinaryId(data.public_id)
setIsModalOpen(false)
}
} catch (e) {
console.error('ERROR', e)
}
}
// Drag and Drop
const onDrop = useCallback(acceptedFiles => {
setIsModalOpen(true)
const fileReader = new FileReader()
fileReader.onload = () => {
setFile(fileReader.result)
}
fileReader.readAsDataURL(acceptedFiles[0])
}, []);
const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });
return (
<div className="m-8">
<div className="w-full relative" {...getRootProps()}>
{cloudinaryId && <button className="absolute z-10 w-full inset-0 bg-indigo-900 opacity-50 flex justify-center items-center">
<Svg name="pencil" strokeWidth={2} className="text-gray-300 h-48 w-48" />
</button>}
<input {...getInputProps()} />
{cloudinaryId && <div className="relative">
<CloudinaryImage
className="object-cover w-full rounded shadow"
cloudName="irevdev"
publicId={cloudinaryId}
width="600"
crop="scale"
/>
</div>}
{!cloudinaryId && <button className="absolute inset-0"></button>}
{!cloudinaryId && <div className="mt-3 text-indigo-500 border-dashed border border-indigo-500 py-8 text-center rounded-lg w-full">
Drop files here ...
or <span className="group flex w-full items-center justify-center py-4">
<span className="bg-indigo-500 shadow rounded text-gray-200 cursor-pointer p-2 hover:shadow-lg transform hover:-translate-y-1 transition-all duration-150">upload</span>
</span>
</div>}
</div>
<Dialog
open={isModalOpen}
onClose={() => setIsModalOpen(false)}
>
<div className="p-4">
<ReactCrop src={file} crop={crop} onImageLoaded={(image) => setImageObj(image)} onChange={newCrop => setCrop(newCrop)} />
<Button onClick={handleImageUpload} variant="outlined">Upload</Button>
</div>
</Dialog>
</div>
);
}
function getCroppedImg(image, crop, fileName) {
const canvas = document.createElement('canvas');
const scaleX = image.naturalWidth / image.width;
const scaleY = image.naturalHeight / image.height;
canvas.width = crop.width;
canvas.height = crop.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(
image,
crop.x * scaleX,
crop.y * scaleY,
crop.width * scaleX,
crop.height * scaleY,
0,
0,
crop.width,
crop.height
);
// As Base64 string
// const base64Image = canvas.toDataURL('image/jpeg');
// As a blob
return new Promise((resolve, reject) => {
canvas.toBlob(blob => {
blob.name = fileName;
resolve(blob);
}, 'image/jpeg', 1);
});
}

View File

@@ -4,23 +4,26 @@ import {
FieldError,
Label,
TextField,
TextAreaField,
Submit,
} from '@redwoodjs/forms'
import { useState } from 'react';
import { navigate, routes } from '@redwoodjs/router'
import { useFlash } from '@redwoodjs/web'
import ImageUploader from './ImageUploader.js'
import Editor from "rich-markdown-editor";
const PartForm = (props) => {
const { addMessage } = useFlash()
const [description, setDescription] = useState(props?.part?.description)
const [imageUrl, setImageUrl] = useState(props?.part?.mainImage)
const onSubmit = async (data, e) => {
await props.onSave({
...data,
description,
mainImage: imageUrl
}, props?.part?.id)
const shouldOpenIde = e?.nativeEvent?.submitter?.dataset?.openIde
if(shouldOpenIde) {
@@ -57,21 +60,8 @@ const PartForm = (props) => {
/>
<FieldError name="title" className="rw-field-error" />
<Label
name="mainImage"
className="p-0"
errorClassName="rw-label rw-label-error"
>
Main image
</Label>
<TextField
name="mainImage"
defaultValue={props.part?.mainImage}
className="rw-input"
errorClassName="rw-input rw-input-error"
validation={{ required: false }}
/>
<FieldError name="mainImage" className="rw-field-error" />
<ImageUploader onImageUpload={({cloudinaryPublicId}) => setImageUrl(cloudinaryPublicId)} />
<Label
name="description"

View File

@@ -1,5 +1,6 @@
import { useMutation, useFlash } from '@redwoodjs/web'
import { Link, routes } from '@redwoodjs/router'
import { Image as CloudinaryImage } from 'cloudinary-react'
import avatar from 'src/assets/harold.jpg'
@@ -52,7 +53,7 @@ const PartsList = ({ parts }) => {
}
return (
<div className="max-w-6xl mx-auto grid gap-8 grid-cols-4">
<div className="max-w-xs sm:max-w-sm md:max-w-2xl lg:max-w-5xl xl:max-w-6xl mx-auto grid gap-8 grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid- cols-4">
{parts.map((part) => {
return (
<Link
@@ -64,11 +65,19 @@ const PartsList = ({ parts }) => {
<div className="rounded-t-2xl bg-gray-900">
<div className="flex items-center p-2 text-indigo-200">
<div className="h-full absolute inset-0 text-6xl flex items-center justify-center text-indigo-700" ><span>?</span></div>
<div className="mr-4"><img src={avatar} className="rounded-full h-10 w-10" /></div>
<div className="mr-4">
<img src={avatar} className="rounded-full h-10 w-10" />
</div>
<h3>{part.title}</h3>
</div>
<div className="relative z-10">
<img className="h-full" src={part.mainImage}/>
<CloudinaryImage
className="object-cover w-full rounded shadow"
cloudName="irevdev"
publicId={part.mainImage}
width="300"
crop="scale"
/>
</div>
</div>
</Link>

View File

@@ -1,12 +1,18 @@
const Svg = ({name, className: className2}) => {
const Svg = ({name, className: className2, strokeWidth = 2}) => {
const svgs = {
"plus-circle": <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1} d="M12 9v3m0 0v3m0-3h3m-3 0H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z" />
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={strokeWidth} d="M12 9v3m0 0v3m0-3h3m-3 0H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>,
"plus":<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={strokeWidth} d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
</svg>,
"pencil": <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={strokeWidth} d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />
</svg>,
"dots-vertical": <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={strokeWidth} d="M12 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z" />
</svg>
}
return <div className={"h-10 w-10 " + className2}>

View File

@@ -1,6 +1,6 @@
import { useMutation, useFlash } from '@redwoodjs/web'
import { Link, routes, navigate } from '@redwoodjs/router'
import { Image as CloudinaryImage } from 'cloudinary-react'
const DELETE_USER_MUTATION = gql`
mutation DeleteUserMutation($id: Int!) {
deleteUser(id: $id) {
@@ -72,7 +72,13 @@ const User = ({ user }) => {
</tr>
<tr>
<th>Image</th>
<td>{user.image}</td>
<td><CloudinaryImage
className="object-cover w-full rounded shadow"
cloudName="irevdev"
publicId={user.image}
width="300"
crop="scale"
/></td>
</tr>
<tr>
<th>Bio</th>

View File

@@ -6,10 +6,21 @@ import {
TextField,
Submit,
} from '@redwoodjs/forms'
import { useState } from 'react';
import { navigate, routes } from '@redwoodjs/router'
import { useFlash } from '@redwoodjs/web'
import ImageUploader from '../PartForm/ImageUploader'
const UserForm = (props) => {
const onSubmit = (data) => {
props.onSave(data, props?.user?.id)
const { addMessage } = useFlash()
// const [bio, setBio] = useState(props?.user?.bio)
const [imageUrl, setImageUrl] = useState(props?.user?.image)
const onSubmit = async (data, e) => {
await props.onSave({
...data,
image: imageUrl
}, props?.user?.id)
addMessage('User updated.', { classes: 'rw-flash-success' })
}
return (
@@ -37,21 +48,7 @@ const UserForm = (props) => {
validation={{ required: true }}
/>
<FieldError name="email" className="rw-field-error" />
<Label
name="image"
className="rw-label"
errorClassName="rw-label rw-label-error"
>
Image
</Label>
<TextField
name="image"
defaultValue={props.user?.image}
className="rw-input"
errorClassName="rw-input rw-input-error"
/>
<FieldError name="image" className="rw-field-error" />
<ImageUploader onImageUpload={({cloudinaryPublicId}) => setImageUrl(cloudinaryPublicId)} />
<Label
name="bio"
@@ -65,6 +62,7 @@ const UserForm = (props) => {
defaultValue={props.user?.bio}
className="rw-input"
errorClassName="rw-input rw-input-error"
validation={{ required: true }}
/>
<FieldError name="bio" className="rw-field-error" />

View File

@@ -0,0 +1,16 @@
function UserPart({ userName, partName }) {
return (
<h3 className="text-xl font-roboto">
<div className="w-1 inline-block text-indigo-800 bg-indigo-800 mr-2">.</div>
<span className="text-gray-500">
{userName}
</span>
<div className="w-1 inline-block bg-gray-400 text-gray-400 mx-3 transform -skew-x-20" >.</div>
<span className="text-indigo-800">
{partName}
</span>
</h3>
)
}
export default UserPart

View File

@@ -8,6 +8,9 @@
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
@import url('https://fonts.googleapis.com/css2?family=Ropa+Sans&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,300;0,500;1,700&display=swap')
/**
* END --- TAILWIND GENERATOR EDIT
*/
@@ -33,7 +36,7 @@
body {
/* TODO can I use a tailwind class here? */
background-color: #4a5568;
background-color: #E5E5E5;
}
button, input, label, textarea {

View File

@@ -3,8 +3,10 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" type="image/png" href="/favi2.jpg" />
<title><%= htmlWebpackPlugin.options.title %></title>
<script>
// Install Cascade Studio as a Progressive Web App for Offline Access
// This needs to be put before ANY HTTP Requests are made, so it can cache them.

View File

@@ -12,36 +12,44 @@ const MainLayout = ({ children }) => {
return (
<>
<header>
<nav className="flex justify-between h-20 bg-gray-900">
<nav className="flex justify-between h-20 px-12 bg-gradient-to-r from-gray-900 to-indigo-900">
<ul className="flex items-center">
<li>
<Link to={routes.home()}>
<Tooltip title="We need a logo!" >
<img src={logo} style={{marginLeft : '50px'}}/>
<img src={logo} style={{marginLeft : '50px'}}/>
</Tooltip>
</Link>
</li>
<li>
<Tooltip title="Very alpha, there's lots of work todo" >
<div className="ml-8 flex">
<h2 className="text-indigo-200 text-2xl">CadHub</h2>
<div className="text-pink-500 pb-4 text-sm" >pre-alpha</div>
<div className="ml-12 flex">
{/* Because of how specific these styles are to this heading/logo and it doesn't need to be replicated else where as well as it's very precise with the placement of "pre-alpha" I think it's appropriate. */}
<h2 className="text-indigo-300 text-5xl font-ropa-sans py-1 tracking-wider" style={{letterSpacing: '0.3em'}}>CadHub</h2>
<div className="text-pink-400 text-sm font-bold font-ropa-sans" style={{paddingBottom: '2rem', marginLeft: '-1.8rem'}}>pre-alpha</div>
</div>
</Tooltip>
</li>
</ul>
<ul className="flex items-center">
<li className="mr-8 rounded-full border-2 border-indigo-300">
<li className="mr-8 h-10 w-10 rounded-full border-2 border-indigo-300 flex items-center justify-center">
<Link to={routes.newPart()}>
<Svg name="plus" className="text-indigo-300" />
</Link>
</li>
<li className="mr-12 p-px border-2 rounded-full border-indigo-300 text-indigo-200">
<a href="#" onClick={isAuthenticated ? logOut : logIn}>
{isAuthenticated ? 'Log Out' : 'Log In'}
<img src={avatar} className="rounded-full h-10 w-10" />
</a>
</li>
{
isAuthenticated ?
<li className="h-10 w-10 border-2 rounded-full border-indigo-300 text-indigo-200">
<a href="#" onClick={logOut}>
<img src={avatar} className="rounded-full object-cover" />
</a>
</li>:
<li>
<a href="#" className='text-indigo-200 font-semibold underline' onClick={logIn}>Sign in/up</a>
</li>
}
</ul>
</nav>
</header>

View File

@@ -16,7 +16,13 @@ module.exports = {
minHeight: {
'md': '28rem'
},
fontFamily: {
'ropa-sans': ['Ropa Sans', 'Arial', 'sans-serif'],
'roboto': ['Roboto', 'Arial', 'sans-serif'],
},
skew: {
'-20': "-20deg"
}
}
},
variants: {},

View File

@@ -4524,6 +4524,11 @@ atob@^2.1.2:
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
attr-accept@^2.2.1:
version "2.2.2"
resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.2.2.tgz#646613809660110749e92f2c10833b70968d929b"
integrity sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==
autoprefixer@9.8.6, autoprefixer@^9.4.5, autoprefixer@^9.7.2:
version "9.8.6"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.6.tgz#3b73594ca1bf9266320c5acf1588d74dea74210f"
@@ -5842,7 +5847,20 @@ clone-deep@^4.0.1:
kind-of "^6.0.2"
shallow-clone "^3.0.0"
clsx@^1.0.4:
cloudinary-core@^2.11.3:
version "2.11.3"
resolved "https://registry.yarnpkg.com/cloudinary-core/-/cloudinary-core-2.11.3.tgz#1440f61c6280485094aac87021b7e10f746dc69e"
integrity sha512-ZRnpjSgvx+LbSf+aEz5NKzxDB4Z0436aY/0BSDa90kAHiwAyd84VyEi95I74SE80e15Ri9t5S2xtksTXpzk9Xw==
cloudinary-react@^1.6.7:
version "1.6.7"
resolved "https://registry.yarnpkg.com/cloudinary-react/-/cloudinary-react-1.6.7.tgz#13a8c8660a36377edbc2482cdc7f061a12d60b19"
integrity sha512-u7Mx2CWEPG7Iy/3jn+JcvYu50uHwem4XokveNDqdnoeBJwit2B/ccfUtOUbpSfKAaEKLxXuPcQR5H8FEpIoavw==
dependencies:
cloudinary-core "^2.11.3"
prop-types "^15.6.2"
clsx@^1.0.4, clsx@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==
@@ -6159,7 +6177,7 @@ core-js-pure@^3.0.0, core-js-pure@^3.0.1:
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.5.tgz#c79e75f5e38dbc85a662d91eea52b8256d53b813"
integrity sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==
core-js@3.6.5, core-js@^3.0.1, core-js@^3.0.4, core-js@^3.2.1:
core-js@3.6.5, core-js@^3.0.1, core-js@^3.0.4, core-js@^3.2.1, core-js@^3.6.5:
version "3.6.5"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a"
integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==
@@ -7907,6 +7925,13 @@ file-loader@^6.0.0:
loader-utils "^2.0.0"
schema-utils "^2.6.5"
file-selector@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/file-selector/-/file-selector-0.2.2.tgz#76186ac94ea01a18262a1e9ee36a8815911bc0b4"
integrity sha512-tMZc0lkFzhOGlZUAkQ5iljPORvDX+nWEI+9C5nj9KT7Ax8bAUUtI/GYM8JFIjyKfKlQkJRC84D0UgxwDqRGvRQ==
dependencies:
tslib "^2.0.3"
file-system-cache@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/file-system-cache/-/file-system-cache-1.0.5.tgz#84259b36a2bbb8d3d6eb1021d3132ffe64cfff4f"
@@ -13096,6 +13121,15 @@ react-draggable@^4.0.3:
classnames "^2.2.5"
prop-types "^15.6.0"
react-dropzone@^11.2.1:
version "11.2.1"
resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-11.2.1.tgz#7544439ed2e27d1e4ac8efff5c6290b758cc29f5"
integrity sha512-AVWKQKKd4M8vIYzRC7QvvyzsGMrz6UAtAYW2WvSlEmstHKXhHL3CAq9LUzALfzMcDd2mxmntSNcpxij0w7U4qA==
dependencies:
attr-accept "^2.2.1"
file-selector "^0.2.2"
prop-types "^15.7.2"
react-error-overlay@^6.0.1, react-error-overlay@^6.0.3:
version "6.0.7"
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.7.tgz#1dcfb459ab671d53f660a991513cb2f0a0553108"
@@ -13141,6 +13175,15 @@ react-hotkeys@2.0.0:
dependencies:
prop-types "^15.6.1"
react-image-crop@^8.6.6:
version "8.6.6"
resolved "https://registry.yarnpkg.com/react-image-crop/-/react-image-crop-8.6.6.tgz#326f85b4da63c2f39a610f8832abea5d551a338f"
integrity sha512-2iQHKp12dYb6Fu2iN/Mg19BeLMgrbdOuKkU9k0RH7CHX6ZZylOlhfCM3/RsECbKnjGJRtGpXniGF+/i9CGis1A==
dependencies:
clsx "^1.1.1"
core-js "^3.6.5"
prop-types "^15.7.2"
react-is@^16.12.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
@@ -15204,6 +15247,11 @@ tslib@^1.10.0, tslib@^1.11.1, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.2, tslib@^1
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043"
integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==
tslib@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c"
integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==
tslib@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.1.tgz#410eb0d113e5b6356490eec749603725b021b43e"