fix add plant

This commit is contained in:
Romulus21
2022-01-16 17:02:54 +01:00
parent dedda0157d
commit f35944752e
11 changed files with 7576 additions and 3004 deletions

28
.eslintrc.json Normal file
View File

@@ -0,0 +1,28 @@
{
"env": {
"browser": true,
"jest/globals": true
},
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": [
"jest"
],
"rules": {
"jest/no-disabled-tests": "warn",
"jest/no-focused-tests": "error",
"jest/no-identical-title": "error",
"jest/prefer-to-have-length": "warn",
"jest/valid-expect": "error",
"no-restricted-syntax": ["warn", {
"selector": "CallExpression[callee.object.name='console'][callee.property.name!=/^(warn|info)$/]",
"message": "Unexpected property on console object was called"
}],
"semi": [2, "never"]
}
}

10375
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -6,19 +6,38 @@
"scripts": { "scripts": {
"build": "preact build", "build": "preact build",
"serve": "sirv build --port 8080 --cors --single", "serve": "sirv build --port 8080 --cors --single",
"dev": "preact watch" "dev": "preact watch",
"lint": "eslint src",
"test": "jest"
},
"eslintConfig": {
"extends": "preact",
"ignorePatterns": [
"build/"
]
}, },
"devDependencies": { "devDependencies": {
"enzyme": "^3.10.0", "enzyme": "^3.10.0",
"enzyme-adapter-preact-pure": "^2.0.0", "enzyme-adapter-preact-pure": "^2.0.0",
"eslint": "^6.0.1",
"eslint-config-preact": "^1.1.0",
"eslint-plugin-jest": "^25.7.0",
"jest": "^24.9.0",
"jest-preset-preact": "^1.0.0",
"preact-cli": "^3.0.0", "preact-cli": "^3.0.0",
"preact-cli-tailwind": "^3.0.0",
"sirv-cli": "1.0.3" "sirv-cli": "1.0.3"
}, },
"dependencies": { "dependencies": {
"preact": "^10.3.2", "preact": "^10.3.2",
"preact-cli-tailwind": "^3.0.0",
"preact-render-to-string": "^5.1.4", "preact-render-to-string": "^5.1.4",
"preact-router": "^3.2.1", "preact-router": "^3.2.1"
"tailwindcss": "^2.2.19" },
"jest": {
"preset": "jest-preset-preact",
"setupFiles": [
"<rootDir>/tests/__mocks__/browserMocks.js",
"<rootDir>/tests/__mocks__/setupTests.js"
]
} }
} }

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,3 @@
import { classNames } from "../utilities/classNames"
export const Modal = ({children, isOpen, customClose = false, ...props}) => { export const Modal = ({children, isOpen, customClose = false, ...props}) => {
@@ -26,3 +25,5 @@ export const Modal = ({children, isOpen, customClose = false, ...props}) => {
export const ModalTitle = ({children, ...props}) => { export const ModalTitle = ({children, ...props}) => {
return <div className="bg-green-700 text-white text-2xl font-bold text-center -mx-2 -mt-2 p-2 rounded-tl rounded-tr" {...props}>{children}</div> return <div className="bg-green-700 text-white text-2xl font-bold text-center -mx-2 -mt-2 p-2 rounded-tl rounded-tr" {...props}>{children}</div>
} }
export const isCloseModal = e => e.target.classList.contains("overlay") || e.target.classList.contains("close-button")

View File

@@ -1,11 +1,14 @@
import { Link } from "preact-router/match" import { Link } from "preact-router/match"
import {getPicture} from "../utilities/pictures"; import {getPicture} from "../utilities/pictures"
import {InputField, TextAreaField} from "./Form"
import {Button} from "./Button"
import {useState} from "preact/hooks"
export const PlantThumb = ({ plant, children }) => { export const PlantThumb = ({ plant, children }) => {
return <Link href={`/plant/${plant.id}`} class="block h-48"> return <Link href={`/plant/${plant.id}`} class="block h-48">
<div className="bg-green-400 relative rounded shadow-lg flex flex-col"> <div className="bg-green-400 relative rounded shadow-lg flex flex-col">
<img src={getPicture(plant.id)} alt="" className="object-cover h-48 w-full rounded" /> <img src={getPicture(plant.id)} alt="" className="object-cover h-48 w-full min-h-48 min-w-48 rounded" />
<div className="bg-green-700 text-white p-2 text-center absolute bottom-0 w-full rounded-bl rounded-br"> <div className="bg-green-700 text-white p-2 text-center absolute bottom-0 w-full rounded-bl rounded-br">
{children} {children}
</div> </div>
@@ -15,3 +18,18 @@ export const PlantThumb = ({ plant, children }) => {
</div> </div>
</Link> </Link>
} }
export const PlantForm = ({children, plant, ...props}) => {
const [plantForm, setPlantForm] = useState(plant)
return <form onSubmit={e => props.onChange(e, plantForm)}>
<InputField name="name" className="mb-2 mt-5" value={plantForm.name} onChange={(e) => setPlantForm({ ...plantForm, name: e.target.value }) }>Name</InputField>
<TextAreaField name="description" className="mb-5" value={plantForm.description} onChange={(e) => setPlantForm({ ...plantForm, description: e.target.value })}>Description</TextAreaField>
<Button type="submit" className="block w-full mt-5 mb-2 bg-green-800 hover:bg-green-900 text-white mx-auto px-2 py-1 shadow">
{ children }
</Button>
</form>
}

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

View File

@@ -1,19 +1,17 @@
import { createPortal } from "preact/compat" import { createPortal } from "preact/compat"
import { useContext, useState } from "preact/hooks" import { useContext, useState } from "preact/hooks"
import { Button } from "../components/Button" import {isCloseModal, Modal, ModalTitle} from "../components/Modals"
import {Modal, ModalTitle} from "../components/Modals"
import { PageLayout } from "../components/PageLayout" import { PageLayout } from "../components/PageLayout"
import { PlantThumb } from "../components/Plants" import {PlantForm, PlantThumb} from "../components/Plants"
import { PlantsContext } from "../Contexts" import { PlantsContext } from "../Contexts"
import {InputField, TextAreaField} from "../components/Form"
import {Tasks} from "../components/Tasks" import {Tasks} from "../components/Tasks"
export const Home = () => { export const Home = () => {
const [addModal, setAddModal] = useState(false) const [addModal, setAddModal] = useState(false)
const [plantForm, setPlantForm] = useState({})
const { plants, addPlant } = useContext(PlantsContext) const { plants, addPlant } = useContext(PlantsContext)
const handleSubmit = (e) => { const handleSubmit = (e, plantForm) => {
console.log(e)
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()
addPlant(plantForm) addPlant(plantForm)
@@ -21,8 +19,7 @@ export const Home = () => {
} }
const handleCloseAddModal = (e) => { const handleCloseAddModal = (e) => {
if (e.target.classList.contains("overlay") || if (isCloseModal(e)) {
e.target.classList.contains("close-button")) {
setAddModal(false) setAddModal(false)
} }
} }
@@ -50,15 +47,7 @@ export const Home = () => {
<ModalTitle> <ModalTitle>
Add Plant Add Plant
</ModalTitle> </ModalTitle>
<form onSubmit={handleSubmit}> <PlantForm plant={{}} onChange={handleSubmit}>Add</PlantForm>
<InputField name="name" className="mb-2 mt-5" onChange={(e) => setPlantForm({ ...plantForm, name: e.target.value }) }>Name</InputField>
<TextAreaField name="description" className="mb-5" onChange={(e) => setPlantForm({ ...plantForm, description: e.target.value })}>Description</TextAreaField>
<Button type="submit" className="block w-full mt-5 mb-2 bg-green-800 hover:bg-green-900 text-white mx-auto px-2 py-1 shadow">
Add
</Button>
</form>
</Modal>, </Modal>,
document.getElementById('app') document.getElementById('app')
)} )}

View File

@@ -1,19 +1,20 @@
import {createPortal, useRef} from "preact/compat" import {createPortal, useRef} from "preact/compat"
import { useContext, useEffect, useState } from "preact/hooks" import { useContext, useEffect, useState } from "preact/hooks"
import {Button, SmallButton} from "../components/Button" import {Button, SmallButton} from "../components/Button"
import {Modal, ModalTitle} from "../components/Modals" import {isCloseModal, Modal, ModalTitle} from "../components/Modals"
import { PageLayout } from "../components/PageLayout" import { PageLayout } from "../components/PageLayout"
import { PlantsContext } from "../Contexts" import { PlantsContext } from "../Contexts"
import {InputField, SelectField, TextAreaField} from "../components/Form" import {InputField, SelectField} from "../components/Form"
import {getPicture, storePicture} from "../utilities/pictures" import {getPicture, storePicture} from "../utilities/pictures"
import {EditSVG, PlusSVG} from "../components/SVG"; import {EditSVG, PlusSVG} from "../components/SVG"
import {classNames} from "../utilities/classNames"; import {classNames} from "../utilities/classNames"
import {PlantForm} from "../components/Plants"
const Plant = ({id}) => { const Plant = ({id}) => {
const [addModal, setAddModal] = useState(false) const [addModal, setAddModal] = useState(false)
const [editModal, setEditModal] = useState(false) const [editModal, setEditModal] = useState(false)
const [plantForm, setPlantForm] = useState({}) const [deleteModal, setDeleteModal] = useState(false)
const {plants, editPlant, removePlant, addAction, doneTask, history} = useContext(PlantsContext) const {plants, editPlant, removePlant, addAction, doneTask, history} = useContext(PlantsContext)
const [plant, setPlant] = useState({}) const [plant, setPlant] = useState({})
const [actionForm, setActionForm] = useState({}) const [actionForm, setActionForm] = useState({})
@@ -42,7 +43,7 @@ const Plant = ({id}) => {
setAddModal(false) setAddModal(false)
} }
const handleEditSubmit = (e) => { const handleEditSubmit = (e, plantForm) => {
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()
editPlant(plantForm) editPlant(plantForm)
@@ -50,39 +51,41 @@ const Plant = ({id}) => {
setPlant(plantForm) setPlant(plantForm)
} }
const isCloseModal = e => e.target.classList.contains("overlay") || e.target.classList.contains("close-button")
const handleCloseAddModal = (e) => { const handleCloseAddModal = (e) => {
if (isCloseModal(e)) { if (isCloseModal(e)) {
setAddModal(false) setAddModal(false)
} }
} }
const handleOpenEditModal = () => {
setEditModal(true)
console.log(plant)
setPlantForm(plant)
}
const handleCloseEditModal = (e) => { const handleCloseEditModal = (e) => {
if (isCloseModal(e)) { if (isCloseModal(e)) {
setEditModal(false) setEditModal(false)
} }
} }
const handleCloseDeleteModal = (e) => {
if (isCloseModal(e)) {
setDeleteModal(false)
}
}
const handleDeletePlant = () => removePlant(plant)
const handleOpenEditModal = () => setEditModal(true)
const addPicture = e => storePicture(e, id) const addPicture = e => storePicture(e, id)
return <PageLayout> return <PageLayout>
<div className="flex justify-between items-center"> <div className="flex justify-between items-center">
<h1 className="my-2 flex-1 text-center">{ plant.name }</h1> <h1 className="my-2 flex-1 text-center">{ plant.name }</h1>
<div> <div>
<Button className="bg-blue-500" onClick={() => handleOpenEditModal()}>Edit</Button> <Button className="bg-blue-500 hover:bg-blue-700" onClick={() => handleOpenEditModal()}>Edit</Button>
{/*<Button className="bg-red-500" onClick={() => removePlant(plant)}>Delete</Button>*/} <Button className="bg-red-500 hover:bg-red-700" onClick={() => setDeleteModal(true)}>Delete</Button>
</div> </div>
</div> </div>
<div className="flex justify-around flex-wrap gap-5"> <div className="flex justify-around flex-wrap gap-5">
<div className="relative"> <div className="relative">
<img id="picture" ref={picture} src={getPicture(id)} alt=""/> <img id="picture" ref={picture} src={getPicture(id)} alt="" className="inline-block min-w-[300px] min-h-[200px] bg-gray-400"/>
<SmallButton className="absolute top-2 left-2 cursor-pointer bg-blue-500 hover:bg-blue-700 max-w-[300px]"> <SmallButton className="absolute top-2 left-2 cursor-pointer bg-blue-500 hover:bg-blue-700 max-w-[300px]">
<label className="relative"> <label className="relative">
<EditSVG className="w-4 h-4 block z-10 cursor-pointer" /> <EditSVG className="w-4 h-4 block z-10 cursor-pointer" />
@@ -90,7 +93,9 @@ const Plant = ({id}) => {
</label> </label>
</SmallButton> </SmallButton>
</div> </div>
<p className="flex-1">{ plant.description }</p> <div className="flex-1">
<p>{ plant.description }</p>
</div>
</div> </div>
<div> <div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
@@ -138,15 +143,17 @@ const Plant = ({id}) => {
<ModalTitle> <ModalTitle>
Edit Plant Edit Plant
</ModalTitle> </ModalTitle>
<form onSubmit={handleEditSubmit}> <PlantForm plant={plant} onChange={handleEditSubmit}>Add</PlantForm>
</Modal>,
app
)}
<InputField name="name" className="mb-2 mt-5" value={plantForm.name} onChange={(e) => setPlantForm({ ...plantForm, name: e.target.value }) }>Name</InputField> {createPortal(
<TextAreaField name="description" className="mb-5" value={plantForm.description} onChange={(e) => setPlantForm({ ...plantForm, description: e.target.value })}>Description</TextAreaField> <Modal isOpen={deleteModal} onChange={handleCloseDeleteModal}>
<ModalTitle>
<Button type="submit" className="block w-full mt-5 mb-2 bg-green-800 hover:bg-green-900 text-white mx-auto px-2 py-1 shadow"> Delete Plant ?
Edit </ModalTitle>
</Button> <Button className="bg-red-500 hover:bg-red-700 mt-10" onClick={handleDeletePlant}>Confirm delete plant</Button>
</form>
</Modal>, </Modal>,
app app
)} )}

View File

@@ -1,3 +1,4 @@
import { setupRouting } from 'preact-cli/sw' import { getFiles, setupPrecaching, setupRouting } from 'preact-cli/sw/'
setupRouting() setupRouting()
setupPrecaching(getFiles())

View File

@@ -4,7 +4,7 @@ const pictureName = id => {
} }
export const getPicture = id => { export const getPicture = id => {
return localStorage.getItem('picture-' + id ?? '') return localStorage.getItem('picture-' + id ?? '') ?? ""
} }
export const storePicture = (e, id) => { export const storePicture = (e, id) => {