From e94fabaf21df417a3e758e4c31f8fd786e6dfdcf Mon Sep 17 00:00:00 2001 From: akaishikiso Date: Sat, 24 May 2025 23:55:01 +0900 Subject: [PATCH 1/2] =?UTF-8?q?:sparkles:=20feat:=20Step3=E3=81=8B?= =?UTF-8?q?=E3=82=89=E3=83=97=E3=83=AC=E3=83=93=E3=83=A5=E3=83=BC=E7=94=BB?= =?UTF-8?q?=E9=9D=A2=E3=81=BE=E3=81=A7=E3=81=AE=E5=B0=8E=E7=B7=9A=E3=81=AE?= =?UTF-8?q?=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FoldMethodSelectPanel/index.tsx | 8 +- .../PreviewPanel/index.module.scss | 32 ++++++++ .../PreviewPanel/index.tsx | 43 +++++++++++ .../FoldMethodControlPanel/index.tsx | 77 ++++++++++++------- .../hooks/useRegisterOrigami/index.tsx | 29 +++++-- src/components/OrigamiPost/index.tsx | 14 +++- 6 files changed, 163 insertions(+), 40 deletions(-) create mode 100644 src/components/OrigamiPost/FoldMethodControlPanel/PreviewPanel/index.module.scss create mode 100644 src/components/OrigamiPost/FoldMethodControlPanel/PreviewPanel/index.tsx diff --git a/src/components/OrigamiPost/FoldMethodControlPanel/FoldMethodSelectPanel/index.tsx b/src/components/OrigamiPost/FoldMethodControlPanel/FoldMethodSelectPanel/index.tsx index 64e4b12..7ab2e7f 100644 --- a/src/components/OrigamiPost/FoldMethodControlPanel/FoldMethodSelectPanel/index.tsx +++ b/src/components/OrigamiPost/FoldMethodControlPanel/FoldMethodSelectPanel/index.tsx @@ -15,7 +15,7 @@ type Props = { totalNumber: number; currentNumber: number; isFoldFrontSide: boolean; - handleRegisterOrigami: () => void; + handleFinishFolding: () => void; origamiDescription: string; handleOrigamiDescriptionChange: (description: string) => void; }; @@ -30,7 +30,7 @@ export const FoldMethodSelectPanel: React.FC = ({ totalNumber, currentNumber, isFoldFrontSide, - handleRegisterOrigami, + handleFinishFolding, origamiDescription, handleOrigamiDescriptionChange, }) => { @@ -85,11 +85,11 @@ export const FoldMethodSelectPanel: React.FC = ({ ); diff --git a/src/components/OrigamiPost/FoldMethodControlPanel/PreviewPanel/index.module.scss b/src/components/OrigamiPost/FoldMethodControlPanel/PreviewPanel/index.module.scss new file mode 100644 index 0000000..a2c801d --- /dev/null +++ b/src/components/OrigamiPost/FoldMethodControlPanel/PreviewPanel/index.module.scss @@ -0,0 +1,32 @@ +@use "@/styles/variables" as *; + +.container { + display: flex; + flex-direction: column; + gap: 2.5rem; + align-items: start; + width: 100%; + + .title { + font-size: 1.5rem; + font-weight: bold; + } + + .descriptions { + display: flex; + flex-direction: column; + gap: 1rem; + width: 100%; + + .gif { + border: solid 1px #c7c7c7; + } + } + + .buttons { + width: 100%; + justify-content: center; + display: flex; + gap: 1rem; + } +} diff --git a/src/components/OrigamiPost/FoldMethodControlPanel/PreviewPanel/index.tsx b/src/components/OrigamiPost/FoldMethodControlPanel/PreviewPanel/index.tsx new file mode 100644 index 0000000..39fae83 --- /dev/null +++ b/src/components/OrigamiPost/FoldMethodControlPanel/PreviewPanel/index.tsx @@ -0,0 +1,43 @@ +import styles from "./index.module.scss"; +import { NextStepButton } from "../ui/NextStepButton"; +import { PrevStepButton } from "../ui/PrevStepButton"; +import Image from "next/image"; +import { Button } from "@radix-ui/themes"; + +type Props = { + handlePrevStep: () => void; + handleNextStep: () => void; + handleRegisterOrigami: () => void; +}; + +export const PreviewPanel: React.FC = ({ + handlePrevStep, + handleNextStep, + handleRegisterOrigami, +}) => { + return ( +
+

折り紙を公開する

+
+

+ 動画:カーソルが動いて、折り紙の折る側の面を選択している。 +
+
+ + + +
+
+ ); +}; diff --git a/src/components/OrigamiPost/FoldMethodControlPanel/index.tsx b/src/components/OrigamiPost/FoldMethodControlPanel/index.tsx index ca20bd8..10e290d 100644 --- a/src/components/OrigamiPost/FoldMethodControlPanel/index.tsx +++ b/src/components/OrigamiPost/FoldMethodControlPanel/index.tsx @@ -6,6 +6,7 @@ import { FoldTargetSelectPanel } from "./FoldTargetSelectPanel"; import { FoldMethodSelectPanel } from "./FoldMethodSelectPanel"; import { FoldStepSegmentedControl } from "./ui/FoldStepSegmentedControl"; import React from "react"; +import { PreviewPanel } from "./PreviewPanel"; export type Step = "axis" | "target" | "fold"; @@ -29,6 +30,8 @@ type Props = { inputStepLength: number; procedureIndex: number; handleChangeStep: (step: number) => void; + handleFinishFolding: () => void; + isFinishFolding: boolean; }; export const FoldMethodControlPanel: React.FC = ({ @@ -51,41 +54,57 @@ export const FoldMethodControlPanel: React.FC = ({ inputStepLength, procedureIndex, handleChangeStep, + handleFinishFolding, + isFinishFolding, }) => { return (
- {currentStep === "axis" && ( - - )} - {currentStep === "target" && ( - - )} - {currentStep === "fold" && ( - + {currentStep === "axis" && ( + + )} + {currentStep === "target" && ( + + )} + {currentStep === "fold" && ( + + )} +
+ +
+ + ) : ( + )} -
- -
); }; diff --git a/src/components/OrigamiPost/hooks/useRegisterOrigami/index.tsx b/src/components/OrigamiPost/hooks/useRegisterOrigami/index.tsx index 9dd6169..2d05295 100644 --- a/src/components/OrigamiPost/hooks/useRegisterOrigami/index.tsx +++ b/src/components/OrigamiPost/hooks/useRegisterOrigami/index.tsx @@ -15,6 +15,7 @@ type UseRegisterOrigami = (props: { cameraRef: React.MutableRefObject; rendererRef: React.MutableRefObject; }) => { + handleDecideProcedure: () => Model | undefined; handleRegisterOrigami: () => void; }; @@ -39,14 +40,10 @@ export const useRegisterOrigami: UseRegisterOrigami = ({ const isMoveBoardsRight = step.isMoveBoardsRight; const description = step.description; - const handleRegisterOrigami = () => { - //折り面、折り線、タイトルがない場合は登録できない。 + const handleDecideProcedure = () => { + //折り面、折り線がない場合は登録できない。 if (!moveBoards.length) return; if (!rotateAxis.length) return; - if (!origamiName.length) { - console.error("Origami name is required."); - return; - } // xy平面上の板のうち、z座標が大きい順に、numberOfMoveBoards枚を折る // それ以外の板は無条件で折る @@ -64,6 +61,10 @@ export const useRegisterOrigami: UseRegisterOrigami = ({ // TODO: ProcedureとinputStepObjectの整合性を取る // 現在はnewProcedureだけが入っているが、それまでの手順は入っていない const procedures = { [procedureIndex]: newProcedure }; + if (!procedures) { + console.error("Procedure is null."); + return; + } // idとimageUrlはDBから取得するため、空文字を設定 const model: Model = { @@ -74,6 +75,21 @@ export const useRegisterOrigami: UseRegisterOrigami = ({ procedure: procedures, }; + return model; + }; + + const handleRegisterOrigami = () => { + // タイトル、折り紙モデルがない場合は登録できない。 + if (!origamiName.length) { + console.error("Origami name is required."); + return; + } + const model = handleDecideProcedure(); + if (!model) { + console.error("Failed to decide procedure."); + return; + } + const scene = sceneRef.current; const camera = cameraRef.current; const renderer = rendererRef.current; @@ -100,5 +116,6 @@ export const useRegisterOrigami: UseRegisterOrigami = ({ return { handleRegisterOrigami, + handleDecideProcedure, }; }; diff --git a/src/components/OrigamiPost/index.tsx b/src/components/OrigamiPost/index.tsx index 7070799..62c64bc 100644 --- a/src/components/OrigamiPost/index.tsx +++ b/src/components/OrigamiPost/index.tsx @@ -34,6 +34,7 @@ export const OrigamiPost = () => { const { origamiName, handleOrigamiNameChange } = useOrigamiName(); const { origamiColor, handleOrigamiColorChange } = useOrigamiColor(); const [popup, setPopup] = useState(null); + const [isFinishFolding, setIsFinishFolding] = useState(false); // 折り方選択で、現在のステップを保持する変数 const [currentStep, setCurrentStep] = useAtom(currentStepAtom); @@ -134,7 +135,7 @@ export const OrigamiPost = () => { const { handleDecideFoldMethod }: { handleDecideFoldMethod: () => void } = useDecideFoldMethod(); - const { handleRegisterOrigami } = useRegisterOrigami({ + const { handleDecideProcedure, handleRegisterOrigami } = useRegisterOrigami({ origamiName, origamiColor, sceneRef, @@ -146,6 +147,15 @@ export const OrigamiPost = () => { setPopup(null); }; + const handleFinishFolding = () => { + const model = handleDecideProcedure(); + if (model) { + setIsFinishFolding(true); + } else { + console.error("Failed to decide procedure."); + } + }; + return ( <> @@ -178,6 +188,8 @@ export const OrigamiPost = () => { inputStepLength={inputStepLength} procedureIndex={procedureIndex} handleChangeStep={handleChangeStep} + handleFinishFolding={handleFinishFolding} + isFinishFolding={isFinishFolding} /> {popup?.message.length && ( From 2b4c762669e224eaf3481f8500ba753448d14516 Mon Sep 17 00:00:00 2001 From: akaishikiso Date: Sun, 25 May 2025 00:45:50 +0900 Subject: [PATCH 2/2] =?UTF-8?q?:sparkles:=20feat:=20=E3=83=97=E3=83=AC?= =?UTF-8?q?=E3=83=93=E3=83=A5=E3=83=BC=E7=94=BB=E9=9D=A2=E3=81=AE=E3=83=91?= =?UTF-8?q?=E3=83=8D=E3=83=ABUI=E4=BD=9C=E6=88=90=EF=BC=88step1=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PreviewPanel/index.module.scss | 73 ++++++++++++++++++- .../PreviewPanel/index.tsx | 61 ++++++++++++---- .../FoldMethodControlPanel/index.tsx | 20 +++-- src/components/OrigamiPost/index.tsx | 4 + 4 files changed, 138 insertions(+), 20 deletions(-) diff --git a/src/components/OrigamiPost/FoldMethodControlPanel/PreviewPanel/index.module.scss b/src/components/OrigamiPost/FoldMethodControlPanel/PreviewPanel/index.module.scss index a2c801d..b4d697f 100644 --- a/src/components/OrigamiPost/FoldMethodControlPanel/PreviewPanel/index.module.scss +++ b/src/components/OrigamiPost/FoldMethodControlPanel/PreviewPanel/index.module.scss @@ -11,6 +11,39 @@ font-size: 1.5rem; font-weight: bold; } + .h3Section { + width: 100%; + display: flex; + flex-direction: column; + align-items: start; + gap: 1rem; + + .h3 { + font-size: 1.25rem; + font-weight: bold; + } + + .requiredMessage { + color: red; + font-size: 0.875rem; + } + } + + .pickerContainer { + display: flex; + gap: 0.5rem; + align-items: center; + border: solid 1px #c7c7c7; + padding: 0.25rem; + border-radius: 0.25rem; + width: 100%; + + .picker { + width: 1.5rem; + height: 1.5rem; + cursor: pointer; + } + } .descriptions { display: flex; @@ -24,9 +57,47 @@ } .buttons { + display: flex; + flex-direction: column; width: 100%; justify-content: center; - display: flex; + align-items: center; gap: 1rem; + + .button { + position: relative; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 0.75rem 1rem 1rem 1rem; + border-radius: 0.5rem; + border: solid 2px #000; + font-weight: bold; + width: 100%; + background-color: #fff; + color: #000; + + &:hover { + background-color: $hover-color; + } + } + + .active { + border: solid 2px $primary-color; + color: $primary-color; + } + + .registerButton { + position: relative; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 0.75rem 1rem 1rem 1rem; + border-radius: 0.5rem; + font-weight: bold; + width: 100%; + } } } diff --git a/src/components/OrigamiPost/FoldMethodControlPanel/PreviewPanel/index.tsx b/src/components/OrigamiPost/FoldMethodControlPanel/PreviewPanel/index.tsx index 39fae83..0602f92 100644 --- a/src/components/OrigamiPost/FoldMethodControlPanel/PreviewPanel/index.tsx +++ b/src/components/OrigamiPost/FoldMethodControlPanel/PreviewPanel/index.tsx @@ -1,24 +1,55 @@ import styles from "./index.module.scss"; -import { NextStepButton } from "../ui/NextStepButton"; -import { PrevStepButton } from "../ui/PrevStepButton"; -import Image from "next/image"; -import { Button } from "@radix-ui/themes"; +import { Button, TextField } from "@radix-ui/themes"; type Props = { handlePrevStep: () => void; handleNextStep: () => void; handleRegisterOrigami: () => void; + name: string; + handleNameChange: (e: React.ChangeEvent) => void; + color: string; + handleColorChange: (e: React.ChangeEvent) => void; }; export const PreviewPanel: React.FC = ({ - handlePrevStep, - handleNextStep, - handleRegisterOrigami, + name, + color, + handleColorChange, + handleNameChange, + //handleRegisterOrigami, }) => { return (

折り紙を公開する

-
+
+

+ 折り紙の名前をつけましょう + ※必須 +

+
+ +
+
+
+

折り紙の色を変更できます

+
+ +
{color}
+
+
+
+

折り方に間違いがないか確認してください

+
+ {/*

= ({ height={255} className={styles.gif} /> -
+
*/}
- - +
diff --git a/src/components/OrigamiPost/FoldMethodControlPanel/index.tsx b/src/components/OrigamiPost/FoldMethodControlPanel/index.tsx index 10e290d..096843f 100644 --- a/src/components/OrigamiPost/FoldMethodControlPanel/index.tsx +++ b/src/components/OrigamiPost/FoldMethodControlPanel/index.tsx @@ -32,6 +32,10 @@ type Props = { handleChangeStep: (step: number) => void; handleFinishFolding: () => void; isFinishFolding: boolean; + name: string; + handleNameChange: (e: React.ChangeEvent) => void; + color: string; + handleColorChange: (e: React.ChangeEvent) => void; }; export const FoldMethodControlPanel: React.FC = ({ @@ -56,6 +60,10 @@ export const FoldMethodControlPanel: React.FC = ({ handleChangeStep, handleFinishFolding, isFinishFolding, + name, + handleNameChange, + color, + handleColorChange, }) => { return (
@@ -96,13 +104,13 @@ export const FoldMethodControlPanel: React.FC = ({ ) : ( console.log("未実装")} + handleNextStep={() => console.log("未実装")} handleRegisterOrigami={handleRegisterOrigami} + name={name} + handleNameChange={handleNameChange} + color={color} + handleColorChange={handleColorChange} /> )}
diff --git a/src/components/OrigamiPost/index.tsx b/src/components/OrigamiPost/index.tsx index 62c64bc..03867d8 100644 --- a/src/components/OrigamiPost/index.tsx +++ b/src/components/OrigamiPost/index.tsx @@ -190,6 +190,10 @@ export const OrigamiPost = () => { handleChangeStep={handleChangeStep} handleFinishFolding={handleFinishFolding} isFinishFolding={isFinishFolding} + name={origamiName} + handleNameChange={handleOrigamiNameChange} + color={origamiColor} + handleColorChange={handleOrigamiColorChange} /> {popup?.message.length && (