From 53e8e16191dd30a38afeb8dfe03ce016c41dcd65 Mon Sep 17 00:00:00 2001 From: Artur AGH Date: Tue, 31 Oct 2023 11:38:01 +0100 Subject: [PATCH] adding canvas size button to sidebar - without fonctionality --- src/components/delete-shape-button.tsx | 25 +++++++++ src/components/image-toolbar.tsx | 31 ++++++++++- src/components/layout/sidebar/sidebar.tsx | 2 + src/components/layout/sidebar/size-select.tsx | 54 +++++++++++++++++++ src/components/text-toolbar.tsx | 7 +-- src/components/toolbar.tsx | 15 +++++- src/store/app.slice.ts | 50 ++++++++++++----- 7 files changed, 161 insertions(+), 23 deletions(-) create mode 100644 src/components/delete-shape-button.tsx create mode 100644 src/components/layout/sidebar/size-select.tsx diff --git a/src/components/delete-shape-button.tsx b/src/components/delete-shape-button.tsx new file mode 100644 index 0000000..d698f0f --- /dev/null +++ b/src/components/delete-shape-button.tsx @@ -0,0 +1,25 @@ +import React from "react"; +import { Button } from "@/components/ui/button"; +import { deleteShape } from "@/store/app.slice"; +import { useAppDispatch } from "@/hooks"; +import { BsTrash3 } from "react-icons/bs"; + +type Props = { + selectedItemId: string; +}; + +export const DeleteShapeButton = ({ selectedItemId }: Props) => { + const dispatch = useAppDispatch(); + const deleteTextHandler = (selectedItemId: string) => { + dispatch(deleteShape(selectedItemId)); + }; + return ( + + ); +}; diff --git a/src/components/image-toolbar.tsx b/src/components/image-toolbar.tsx index 0c10c48..ac5f237 100644 --- a/src/components/image-toolbar.tsx +++ b/src/components/image-toolbar.tsx @@ -1,5 +1,32 @@ import React from "react"; +import { DeleteShapeButton } from "@/components/delete-shape-button"; +import { Button } from "@/components/ui/button"; +import { TbFlipHorizontal, TbFlipVertical } from "react-icons/tb"; +import { Toggle } from "@/components/ui/toggle"; +import { useAppDispatch } from "@/hooks"; +import { updateImage } from "@/store/app.slice"; -export function ImageToolbar() { - return
Image toolbar
; +export function ImageToolbar({ selectedItemId, currentImage }) { + const dispatch = useAppDispatch(); + const flipImageVerticaly = (selectedItemId) => { + dispatch( + updateImage({ + id: selectedItemId, + }), + ); + }; + + const flipImageHorizontaly = () => { + console.log("Horizontal Flip"); + }; + return ( + <> + + + + + + + + ); } diff --git a/src/components/layout/sidebar/sidebar.tsx b/src/components/layout/sidebar/sidebar.tsx index 9bf912f..2c0a375 100644 --- a/src/components/layout/sidebar/sidebar.tsx +++ b/src/components/layout/sidebar/sidebar.tsx @@ -3,10 +3,12 @@ import ImageInput from "@/components/layout/sidebar/image-input"; import { SelectTemplate } from "@/components/layout/sidebar/select-template"; import { Button } from "@/components/ui/button"; import { useAppDispatch } from "@/hooks"; +import SizeSelect from "@/components/layout/sidebar/size-select"; export function Sidebar() { return (
+ diff --git a/src/components/layout/sidebar/size-select.tsx b/src/components/layout/sidebar/size-select.tsx new file mode 100644 index 0000000..3516857 --- /dev/null +++ b/src/components/layout/sidebar/size-select.tsx @@ -0,0 +1,54 @@ +import React, { useState } from "react"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; +import { Button } from "@/components/ui/button"; +import { PiTextT } from "react-icons/pi"; +import { Card, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"; +import { Textarea } from "@/components/ui/textarea"; +import { addText } from "@/store/app.slice"; +import { SlSizeFullscreen } from "react-icons/sl"; + +const SizeSelect = () => { + const [open, setOpen] = useState(false); + + const handleSizeSelect = () => { + setOpen(false); + }; + return ( + + + + + + + + Sélectionnez la taille d'étiquette + + +
+ + + +
+ + + + + +
+
+
+ ); +}; +export default SizeSelect; diff --git a/src/components/text-toolbar.tsx b/src/components/text-toolbar.tsx index ab6a829..1cca126 100644 --- a/src/components/text-toolbar.tsx +++ b/src/components/text-toolbar.tsx @@ -9,6 +9,7 @@ import { type TransformableTextProps } from "@/components/transformable-text"; import { Button } from "@/components/ui/button"; import { useAppDispatch } from "@/hooks"; import { deleteShape } from "@/store/app.slice"; +import { DeleteShapeButton } from "@/components/delete-shape-button"; type Props = { selectedItemId: string; @@ -22,9 +23,6 @@ export const TextToolbar = ({ }: Props) => { const dispatch = useAppDispatch(); if (!currentText) return null; - const deleteTextHandler = (selectedItemId) => { - dispatch(deleteShape(selectedItemId)); - }; return ( <> @@ -53,9 +51,6 @@ export const TextToolbar = ({ currentText={currentText} selectedItemId={selectedItemId} /> - ); }; diff --git a/src/components/toolbar.tsx b/src/components/toolbar.tsx index 436fbeb..bd8f7b1 100644 --- a/src/components/toolbar.tsx +++ b/src/components/toolbar.tsx @@ -3,6 +3,10 @@ import { ImageToolbar } from "@/components/image-toolbar"; import { TextToolbar } from "@/components/text-toolbar"; import { useAppDispatch, useAppSelector } from "@/hooks"; import { updateText } from "@/store/app.slice"; +import { BsTrash3 } from "react-icons/bs"; +import { Button } from "@/components/ui/button"; +import { DeleteShapeButton } from "@/components/delete-shape-button"; +import { Separator } from "@/components/ui/separator"; export const Toolbar = () => { const dispatch = useAppDispatch(); @@ -27,7 +31,6 @@ export const Toolbar = () => { return (
- {currentImage && } {currentText && ( { onTextColorChange={handleTextColorChange} /> )} + {currentImage && ( + + )} + + + +
); }; diff --git a/src/store/app.slice.ts b/src/store/app.slice.ts index 0488bcf..e0655a7 100644 --- a/src/store/app.slice.ts +++ b/src/store/app.slice.ts @@ -3,10 +3,10 @@ import type { TransformableTextProps } from "@/components/transformable-text"; import type { PayloadAction } from "@reduxjs/toolkit"; import type { ChangeEvent } from "react"; -import { createSlice } from "@reduxjs/toolkit"; +import { createSlice, current } from "@reduxjs/toolkit"; import { v1 } from "uuid"; import type { TextConfig } from "konva/lib/shapes/Text"; -import { RootState } from "./store"; +import type { ImageConfig } from "konva/lib/shapes/Image"; const initialState = { selectedItemId: null as string | null, @@ -22,26 +22,30 @@ const defaultTextConfig = { fontFamily: "Roboto", }; +const defaultImageConfig = {}; + export const appSlice = createSlice({ name: "app", initialState, reducers: { + addText: (state, action: PayloadAction<{ initialValue: string }>) => { + const textId = v1(); + state.texts.push({ + text: action.payload.initialValue, + id: textId, + ...defaultTextConfig, + }); + + console.log(current(state.texts)); + }, + addImage: (state, action: PayloadAction>) => { const file = action.payload.target.files?.[0]; if (!file) return; const imageId = v1(); const imageUrl = URL.createObjectURL(file); state.images.push({ imageUrl, id: imageId }); - }, - - addText: (state, action: PayloadAction<{ initialValue: string }>) => { - const textId = v1(); - console.log(state); - state.texts.push({ - text: action.payload.initialValue, - id: textId, - ...defaultTextConfig, - }); + console.log(current(state.images)); }, selectItem: (state, action: PayloadAction) => { @@ -54,7 +58,7 @@ export const appSlice = createSlice({ updateText: ( state, - action: PayloadAction<{ id: string } & Partial>, + action: PayloadAction<{ id: string } & Partial>, ) => { const textToUpdateIndex = state.texts.findIndex( (t) => t.id === action.payload.id, @@ -69,11 +73,28 @@ export const appSlice = createSlice({ }; }, + updateImage: ( + state, + action: PayloadAction<{ id: string } & Partial>, + ) => { + const imageToUpdateIndex = state.images.findIndex( + (img) => img.id === action.payload.id, + ); + const imageToUpdate = state.images[imageToUpdateIndex]; + + if (!imageToUpdate) return; + + state.images[imageToUpdateIndex] = { + ...imageToUpdate, + ...action.payload, + }; + }, + deleteShape: (state, action: PayloadAction) => { - console.log(state.texts); return { ...state, texts: state.texts.filter((shape) => shape.id !== action.payload), + images: state.images.filter((shape) => shape.id !== action.payload), }; }, }, @@ -85,5 +106,6 @@ export const { selectItem, deselectItem, updateText, + updateImage, deleteShape, } = appSlice.actions;