code refactor, created separate file for types

This commit is contained in:
slawk0
2025-01-02 00:33:29 +01:00
parent 81aeb5a926
commit 6db8d2d574
17 changed files with 81 additions and 74 deletions

View File

@@ -1,6 +1,6 @@
import { axiosClient } from '../App.tsx'; import { axiosClient } from '../App.tsx';
import { ChatMessagesProps } from '../pages/Chat.tsx';
import { ContactsProps } from '../pages/Chat.tsx'; import { ChatMessagesProps, ContactsProps } from '@/types/types.ts';
export async function getContactsList(): Promise<ContactsProps[]> { export async function getContactsList(): Promise<ContactsProps[]> {
try { try {

View File

@@ -1,7 +1,8 @@
import { useState } from 'react'; import { useState } from 'react';
import { Trash2 } from 'lucide-react'; import { Trash2 } from 'lucide-react';
import AttachmentPreview from './AttachmentPreview.tsx'; import AttachmentPreview from './AttachmentPreview.tsx';
import { ChatMessagesProps } from '@/pages/Chat.tsx';
import { ChatMessagesProps } from '@/types/types.ts';
type AnimatedMessageProps = { type AnimatedMessageProps = {
message: ChatMessagesProps; message: ChatMessagesProps;

View File

@@ -1,37 +1,28 @@
import { useRef, useCallback, useEffect, useState } from 'react';
import { useForm, SubmitHandler } from 'react-hook-form';
import type { KeyboardEventHandler } from 'react'; import type { KeyboardEventHandler } from 'react';
import { useCallback, useEffect, useRef, useState } from 'react';
import { SubmitHandler, useForm } from 'react-hook-form';
import { socket } from '../../../socket/socket.tsx'; import { socket } from '../../../socket/socket.tsx';
import { ChatMessagesProps, ContactsProps } from '../../../pages/Chat.tsx';
import { axiosClient } from '../../../App.tsx'; import { axiosClient } from '../../../App.tsx';
import { File, Paperclip, Send, X } from 'lucide-react'; import { File, Paperclip, Send, X } from 'lucide-react';
import LoadingWheel from '@/components/chat/LoadingWheel.tsx'; import LoadingWheel from '@/components/chat/LoadingWheel.tsx';
type Input = { import {
message: string; FileWithPreviewProps,
attachments: FileList | null; InputProps,
}; MessageFormProps,
} from '@/types/types.ts';
type MessageFormProps = {
contact: ContactsProps;
messages: ChatMessagesProps[];
};
type FileWithPreview = {
file: File;
preview: string | null;
};
const MessageForm = ({ contact }: MessageFormProps) => { const MessageForm = ({ contact }: MessageFormProps) => {
const [files, setFiles] = useState<FileWithPreview[]>([]); const [files, setFiles] = useState<FileWithPreviewProps[]>([]);
const [isUploading, setIsUploading] = useState(false); const [isUploading, setIsUploading] = useState(false);
const [isSending, setIsSending] = useState<boolean>(false); const [isSending, setIsSending] = useState<boolean>(false);
const [errorMessage, setErrorMessage] = useState<string | null>(null); const [errorMessage, setErrorMessage] = useState<string | null>(null);
const fileInputRef = useRef<HTMLInputElement | null>(null); const fileInputRef = useRef<HTMLInputElement | null>(null);
const { register, handleSubmit, reset, watch, setValue } = useForm<Input>({ const { register, handleSubmit, reset, watch, setValue } =
mode: 'onChange', useForm<InputProps>({
}); mode: 'onChange',
});
const message = watch('message', ''); const message = watch('message', '');
const textareaRef = useRef<HTMLTextAreaElement | null>(null); const textareaRef = useRef<HTMLTextAreaElement | null>(null);
@@ -114,7 +105,7 @@ const MessageForm = ({ contact }: MessageFormProps) => {
} }
}; };
const submitMessage: SubmitHandler<Input> = async (data) => { const submitMessage: SubmitHandler<InputProps> = async (data) => {
if ((!data.message && files.length === 0) || isSending) return; if ((!data.message && files.length === 0) || isSending) return;
setErrorMessage(null); setErrorMessage(null);
setIsSending(true); setIsSending(true);
@@ -172,7 +163,7 @@ const MessageForm = ({ contact }: MessageFormProps) => {
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => { const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files && e.target.files.length > 0) { if (e.target.files && e.target.files.length > 0) {
const newFiles: FileWithPreview[] = Array.from(e.target.files).map( const newFiles: FileWithPreviewProps[] = Array.from(e.target.files).map(
(file) => ({ (file) => ({
file, file,
preview: file.type.startsWith('image/') preview: file.type.startsWith('image/')

View File

@@ -3,10 +3,13 @@ import { socket } from '@/socket/socket.tsx';
import { useOutletContext } from 'react-router-dom'; import { useOutletContext } from 'react-router-dom';
import { sendContact } from '@/api/contactsApi.tsx'; import { sendContact } from '@/api/contactsApi.tsx';
import LoadingWheel from '../LoadingWheel.tsx'; import LoadingWheel from '../LoadingWheel.tsx';
import { ChatMessagesProps, MeProps } from '@/pages/Chat.tsx';
import { ContactsProps } from '@/pages/Chat.tsx';
import { UsernameType } from '@/utils/ProtectedRoutes.tsx';
import AnimatedMessage from '@/components/chat/chatArea/AnimatedMessage.tsx'; import AnimatedMessage from '@/components/chat/chatArea/AnimatedMessage.tsx';
import {
ChatMessagesProps,
ContactsProps,
MeProps,
UsernameType,
} from '@/types/types.ts';
type MessagesAreaProps = { type MessagesAreaProps = {
messages: ChatMessagesProps[]; messages: ChatMessagesProps[];

View File

@@ -2,10 +2,10 @@ import LoadingWheel from '../LoadingWheel.tsx';
import { useEffect, useRef, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
import { SubmitHandler, useForm } from 'react-hook-form'; import { SubmitHandler, useForm } from 'react-hook-form';
import { axiosClient } from '../../../App.tsx'; import { axiosClient } from '../../../App.tsx';
import { ContactsProps } from '../../../pages/Chat.tsx';
import { socket } from '../../../socket/socket.tsx'; import { socket } from '../../../socket/socket.tsx';
import { UserRoundPlus } from 'lucide-react'; import { UserRoundPlus } from 'lucide-react';
import { Button } from '@/components/ui/button.tsx'; import { Button } from '@/components/ui/button.tsx';
import { ContactsProps } from '@/types/types.ts';
type Inputs = { type Inputs = {
username: string; username: string;

View File

@@ -1,8 +1,8 @@
import profile from '../../../../assets/profile.svg'; import profile from '../../../../assets/profile.svg';
import CreateGroupButton from './CreateGroupButton.tsx'; import CreateGroupButton from './CreateGroupButton.tsx';
import AddGroupMember from './AddGroupMember.tsx'; import AddGroupMember from './AddGroupMember.tsx';
import { ContactsProps } from '@/pages/Chat.tsx';
import { UsersRound } from 'lucide-react'; import { UsersRound } from 'lucide-react';
import { ContactsProps } from '@/types/types.ts';
type ContactProfileProps = { type ContactProfileProps = {
contact: ContactsProps | null; contact: ContactsProps | null;

View File

@@ -1,10 +1,10 @@
import { useForm, SubmitHandler } from 'react-hook-form'; import { useForm, SubmitHandler } from 'react-hook-form';
import { ContactsProps } from '../../../pages/Chat.tsx';
import { axiosClient } from '../../../App.tsx'; import { axiosClient } from '../../../App.tsx';
import { AxiosResponse } from 'axios'; import { AxiosResponse } from 'axios';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import LoadingWheel from '../LoadingWheel.tsx'; import LoadingWheel from '../LoadingWheel.tsx';
import { Search } from 'lucide-react'; import { Search } from 'lucide-react';
import { ContactsProps } from '@/types/types.ts';
type Input = { type Input = {
contact: string; contact: string;

View File

@@ -1,5 +1,4 @@
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import { ChatMessagesProps, ContactsProps } from '@/pages/Chat.tsx';
import { socket } from '@/socket/socket.tsx'; import { socket } from '@/socket/socket.tsx';
import GroupIcon from '../../../../assets/group.svg'; import GroupIcon from '../../../../assets/group.svg';
import { import {
@@ -16,6 +15,7 @@ import {
import { axiosClient } from '@/App.tsx'; import { axiosClient } from '@/App.tsx';
import { Dot } from 'lucide-react'; import { Dot } from 'lucide-react';
import LastActiveTime from '@/components/chat/leftSidebar/LastActiveTime.tsx'; import LastActiveTime from '@/components/chat/leftSidebar/LastActiveTime.tsx';
import { ChatMessagesProps, ContactsProps } from '@/types/types.ts';
type ContactsListProps = { type ContactsListProps = {
initializeContact: (contact: ContactsProps) => void; initializeContact: (contact: ContactsProps) => void;

View File

@@ -1,6 +1,7 @@
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { formatDistanceToNow, differenceInSeconds } from 'date-fns'; import { formatDistanceToNow, differenceInSeconds } from 'date-fns';
import { ContactsProps } from '@/pages/Chat.tsx';
import { ContactsProps } from '@/types/types.ts';
type LastActiveTimeProps = { type LastActiveTimeProps = {
contact: ContactsProps; contact: ContactsProps;

View File

@@ -2,7 +2,8 @@ import zdjecie from '../../../../assets/turtleProfileImg3.webp';
import logoutIcon from '../../../../assets/logout.svg'; import logoutIcon from '../../../../assets/logout.svg';
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
import { useOutletContext } from 'react-router-dom'; import { useOutletContext } from 'react-router-dom';
import { UsernameType } from '../../../utils/ProtectedRoutes.tsx';
import { UsernameType } from '@/types/types.ts';
function UserProfile() { function UserProfile() {
const user: UsernameType = useOutletContext(); const user: UsernameType = useOutletContext();

View File

@@ -1,6 +1,5 @@
import { useContext, useEffect, useMemo, useState } from 'react'; import { useContext, useEffect, useMemo, useState } from 'react';
import { axiosClient } from '@/App.tsx'; import { axiosClient } from '@/App.tsx';
import { ContactsProps, MeProps } from '@/pages/Chat.tsx';
import { socket } from '@/socket/socket.tsx'; import { socket } from '@/socket/socket.tsx';
import { Crown, Sword } from 'lucide-react'; import { Crown, Sword } from 'lucide-react';
import { import {
@@ -9,9 +8,9 @@ import {
ContextMenuItem, ContextMenuItem,
ContextMenuTrigger, ContextMenuTrigger,
} from '@/components/ui/context-menu.tsx'; } from '@/components/ui/context-menu.tsx';
import { UsernameType } from '@/utils/ProtectedRoutes.tsx';
import { useOutletContext } from 'react-router-dom'; import { useOutletContext } from 'react-router-dom';
import zdjecie from '../../../../assets/turtleProfileImg3.webp'; import zdjecie from '../../../../assets/turtleProfileImg3.webp';
import { ContactsProps, MeProps, UsernameType } from '@/types/types.ts';
type ParticipantsProps = { type ParticipantsProps = {
user_id: string; user_id: string;
username: string; username: string;

View File

View File

@@ -10,35 +10,7 @@ import Cookies from 'js-cookie';
import { getMessages, setContactStatus } from '../api/contactsApi.tsx'; import { getMessages, setContactStatus } from '../api/contactsApi.tsx';
import axios from 'axios'; import axios from 'axios';
import ParticipantsBar from '@/components/chat/rightSidebar/ParticipantsBar.tsx'; import ParticipantsBar from '@/components/chat/rightSidebar/ParticipantsBar.tsx';
import { ChatMessagesProps, ContactsProps, MeProps } from '@/types/types.ts';
export type MeProps = {
isGroupAdmin: boolean;
isGroupOwner: boolean;
};
export type ChatMessagesProps = {
sender: string;
message: string;
recipient: string; // conversation_id
message_id: number;
attachment_urls: string[] | null;
sender_id: string;
conversation_id: string;
sent_at: Date;
};
export type ContactsProps = {
read: boolean;
username: string;
user_id: string;
id: number;
type: 'direct' | 'group';
conversation_id: string;
last_active: string;
last_message: string;
last_message_time: string;
last_message_sender: string;
};
function Chat() { function Chat() {
const meDefaultValue = { const meDefaultValue = {

View File

@@ -6,7 +6,7 @@ import { AuthContext } from '../utils/AuthProvider.tsx';
import LoadingWheel from '../components/chat/LoadingWheel.tsx'; import LoadingWheel from '../components/chat/LoadingWheel.tsx';
import { axiosClient } from '../App.tsx'; import { axiosClient } from '../App.tsx';
type Inputs = { export type Inputs = {
username: string; username: string;
password: string; password: string;
}; };

44
client/src/types/types.ts Normal file
View File

@@ -0,0 +1,44 @@
import { File } from 'lucide-react';
export type MeProps = {
isGroupAdmin: boolean;
isGroupOwner: boolean;
};
export type ChatMessagesProps = {
sender: string;
message: string;
recipient: string; // conversation_id
message_id: number;
attachment_urls: string[] | null;
sender_id: string;
conversation_id: string;
sent_at: Date;
};
export type ContactsProps = {
read: boolean;
username: string;
user_id: string;
id: number;
type: 'direct' | 'group';
conversation_id: string;
last_active: string;
last_message: string;
last_message_time: string;
last_message_sender: string;
};
export type InputProps = {
message: string;
attachments: FileList | null;
};
export type MessageFormProps = {
contact: ContactsProps;
messages: ChatMessagesProps[];
};
export type FileWithPreviewProps = {
file: File;
preview: string | null;
};
export type UsernameType = {
username: string | null;
user_id: string | null;
};

View File

@@ -1,13 +1,9 @@
import { Navigate, Outlet } from 'react-router-dom'; import { Navigate, Outlet } from 'react-router-dom';
import { useState, useEffect, useContext } from 'react'; import { useContext, useEffect, useState } from 'react';
import { AuthContext } from './AuthProvider.tsx'; import { AuthContext } from './AuthProvider.tsx';
import LoadingScreen from '../components/LoadingScreen.tsx'; import LoadingScreen from '../components/LoadingScreen.tsx';
import { axiosClient } from '../App.tsx'; import { axiosClient } from '../App.tsx';
import { UsernameType } from '@/types/types.ts';
export type UsernameType = {
username: string | null;
user_id: string | null;
};
function ProtectedRoutes() { function ProtectedRoutes() {
const { authorized, isLoading } = useContext(AuthContext); const { authorized, isLoading } = useContext(AuthContext);

View File

@@ -1,6 +1,5 @@
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
export default { export default {
important: true,
darkMode: ['class'], darkMode: ['class'],
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'], content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
theme: { theme: {