Refactor Chat page to use separate components

Modularize the Chat page by extracting contact input, user profile, and message form into distinct components. This change simplifies the code, enhances readability, and improves maintainability by isolating individual functionality.
This commit is contained in:
slawk0
2024-10-14 11:15:40 +02:00
parent f7aa6ba713
commit c77c1cfd7e
4 changed files with 101 additions and 100 deletions

View File

@@ -0,0 +1,55 @@
import { useForm, SubmitHandler } from "react-hook-form";
import { sendContact, sendRequestHistorical } from "../socket/socket.tsx";
import { Dispatch, SetStateAction, useEffect } from "react";
type Input = {
contact: string;
};
interface ContactInputProps {
contact: string;
setContact: Dispatch<SetStateAction<string>>;
}
function ContactInput({ contact, setContact }: ContactInputProps) {
const { register, handleSubmit, reset } = useForm<Input>();
let storedContact: string | null = "";
useEffect(() => {
storedContact = storedContact = localStorage.getItem("contact");
if (storedContact) {
setContact(storedContact);
sendRequestHistorical(storedContact);
}
}, [setContact]);
const submitContact: SubmitHandler<Input> = (data) => {
localStorage.setItem("contact", data.contact);
setContact(data.contact);
sendContact(data.contact); //TODO zapisz w bazie danych te kontakty
console.log("Contact submitted:", data.contact);
reset({ contact: "" });
};
return (
<>
<div className="text-center">
<form onSubmit={handleSubmit(submitContact)}>
<input
className="text-black bg-green-100 pl-2 shadow-lg rounded-md h-8 mb-2 mt-2"
type="text"
autoFocus={!!contact}
placeholder="Enter contact"
{...register("contact", {
// valid username length (validated on signup)
minLength: 4,
maxLength: 20,
})}
/>
</form>
</div>
</>
);
}
export default ContactInput;

View File

@@ -3,20 +3,21 @@ import zdjecie from "../../assets/walter.png";
function ContactProfile() {
return (
<>
<div className="m-3 rounded-full w-10 h-10 overflow-hidden ">
<img
className="w-full h-full object-cover"
src={zdjecie}
alt="walter"
draggable={false}
/>
<div className="flex items-center">
<div className="m-3 rounded-full w-10 h-10 overflow-hidden ">
<img
className="w-full h-full object-cover"
src={zdjecie}
alt="walter"
draggable={false}
/>
</div>
<div className="text-center text-gray-200">
<p>Walter White</p>
</div>
</div>
<div className="text-center text-gray-200">
<p>Walter White</p>
</div>
<hr />
</>
);
}
export default ContactProfile;

View File

@@ -0,0 +1,23 @@
import zdjecie from "../../assets/walter.png";
function UserProfile() {
return (
<>
<div className="flex items-center">
<div className="m-3 rounded-full w-12 h-12 overflow-hidden ">
<img
className="w-full h-full object-cover"
src={zdjecie}
alt="walter"
draggable={false}
/>
</div>
<div className="text-center text-gray-200">
<p>Walter White</p>
</div>
</div>
</>
);
}
export default UserProfile;

View File

@@ -1,78 +1,18 @@
import { useForm, SubmitHandler } from "react-hook-form";
import zdjecie from "../../assets/walter.png";
import MessageForm from "../components/MessageForm.tsx";
import {
sendMessage,
sendContact,
sendRequestHistorical,
} from "../socket/socket.tsx";
import { useEffect, useState } from "react";
import messageForm from "../components/MessageForm.tsx";
type Input = {
message: string;
contact: string;
};
import ContactProfile from "../components/ContactProfile.tsx";
import UserProfile from "../components/UserProfile.tsx";
import ContactInput from "../components/ContactInput.tsx";
import { useState } from "react";
function Chat() {
const {
register,
handleSubmit,
reset,
formState: { errors },
} = useForm<Input>();
const [contact, setContact] = useState<string>("");
const [messages, setMessages] = useState<string>("");
const [contactFocus, setContactFocus] = useState<boolean>(false);
const [messageFocus, setMessageFocus] = useState<boolean>(true);
useEffect(() => {
const storedContact = localStorage.getItem("contact");
if (storedContact) {
setContact(storedContact);
sendRequestHistorical(storedContact);
// setMessageFocus(true);
// setContactFocus(false);
}
console.log(
"message focus: ",
messageFocus,
"contact focus: ",
contactFocus,
);
}, [messageFocus, contactFocus]);
// Sending contact
const submitContact: SubmitHandler<Input> = (data) => {
setContactFocus(false);
setMessageFocus(true);
localStorage.setItem("contact", data.contact);
setContact(data.contact);
sendContact(data.contact); //TODO zapisz w bazie danych te kontakty
console.log("Contact submitted:", data.contact);
reset({ contact: "" });
};
return (
<>
<div className="text-white flex h-screen">
{/*Sidebar*/}
<div className="h-screen bg-[#1E1E1E] flex flex-col">
{/*Contact input*/}
<div className="text-center">
<form onSubmit={handleSubmit(submitContact)}>
<input
className="text-black bg-green-100 pl-2 shadow-lg rounded-md h-8 mb-2 mt-2"
type="text"
autoFocus={contactFocus}
placeholder="Enter contact"
{...register("contact", {
// valid username length (validated on signup)
minLength: 4,
maxLength: 20,
})}
/>
</form>
</div>
<ContactInput contact={contact} setContact={setContact} />
{/*Contact list*/}
<div className="flex-grow overflow-y-auto w-64">
<ul className="ml-2">
@@ -88,36 +28,18 @@ function Chat() {
</div>
{/*Profile element*/}
<hr />
<div className="flex items-center">
<div className="m-3 rounded-full w-12 h-12 overflow-hidden ">
<img
className="w-full h-full object-cover"
src={zdjecie}
alt="walter"
draggable={false}
/>
</div>
<div className="text-center text-gray-200">
<p>Walter White</p>
</div>
</div>
<UserProfile />
</div>
{/*Chat area */}
<div className="text-white bg-[#121212] flex flex-col h-screen w-full">
{/*Messages*/}
<div>
<p>{contact}</p>
<ul className="ml-5">
{/*{messagesArray.map((message, index) => (*/}
{/* <li key={index}>*/}
{/* {message.username}: {message.content}*/}
{/* </li>*/}
{/*))}*/}
</ul>
<div className="flex">
<ContactProfile />
</div>
<hr />
{/*Messages input*/}
<div className="mt-auto mb-2">
<MessageForm contact={contact} messageFocus={messageFocus} />
<MessageForm />
</div>
</div>
</div>