Skip to content

Commit

Permalink
Merge pull request #10 from boostcampwm-2024/feature/#8
Browse files Browse the repository at this point in the history
[Feat] RSS 등록 폼에 상태 저장 기능 추가
  • Loading branch information
kimhji authored Jan 17, 2025
2 parents a115b10 + f94e8f3 commit d27f8e2
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 53 deletions.
36 changes: 29 additions & 7 deletions client/src/components/RssRegistration/RssRegistrationModal.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useState } from "react";
import { useEffect, useState } from "react";

import FormInput from "@/components/RssRegistration/FormInput";
import { PlatformSelector } from "@/components/RssRegistration/PlatformSelector.tsx";
import { PlatformSelector } from "@/components/RssRegistration/PlatformSelector";
import { RssUrlInput } from "@/components/RssRegistration/RssUrlInput";
import Alert from "@/components/common/Alert";
import { Button } from "@/components/ui/button";
Expand All @@ -14,21 +14,24 @@ import {
DialogTitle,
} from "@/components/ui/dialog";

import { useRssRegistrationForm } from "@/hooks/common/useRssRegistrationForm.ts";
import { useRegisterRss } from "@/hooks/queries/useRegisterRss.ts";
import { useRssRegistrationForm } from "@/hooks/common/useRssRegistrationForm";
import { useRegisterRss } from "@/hooks/queries/useRegisterRss";

import { AlertType } from "@/types/alert.ts";
import { RegisterRss } from "@/types/rss.ts";
import { useRegisterModalStore } from "@/store/useRegisterModalStore";
import { AlertType } from "@/types/alert";
import { RegisterRss } from "@/types/rss";

export default function RssRegistrationModal({ onClose, rssOpen }: { onClose: () => void; rssOpen: boolean }) {
const [alertOpen, setAlertOpen] = useState<AlertType>({ title: "", content: "", isOpen: false });
const [showMessage, setShowMessage] = useState(false);
const [messageText, setMessageText] = useState("");

const { platform, values, handlers, formState } = useRssRegistrationForm();
const { mutate } = useRegisterRss(
() => {
setAlertOpen({
title: "RSS 요청 성공!",
content: "관리자가 검토후 처리 결과를 입력해주신 메일을 통해 전달드릴 예정이에요!",
content: "관리자가 검토 후 처리 결과를 입력해주신 메일을 통해 전달드릴 예정이에요!",
isOpen: true,
});
},
Expand All @@ -41,6 +44,24 @@ export default function RssRegistrationModal({ onClose, rssOpen }: { onClose: ()
}
);

useEffect(() => {
if (rssOpen) {
const store = useRegisterModalStore.getState();
const hasPreviousData =
store.bloggerName.trim() !== "" || store.userName.trim() !== "" || store.email.trim() !== "";
if (hasPreviousData) {
setMessageText("등록 중이던 데이터를 불러왔습니다.");
setShowMessage(true);
setTimeout(() => setShowMessage(false), 3000);
}

store.setRssUrlValid(/^(https?:\/\/[^\s]+)$/i.test(store.rssUrl));
store.setBloggerNameValid(store.bloggerName.trim().length > 0);
store.setUserNameValid(store.userName.trim().length > 0);
store.setEmailValid(/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(store.email));
}
}, [rssOpen]);

const handleAlertClose = () => {
setAlertOpen({ title: "", content: "", isOpen: false });
formState.reset();
Expand Down Expand Up @@ -71,6 +92,7 @@ export default function RssRegistrationModal({ onClose, rssOpen }: { onClose: ()
<div className="space-y-6">
<PlatformSelector platform={platform} onPlatformChange={handlers.handlePlatformChange} />
<RssUrlInput platform={platform} value={values.urlUsername} onChange={handlers.handleUsernameChange} />
{showMessage && <div className="mb-4 text-sm text-primary font-medium">{messageText}</div>}

<div className="space-y-4">
<FormInput
Expand Down
93 changes: 47 additions & 46 deletions client/src/store/useRegisterModalStore.ts
Original file line number Diff line number Diff line change
@@ -1,90 +1,91 @@
import { create } from "zustand";

import { persist } from "zustand/middleware";

interface RegisterModalState {
//Form Value
rssUrl: string;
bloggerName: string;
userName: string;
email: string;

//Vaildation state
rssUrlValid: boolean;
bloggerNameValid: boolean;
userNameValid: boolean;
emailValid: boolean;

//Setting Form Value
setRssUrl: (url: string) => void;
setBloggerName: (name: string) => void;
setUserName: (name: string) => void;
setEmail: (email: string) => void;

//Setting Vaildation State
setRssUrlValid: (valid: boolean) => void;
setBloggerNameValid: (valid: boolean) => void;
setUserNameValid: (valid: boolean) => void;
setEmailValid: (valid: boolean) => void;

//Vaildation Handler
handleInputChange: (
value: string,
setValue: (value: string) => void,
setValid: (valid: boolean) => void,
validate: (value: string) => boolean
) => void;

//Other
resetInputs: () => void;
isFormValid: () => boolean;
}

export const useRegisterModalStore = create<RegisterModalState>((set, get) => ({
// Initial Form Values
rssUrl: "",
bloggerName: "",
userName: "",
email: "",

// Initial Validation States
rssUrlValid: false,
bloggerNameValid: false,
userNameValid: false,
emailValid: false,

// Setters Form Values
setRssUrl: (url) => set({ rssUrl: url }),
setBloggerName: (name) => set({ bloggerName: name }),
setUserName: (name) => set({ userName: name }),
setEmail: (email) => set({ email }),

// Setters Validation States
setRssUrlValid: (valid) => set({ rssUrlValid: valid }),
setBloggerNameValid: (valid) => set({ bloggerNameValid: valid }),
setUserNameValid: (valid) => set({ userNameValid: valid }),
setEmailValid: (valid) => set({ emailValid: valid }),

// Reset
resetInputs: () =>
set({
export const useRegisterModalStore = create(
persist<RegisterModalState>(
(set, get) => ({
rssUrl: "",
bloggerName: "",
userName: "",
email: "",

rssUrlValid: false,
bloggerNameValid: false,
userNameValid: false,
emailValid: false,
}),

// Check Form Vaildation
isFormValid: () => {
const state = get();
return state.rssUrlValid && state.bloggerNameValid && state.userNameValid && state.emailValid;
},
setRssUrl: (url) => set({ rssUrl: url }),
setBloggerName: (name) => set({ bloggerName: name }),
setUserName: (name) => set({ userName: name }),
setEmail: (email) => set({ email }),

setRssUrlValid: (valid) => set({ rssUrlValid: valid }),
setBloggerNameValid: (valid) => set({ bloggerNameValid: valid }),
setUserNameValid: (valid) => set({ userNameValid: valid }),
setEmailValid: (valid) => set({ emailValid: valid }),

resetInputs: () =>
set({
rssUrl: "",
bloggerName: "",
userName: "",
email: "",
rssUrlValid: false,
bloggerNameValid: false,
userNameValid: false,
emailValid: false,
}),

// Handle input change with validation
handleInputChange: (value, setValue, setValid, validate) => {
setValue(value);
setValid(validate(value));
},
}));
isFormValid: () => {
const state = get();
return state.rssUrlValid && state.bloggerNameValid && state.userNameValid && state.emailValid;
},

handleInputChange: (value, setValue, setValid, validate) => {
setValue(value);
setValid(validate(value));
},
}),
{
name: "register-modal-storage",
partialize: (state) => ({
bloggerName: state.bloggerName,
userName: state.userName,
email: state.email,
}),
}
)
);

0 comments on commit d27f8e2

Please sign in to comment.