Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/develop-CD.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ jobs:
- name: Build Docker image
run: |
docker build \
--build-arg NEXT_PUBLIC_API_URL=${{ secrets.API_URL_DEV }} \
--build-arg NEXT_PUBLIC_FIREBASE_API_KEY=${{ secrets.FIREBASE_API_KEY }} \
--build-arg NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=${{ secrets.FIREBASE_AUTH_DOMAIN }} \
--build-arg NEXT_PUBLIC_FIREBASE_PROJECT_ID=${{ secrets.FIREBASE_PROJECT_ID }} \
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/master-CD.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
- name: Build Docker image
run: |
docker build \
--build-arg NEXT_PUBLIC_API_URL=${{ secrets.API_URL_PROD }} \
--build-arg NEXT_PUBLIC_FIREBASE_API_KEY=${{ secrets.FIREBASE_API_KEY }} \
--build-arg NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=${{ secrets.FIREBASE_AUTH_DOMAIN }} \
--build-arg NEXT_PUBLIC_FIREBASE_PROJECT_ID=${{ secrets.FIREBASE_PROJECT_ID }} \
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.local
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:22-slim
FROM node:22-alpine

RUN mkdir -p /app

Expand Down
2 changes: 2 additions & 0 deletions Dockerfile.prod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ RUN npm install

COPY . .

ARG NEXT_PUBLIC_API_URL
ARG NEXT_PUBLIC_FIREBASE_API_KEY
ARG NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN
ARG NEXT_PUBLIC_FIREBASE_PROJECT_ID
Expand All @@ -17,6 +18,7 @@ ARG NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID
ARG NEXT_PUBLIC_FIREBASE_APP_ID
ARG NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID

ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
ENV NEXT_PUBLIC_FIREBASE_API_KEY=$NEXT_PUBLIC_FIREBASE_API_KEY
ENV NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=$NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN
ENV NEXT_PUBLIC_FIREBASE_PROJECT_ID=$NEXT_PUBLIC_FIREBASE_PROJECT_ID
Expand Down
12 changes: 12 additions & 0 deletions app/(protected)/dashboard/_apis/messages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import myAxios from '@/app/_apis/myAxios.config';
import { IMessage } from '@/app/_lib/_interfaces/IMessage';

export const getRoomMessages = async (roomId: string) => {
try {
const res = await myAxios.get<IMessage[]>(`/api/v1/chat/rooms/${roomId}/messages`);
return res.data;
} catch (error) {
console.error('Error fetching room messages:', error);
return [];
}
};
65 changes: 65 additions & 0 deletions app/(protected)/dashboard/_apis/rooms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
'use client';

import myAxios from '@/app/_apis/myAxios.config';
import { ICreateRoom, IRoom } from '@/app/_lib/_interfaces/IRoom';
import { toast } from 'react-toastify';

export const createRoom = async (data: ICreateRoom) => {
const { name, description, userIds } = data;
console.log('data', data);
if (!name || !description || !userIds) {
toast.error('Por favor completa todos los campos');
return null;
}

try {
const res = await myAxios.post<ICreateRoom>('/api/v1/chat/rooms', data);
toast.success('Sala creada con éxito');
return res.data;
} catch (error: any) {
toast.error(error.response?.data || 'Error al crear la sala');
return null;
}
};

export const getRoomsImIn = async () => {
try {
const res = await myAxios.get<IRoom[]>('/api/v1/chat/rooms/me');
return res.data;
} catch (error) {
console.error('Error fetching rooms:', error);
return [];
}
};

export const getAllRooms = async () => {
try {
const res = await myAxios.get<IRoom[]>('/api/v1/chat/rooms');
return res.data.filter(room => !room.isPrivate);
} catch (error) {
console.error('Error fetching all rooms:', error);
return [];
}
};

export const getRoomById = async (roomId: string) => {
try {
const res = await myAxios.get<IRoom>(`/api/v1/chat/rooms/${roomId}`);
return res.data;
} catch (error) {
console.error('Error fetching room by ID:', error);
return null;
}
};

export const joinRoom = async (roomId: string) => {
try {
const res = await myAxios.post(`/api/v1/chat/rooms/${roomId}/join`);
toast.success('Te has unido al chat');
return res.data;
} catch (error: any) {
toast.error(error.response?.data || 'Error al unirte al chat');
return null;
}
};
140 changes: 30 additions & 110 deletions app/(protected)/dashboard/_components/RoomList.tsx
Original file line number Diff line number Diff line change
@@ -1,125 +1,45 @@
import { auth } from '@/app/_lib/_firebase/firebase.config';
import { IRoom } from '@/app/_lib/_interfaces/IRoom';
import { CancelIcon, DoorBellIcon } from '@/app/_ui/icons';
import { Tooltip } from '@mui/material';
import Link from 'next/link';

const salas = [
{
id: 1,
name: 'Sala 1',
created_by: 'Usuario 1',
created_at: '2023-10-01',
},
{
id: 2,
name: 'Sala 2',
created_by: 'Usuario 2',
created_at: '2023-10-02',
},
{
id: 3,
name: 'Sala 3',
created_by: 'Usuario 3',
created_at: '2023-10-03',
},
{
id: 4,
name: 'Sala 4',
created_by: 'Usuario 4',
created_at: '2023-10-04',
},
{
id: 5,
name: 'Sala 5',
created_by: 'Usuario 5',
created_at: '2023-10-05',
},
{
id: 6,
name: 'Sala 6',
created_by: 'Usuario 6',
created_at: '2023-10-06',
},
{
id: 7,
name: 'Sala 7',
created_by: 'Usuario 7',
created_at: '2023-10-07',
},
{
id: 8,
name: 'Sala 8',
created_by: 'Usuario 8',
created_at: '2023-10-08',
},
{
id: 9,
name: 'Sala 9',
created_by: 'Usuario 9',
created_at: '2023-10-09',
},
{
id: 10,
name: 'Sala 10',
created_by: 'Usuario 10',
created_at: '2023-10-10',
},
{
id: 11,
name: 'Sala 11',
created_by: 'Usuario 11',
created_at: '2023-10-11',
},
{
id: 12,
name: 'Sala 12',
created_by: 'Usuario 12',
created_at: '2023-10-12',
},
{
id: 13,
name: 'Sala 13',
created_by: 'Usuario 13',
created_at: '2023-10-13',
},
{
id: 14,
name: 'Sala 14',
created_by: 'Usuario 14',
created_at: '2023-10-14',
},
{
id: 15,
name: 'Sala 15',
created_by: 'Usuario 15',
created_at: '2023-10-14',
},
];
interface Props {
rooms: IRoom[];
}

export default function RoomList({ rooms }: Props) {
const userId = auth.currentUser?.uid;

const CanExitRoom = (room: IRoom) => {
return room.members.some(member => member === userId);
};

export default function RoomList() {
return (
<section className="w-full h-full flex flex-col gap-5 overflow-auto px-[5vw] py-5">
{salas.map(sala => (
<>
{rooms.map(sala => (
<article key={sala.id} className="w-full flex gap-5 items-center justify-between">
<Link
href={`dashboard/room/${sala.id}`}
className="flex gap-5 items-center justify-between bg-purple w-full p-3 rounded-2xl"
href={`/dashboard/room/${sala.id}`}
className="flex gap-5 items-center justify-between bg-purple w-full p-3 rounded-2xl min-w-0 flex-11/12"
>
<p className="font-bold text-2xl lg:text-4xl">{sala.name}</p>
<div className="hidden sm:flex flex-col items-center">
<p className="font-semibold text-sm">
Creado por: <span className="font-medium text-purple">{sala.created_by}</span>
</p>
<p className="font-bold text-2xl lg:text-4xl truncate min-w-0 flex-1">{sala.name}</p>
<div className="hidden sm:flex flex-col items-center flex-shrink-0">
<p className="font-semibold text-sm">
Fecha: <span className="font-medium text-sm text-purple">{sala.created_at}</span>
<span className="font-medium text-sm text-purple">
{new Date(sala.createdAt).toLocaleDateString('es-ES')}
</span>
</p>
</div>
</Link>
<div className="flex gap-5">
<Tooltip title="Salir de la sala" placement="top">
<button className="bg-purple rounded-full">
<CancelIcon className="w-10 h-10 cursor-pointer" />{' '}
</button>
</Tooltip>
<div className="flex gap-5 justify-end flex-2/12">
{CanExitRoom(sala) && (
<Tooltip title="Salir de la sala" placement="top">
<button className="bg-purple rounded-full">
<CancelIcon className="w-10 h-10 cursor-pointer" />{' '}
</button>
</Tooltip>
)}
<Tooltip title="Notificaciones" placement="top">
<button className="bg-purple rounded-full">
<DoorBellIcon className="w-10 h-10 cursor-pointer" />{' '}
Expand All @@ -128,6 +48,6 @@ export default function RoomList() {
</div>
</article>
))}
</section>
</>
);
}
48 changes: 48 additions & 0 deletions app/(protected)/dashboard/_components/RoomSearch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'use client';

import LoadingEmoji from '@/app/_components/LoadingEmoji';
import { RoomIcon } from '@/app/_ui/icons';
import { useQuery } from '@tanstack/react-query';
import { getAllRooms } from '../_apis/rooms';
import RoomList from './RoomList';

export default function RoomSearch() {
const { data: rooms, isLoading } = useQuery({
queryKey: ['all-rooms-dashboard'],
queryFn: getAllRooms,
});

if (isLoading) return <LoadingEmoji />;

const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const form = e.currentTarget;
const searchValue = form.search.value;

// Aquí puedes manejar la búsqueda con el valor de searchValue
console.log('Buscando sala:', searchValue);
};

return (
<>
<form className="w-full flex justify-center items-center" onSubmit={handleSubmit}>
<input
type="text"
placeholder="Buscar sala"
className="w-full border border-violet-400 px-4 py-2 flex-11/12 outline-none rounded-l-md"
name="search"
/>
<button className="flex justify-center items-center w-full bg-purple text-white cursor-pointer flex-1/12 h-full rounded-r-md">
<RoomIcon width={30} height={30} />
</button>
</form>
{rooms ? (
<RoomList rooms={rooms} />
) : (
<div className="w-full h-full flex justify-center items-center">
<h2 className="text-lg text-gray-500">No encontramos salas</h2>
</div>
)}
</>
);
}
Loading