finish v0.1"
This commit is contained in:
@@ -3,8 +3,17 @@ import { classNames } from "../utilities/classNames"
|
||||
export const Button = ({ children, className = "", type = "text", ...props }) => {
|
||||
|
||||
return (
|
||||
<button type={type} className={classNames("border px-2 py-1 shadow rounded", className)} {...props}>
|
||||
<button type={type} className={classNames("border px-2 py-1 shadow transition-all duration-300 rounded", className)} {...props}>
|
||||
{children}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
export const SmallButton = ({ children, className = "", type = "button", ...props }) => {
|
||||
|
||||
return (
|
||||
<button type={type} className={classNames("border border-white flex items-center justify-center w-6 h-6 shadow transition-all duration-300 rounded-full cursor-pointer", className)} {...props}>
|
||||
{children}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
23
src/components/SVG.js
Normal file
23
src/components/SVG.js
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
const SVGSkeleton = ({paths, viewBox = "0 0 512 512", ...props}) => {
|
||||
return <svg xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox={viewBox}
|
||||
fill="currentColor"
|
||||
className={props.className ?? ''}
|
||||
{...props}>
|
||||
{props.title && <title>{ props.title }</title>}
|
||||
{paths}
|
||||
</svg>
|
||||
}
|
||||
|
||||
export const PlusSVG = (props) => SVGSkeleton({
|
||||
viewBox: "0 0 448 512",
|
||||
paths: <path d="M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z" />,
|
||||
...props
|
||||
})
|
||||
|
||||
export const EditSVG = (props) => SVGSkeleton({
|
||||
viewBox: "0 0 576 512",
|
||||
paths: <path d="M402.3 344.9l32-32c5-5 13.7-1.5 13.7 5.7V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h273.5c7.1 0 10.7 8.6 5.7 13.7l-32 32c-1.5 1.5-3.5 2.3-5.7 2.3H48v352h352V350.5c0-2.1.8-4.1 2.3-5.6zm156.6-201.8L296.3 405.7l-90.4 10c-26.2 2.9-48.5-19.2-45.6-45.6l10-90.4L432.9 17.1c22.9-22.9 59.9-22.9 82.7 0l43.2 43.2c22.9 22.9 22.9 60 .1 82.8zM460.1 174L402 115.9 216.2 301.8l-7.3 65.3 65.3-7.3L460.1 174zm64.8-79.7l-43.2-43.2c-4.1-4.1-10.8-4.1-14.8 0L436 82l58.1 58.1 30.9-30.9c4-4.2 4-10.8-.1-14.9z" />,
|
||||
...props
|
||||
})
|
||||
@@ -17,10 +17,10 @@ export const Tasks = () => {
|
||||
return <div className="mb-5">
|
||||
<h1>Tasks</h1>
|
||||
<div>
|
||||
{plants.map(plant => plant.actions.filter(action => taskIsRequired(action)).map(action => <div className="flex items-center gap-2">
|
||||
{plants.map(plant => plant.actions.filter(action => taskIsRequired(action)).map(action => <div className="flex items-center gap-2 my-2">
|
||||
<span><Button className="bg-blue-500 hover:bg-blue-700" onClick={() => doneTask(action.id)}>Done</Button></span>
|
||||
<span className="capitalize"><b>{plant.name}</b> {action.action_type}</span>
|
||||
<span> every {action.frequency} days {action.id}</span>
|
||||
<span><Button onClick={() => doneTask(action.id)}>Done</Button></span>
|
||||
<span> every {action.frequency} days</span>
|
||||
</div>))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import {createPortal, useRef} from "preact/compat";
|
||||
import { useContext, useEffect, useState } from "preact/hooks";
|
||||
import { Button } from "../components/Button";
|
||||
import {Modal, ModalTitle} from "../components/Modals";
|
||||
import {createPortal, useRef} from "preact/compat"
|
||||
import { useContext, useEffect, useState } from "preact/hooks"
|
||||
import {Button, SmallButton} from "../components/Button"
|
||||
import {Modal, ModalTitle} from "../components/Modals"
|
||||
import { PageLayout } from "../components/PageLayout"
|
||||
import { PlantsContext } from "../Contexts";
|
||||
import {InputField, SelectField} from "../components/Form";
|
||||
import {getPicture, storePicture} from "../utilities/pictures";
|
||||
import { PlantsContext } from "../Contexts"
|
||||
import {InputField, SelectField} from "../components/Form"
|
||||
import {getPicture, storePicture} from "../utilities/pictures"
|
||||
import {EditSVG, PlusSVG} from "../components/SVG";
|
||||
import {classNames} from "../utilities/classNames";
|
||||
|
||||
const Plant = ({id}) => {
|
||||
|
||||
@@ -46,21 +48,32 @@ const Plant = ({id}) => {
|
||||
}
|
||||
}
|
||||
|
||||
const addPicture = e => storePicture(document.getElementById("input-file"), id, setImage)
|
||||
const addPicture = e => storePicture(e, id)
|
||||
|
||||
return <PageLayout>
|
||||
<div className="flex justify-between">
|
||||
<div className="flex justify-between items-center">
|
||||
<h1>{ plant.name }</h1>
|
||||
<Button onClick={() => removePlant(plant)}>Delete</Button>
|
||||
<div>
|
||||
<Button className="bg-red-500" onClick={() => removePlant(plant)}>Delete</Button>
|
||||
</div>
|
||||
</div>
|
||||
<p>{ plant.description }</p>
|
||||
<div>
|
||||
<div className="relative">
|
||||
<img id="picture" ref={picture} src={getPicture(id)} alt=""/>
|
||||
<img id="output" src="" alt=""/>
|
||||
<input id="input-file" type="file" name="picture" onChange={addPicture}/>
|
||||
<SmallButton className="absolute top-2 left-2 cursor-pointer bg-blue-500 hover:bg-blue-700 max-w-[300px]">
|
||||
<label className="relative">
|
||||
<EditSVG className="w-4 h-4 block z-10 cursor-pointer" />
|
||||
<input id="input-file" type="file" name="picture" className="absolute opacity-0 max-w-[300px] w-0 h-0 inline" onChange={addPicture}/>
|
||||
</label>
|
||||
</SmallButton>
|
||||
</div>
|
||||
<div>
|
||||
<h2>Actions</h2>
|
||||
<div className="flex items-center gap-2">
|
||||
<h2>Actions</h2>
|
||||
<SmallButton className="bg-blue-500 hover:bg-blue-700 mb-2 mt-5" onClick={() => setAddModal(true)}>
|
||||
<PlusSVG className="w-4 h-4" />
|
||||
</SmallButton>
|
||||
</div>
|
||||
{plant.actions && plant.actions.map(action => {
|
||||
let isDone = false
|
||||
let lastTask = false
|
||||
@@ -68,15 +81,13 @@ const Plant = ({id}) => {
|
||||
lastTask = new Date(history()[action.id])
|
||||
isDone = lastTask.addDays(Number(action.frequency)) < (new Date())
|
||||
}
|
||||
console.log(lastTask, isDone)
|
||||
return <div key={action.action_type} className="flex items-center gap-2">
|
||||
return <div key={action.action_type} className="flex items-center gap-2 my-2">
|
||||
<span><Button className={classNames(isDone ? "bg-green-500 hover:bg-green-700" : "bg-blue-500 hover:bg-blue-700")} onClick={() => doneTask(action.id)}>Done</Button></span>
|
||||
<span className="capitalize">{action.action_type}</span>
|
||||
<span>evey {action.frequency} days</span>
|
||||
<span><Button onClick={() => doneTask(action.id)}>Done</Button></span>
|
||||
<span>last task {lastTask ? lastTask.toFrDate() : 'never'}</span>
|
||||
<span>every {action.frequency} days</span>
|
||||
<span className="text-gray-500">last task {lastTask ? lastTask.toFrDate() : 'never'}</span>
|
||||
</div>
|
||||
})}
|
||||
<Button className="bg-red-500" onClick={() => setAddModal(true)}>Add/Edit</Button>
|
||||
</div>
|
||||
|
||||
{createPortal(
|
||||
|
||||
@@ -14,11 +14,20 @@ export default function Profile() {
|
||||
setUser({...user, dark_mode: darkMode})
|
||||
}, [darkMode])
|
||||
|
||||
const handleChangeDarkMode = () => {
|
||||
setUser({...user, dark_mode: !user.dark_mode})
|
||||
}
|
||||
|
||||
return <PageLayout>
|
||||
<h1 className="dark:text-red-600">Profile</h1>
|
||||
<h1 className="">Profile</h1>
|
||||
<label htmlFor="dark_mode">
|
||||
<input type="checkbox"
|
||||
id="dark_mode"
|
||||
name="dark_mode"
|
||||
className="mr-2"
|
||||
checked={user.dark_mode}
|
||||
onChange={() => handleChangeDarkMode()} />
|
||||
Dark Mode
|
||||
<input type="checkbox" id="dark_mode" name="dark_mode" value={darkMode} onChange={() => setDarkMode(!darkMode)} />
|
||||
</label>
|
||||
</PageLayout>
|
||||
}
|
||||
@@ -7,28 +7,37 @@ export const getPicture = id => {
|
||||
return localStorage.getItem('picture-' + id ?? '')
|
||||
}
|
||||
|
||||
export const storePicture = (file, id, setter) => {
|
||||
var filesToUploads = document.getElementById("input-file").files;
|
||||
export const storePicture = (e, id) => {
|
||||
const files = e.target.files;
|
||||
let file = files[0];
|
||||
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
document.getElementById("picture").src = e.target.result;
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
|
||||
const filesToUploads = document.getElementById("input-file").files;
|
||||
file = filesToUploads[0];
|
||||
if (file) {
|
||||
const reader = new FileReader()
|
||||
let dataPicture
|
||||
|
||||
reader.onload = function (e) {
|
||||
console.log(e)
|
||||
var img = document.createElement("img");
|
||||
let img = document.createElement("img");
|
||||
img.src = e.target.result;
|
||||
|
||||
// Create your canvas
|
||||
var canvas = document.createElement("canvas");
|
||||
let canvas = document.createElement("canvas");
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.drawImage(img, 0, 0);
|
||||
|
||||
var MAX_WIDTH = 500;
|
||||
var MAX_HEIGHT = 500;
|
||||
var width = img.width;
|
||||
var height = img.height;
|
||||
const MAX_WIDTH = 300;
|
||||
const MAX_HEIGHT = 300;
|
||||
let width = img.width;
|
||||
let height = img.height;
|
||||
|
||||
// Add the resizing logic
|
||||
if (width > height) {
|
||||
if (width > MAX_WIDTH) {
|
||||
height *= MAX_WIDTH / width;
|
||||
@@ -41,68 +50,19 @@ export const storePicture = (file, id, setter) => {
|
||||
}
|
||||
}
|
||||
|
||||
//Specify the resizing result
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
let ctx2 = canvas.getContext("2d");
|
||||
ctx2.drawImage(img, 0, 0, width, height);
|
||||
console.log(img, ctx2)
|
||||
let dataurl = canvas.toDataURL(file.type);
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.drawImage(img, 0, 0, width, height);
|
||||
|
||||
dataPicture = canvas.toDataURL(file.type);
|
||||
document.getElementById("picture").src = dataPicture;
|
||||
|
||||
setTimeout(() => {
|
||||
localStorage.setItem(pictureName(id), dataPicture)
|
||||
}, 500)
|
||||
|
||||
console.log(dataurl)
|
||||
localStorage.setItem(pictureName(id), dataurl)
|
||||
setter(localStorage.getItem(pictureName(id)))
|
||||
document.getElementById("output").src = dataurl;
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
/*
|
||||
reader.addEventListener("load", function () {
|
||||
|
||||
let img = document.createElement("img");
|
||||
img.src = reader.result
|
||||
|
||||
var canvas = document.createElement("canvas");
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.drawImage(img, 0, 0);
|
||||
|
||||
var MAX_WIDTH = 500;
|
||||
var MAX_HEIGHT = 500;
|
||||
var width = img.width;
|
||||
var height = img.height;
|
||||
|
||||
// Add the resizing logic
|
||||
if (width > height) {
|
||||
if (width > MAX_WIDTH) {
|
||||
height *= MAX_WIDTH / width;
|
||||
width = MAX_WIDTH;
|
||||
}
|
||||
} else {
|
||||
if (height > MAX_HEIGHT) {
|
||||
width *= MAX_HEIGHT / height;
|
||||
height = MAX_HEIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
//Specify the resizing result
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.drawImage(img, 0, 0, width, height);
|
||||
|
||||
let dataurl = canvas.toDataURL(file.type);
|
||||
console.log(dataurl)
|
||||
// document.getElementById('picture').src = dataurl;
|
||||
|
||||
|
||||
localStorage.setItem(pictureName(id), dataurl)
|
||||
// localStorage.setItem(pictureName(id), reader.result)
|
||||
setter(localStorage.getItem(pictureName(id)))
|
||||
}, false);
|
||||
|
||||
if (imgPath) {
|
||||
reader.readAsDataURL(imgPath)
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
Reference in New Issue
Block a user