Skip to content

Commit

Permalink
[WIP] refactor/http-requests-and-add-context (#97)
Browse files Browse the repository at this point in the history
  • Loading branch information
ANGdesarrollo authored Oct 20, 2024
1 parent 1f20c0d commit 405baa0
Show file tree
Hide file tree
Showing 55 changed files with 471 additions and 454 deletions.
27 changes: 27 additions & 0 deletions src/app/[locale]/unauthorized/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use client';
import React from 'react';
import { useRouter } from 'next/navigation';

const UnauthorizedPage = () => {
const router = useRouter();
const handleGoBack = () => {
router.push('/dashboard');
};

return (
<div className='flex min-h-screen flex-col items-center justify-center'>
<div className='rounded-lg p-8 text-center shadow-lg'>
<h1 className='mb-4 text-4xl font-bold text-red-600'>Acceso No Autorizado</h1>
<p className='mb-6 text-xl text-gray-700'>Lo sentimos, no tienes permiso para acceder a esta página.</p>
<button
onClick={handleGoBack}
className='rounded bg-blue-500 px-6 py-2 text-white transition-colors hover:bg-blue-600'
>
Volver
</button>
</div>
</div>
);
};

export default UnauthorizedPage;
6 changes: 6 additions & 0 deletions src/app/[locale]/users/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { Suspense } from 'react';

import { unstable_setRequestLocale } from 'next-intl/server';

import { paginationInitialParams } from '@/features/items/constants/paginationInitialParams';
import { LoaderStarsWars } from '@/features/shared/atoms/loader/LoaderStarsWars';
import { UsersTemplate } from '@/features/users/template/UsersTemplate';
import { PrivateLayout } from '@/layout/private-layout/PrivateLayout';
Expand All @@ -16,8 +17,13 @@ export default async function Page({ searchParams, params: { locale } }: Props)
const params = new URLSearchParams(searchParams);

const queryParams: QueryParams = {
pagination: {
offset: params.get('pagination[offset]') ?? paginationInitialParams.offset,
limit: params.get('pagination[limit]') ?? paginationInitialParams.limit,
},
filter: params,
};

unstable_setRequestLocale(locale);

return (
Expand Down
1 change: 1 addition & 0 deletions src/app/[locale]/users/update/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type Props = {
readonly searchParams: { readonly [key: string]: string };
readonly params: { locale: string };
};

export default function Page({ searchParams, params: { locale } }: Props) {
const { id } = searchParams;
unstable_setRequestLocale(locale);
Expand Down
12 changes: 8 additions & 4 deletions src/app/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,20 @@ import React from 'react';
import { NextUIProvider } from '@nextui-org/react';
import { ThemeProvider as NextThemesProvider } from 'next-themes';
import { Bounce, ToastContainer } from 'react-toastify';

import '../features/shared/atoms/toast/toast.css';
import { UserProvider } from '@/contexts/UserContext';

export function Providers({ children }: { children: React.ReactNode }) {
return (
<NextUIProvider>
<NextThemesProvider attribute='class' defaultTheme='dark'>
<main>
<ToastContainer autoClose={3000} transition={Bounce} theme={'dark'} />
{children}
</main>
<UserProvider>
<main>
<ToastContainer autoClose={3000} transition={Bounce} theme={'dark'} />
{children}
</main>
</UserProvider>
</NextThemesProvider>
</NextUIProvider>
);
Expand Down
File renamed without changes.
32 changes: 32 additions & 0 deletions src/contexts/UserContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
'use client';

import React, { createContext, useState, useContext } from 'react';
import { StaticImageData } from 'next/image';

import { images } from '@/features/shared/hooks/images';

interface UserContextType {
avatar: StaticImageData | string;
handleSetAvatar: (avatar: string) => void;
}

const UserContext = createContext<UserContextType | undefined>(undefined);

export function UserProvider({ children }: { children: React.ReactNode }) {
const { Avatar } = images();
const [avatar, setUserAvatar] = useState<StaticImageData | string>(Avatar);

const handleSetAvatar = (avatar: string): void => {
setUserAvatar(avatar);
};

return <UserContext.Provider value={{ avatar, handleSetAvatar }}>{children}</UserContext.Provider>;
}

export function useContextUser() {
const context = useContext(UserContext);

if (!context) throw new Error('Context not defined');

return context;
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
'use server';

import { env } from '@/config/api';
import { supabaseClientManager } from '@/lib/SupabaseClientManager';
import { supabaseServerClientManager } from '@/lib/SupabaseServerClientManager';

export const handleRecoverPassword = async (username: string) => {
const supabase = supabaseClientManager.getPublicClient();
const supabase = supabaseServerClientManager.getServerPublicClient();

const { error } = await supabase.auth.resetPasswordForEmail(username, {
redirectTo: `${env.urlFront}/auth/update-password`,
Expand Down
4 changes: 2 additions & 2 deletions src/features/auth/login/actions/loginAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { redirect, RedirectType } from 'next/navigation';

import { getLang } from '@/features/shared/hooks/getLang';

import { supabaseClientManager } from '@/lib/SupabaseClientManager';
import { supabaseServerClientManager } from '@/lib/SupabaseServerClientManager';

import { ILoginForm } from '../interfaces/IloginForm';

export const handleSignIn = async (data: ILoginForm) => {
const supabase = supabaseClientManager.getPublicClient();
const supabase = supabaseServerClientManager.getServerPublicClient();
const { lang } = getLang();

const { error } = await supabase.auth.signInWithPassword({
Expand Down
4 changes: 2 additions & 2 deletions src/features/auth/recovery-code/actions/recoveryCodeAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { redirect, RedirectType } from 'next/navigation';

import { getLang } from '@/features/shared/hooks/getLang';

import { supabaseClientManager } from '@/lib/SupabaseClientManager';
import { supabaseServerClientManager } from '@/lib/SupabaseServerClientManager';

import { IrecoveryCode } from '../interfaces/IrecoveryCode';

export const handleRecoveryCode = async (email: string, data: IrecoveryCode) => {
const supabase = supabaseClientManager.getPublicClient();
const supabase = supabaseServerClientManager.getServerPublicClient();
const { lang } = getLang();

const { error } = await supabase.auth.verifyOtp({ email, token: data.code, type: 'recovery' });
Expand Down
4 changes: 2 additions & 2 deletions src/features/auth/register/actions/registerAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { redirect, RedirectType } from 'next/navigation';

import { env } from '@/config/api';
import { IRegisterForm } from '@/features/auth/register/interfaces/IRegisterForm';
import { supabaseClientManager } from '@/lib/SupabaseClientManager';
import { supabaseServerClientManager } from '@/lib/SupabaseServerClientManager';

export const handleSignUp = async (props: IRegisterForm) => {
const supabase = supabaseClientManager.getPublicClient();
const supabase = supabaseServerClientManager.getServerPublicClient();

const { error } = await supabase.auth.signUp({
email: props.email,
Expand Down
4 changes: 2 additions & 2 deletions src/features/auth/shared/actions/singOutAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

import { redirect, RedirectType } from 'next/navigation';

import { supabaseClientManager } from '@/lib/SupabaseClientManager';
import { supabaseServerClientManager } from '@/lib/SupabaseServerClientManager';

export const handleSignOut = async () => {
const supabase = supabaseClientManager.getPublicClient();
const supabase = supabaseServerClientManager.getServerPublicClient();

const { error } = await supabase.auth.signOut();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

import { redirect, RedirectType } from 'next/navigation';

import { supabaseClientManager } from '@/lib/SupabaseClientManager';
import { supabaseServerClientManager } from '@/lib/SupabaseServerClientManager';

export const handleUpdatePassword = async (password: string, code: string) => {
const supabase = supabaseClientManager.getPublicClient();
const supabase = supabaseServerClientManager.getServerPublicClient();

await supabase.auth.exchangeCodeForSession(code);

Expand Down
2 changes: 1 addition & 1 deletion src/features/items/actions/ItemAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
import { revalidatePath } from 'next/cache';
import { redirect } from 'next/navigation';

import { config } from '@/config/config';
import { ItemPayload, ItemsResponse } from '@/features/items/interfaces/itemsResponse';
import { config } from '@/features/shared/actions/config';
import PayloadProps from '@/features/shared/interfaces/PayloadProps';
import HttpService from '@/service/HttpService';
import { HeadersContentType, IHttpParams } from '@/service/IHttpParams';
Expand Down
2 changes: 1 addition & 1 deletion src/features/items/constants/paginationInitialParams.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { InitialPaginationParams } from '@/features/shared/interfaces/InitialPaginationParams';

export const paginationInitialParams: InitialPaginationParams = {
limit: '5',
limit: '6',
offset: '0',
};
7 changes: 2 additions & 5 deletions src/features/items/organisms/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,9 @@ export const List = ({ items, pagination }: Props) => {
handleSearchType();
}, [handleSearchType]);

// TODO: Analizar si esto es realmente necesario
useEffect(() => {
if (items.length === 0) {
handlePage(1);
}
}, [handlePage, items]);
handleReplaceURL();
}, [currentPage]);

return (
<section className={style.container}>
Expand Down
7 changes: 3 additions & 4 deletions src/features/navbar/constants/dataNav.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import { icons } from '@/features/shared/hooks/icons';
import { images } from '@/features/shared/hooks/images';

const { HomeIcon, ItemsIcon, CloseIcon, IconUser, IconSettings, IconLogOut, IconDropdown, UsersIcon } = icons();
const { BgUser } = images();
const { HomeIcon, ItemsIcon, CloseIcon, IconSettings, IconLogOut, IconDropdown, UsersIcon } = icons();
const { Avatar } = images();

export const dataClose = {
image: CloseIcon,
};
export const dataUser = {
image: BgUser,
image: Avatar,
username: 'babyoda@gmail.com',
icon: IconDropdown,
};
export const dataPerfil = [
{
icon: IconUser,
description: 'perfil',
path: '/profile',
},
Expand Down
14 changes: 7 additions & 7 deletions src/features/navbar/molecules/dropdown/DropdownUser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ import { toast } from 'react-toastify';

import { locales } from '@/config';
import { handleSignOut } from '@/features/auth/shared/actions/singOutAction';
import { User } from '@/features/navbar/organisms/NavbarTop';
import { icons } from '@/features/shared/hooks/icons';
import { UserHasRole } from '@/features/shared/interfaces/UserHasRole';
import { AccordionComponent } from '@/features/shared/molecules/accordion/accordion';

import style from './dropdown-user.module.css';

type Props = {
avatar: string | StaticImageData;
dataPerfil: {
icon: StaticImageData;
description: string;
path: string;
}[];
Expand All @@ -37,7 +37,7 @@ type Props = {
isUserDropdownOpen: boolean;
handleDropdownUser: () => void;
id?: string;
user?: User;
user?: UserHasRole;
};

export const DropdownUser = (props: Props) => {
Expand All @@ -64,12 +64,12 @@ export const DropdownUser = (props: Props) => {
<div className={style.container}>
<div className={style.containerIconUser}>
<button onClick={props.handleDropdownUser} className={`${style.iconUser} ${background}`}>
<Image src={props.user?.image_id ?? props.dataUser.image} alt={'Icon user'} height={1080} width={1080} />
<Image src={props.avatar} alt={'Icon user'} height={1080} width={1080} />
<Image
className={`${style.dropdown} ${rotate}`}
width={82}
height={82}
src={props.user?.image_id ?? props.dataUser.icon}
src={props.user?.user_id.image_id ?? props.dataUser.icon}
alt={'dropdown'}
/>
</button>
Expand All @@ -84,12 +84,12 @@ export const DropdownUser = (props: Props) => {
<div className={style.containerIconUserOpen}>
<Image
className={style.profileImage}
src={props.user?.image_id ?? props.dataUser.image}
src={props.user?.user_id.image_id ?? props.dataUser.image}
alt={'Icon user'}
width={82}
height={82}
/>
<p>{props.user?.first_name ?? props.dataUser.username}</p>
<p>{props.user?.user_id.first_name ?? props.dataUser.username}</p>
</div>
{props.dataPerfil.map(({ description, path }) => (
<Link href={path ?? '#'} key={t(description)} className={style.perfilSections}>
Expand Down
27 changes: 16 additions & 11 deletions src/features/navbar/organisms/NavbarTop.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,23 @@
'use client';
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';

import { useContextUser } from '@/contexts/UserContext';
import { dataLogin, dataPerfil, dataUser } from '@/features/navbar/constants/dataNav';
import { DropdownUser } from '@/features/navbar/molecules/dropdown/DropdownUser';
import { ChangeLanguage } from '@/features/shared/atoms/changeLanguage/changeLanguage';
import ThemeSwitcher from '@/features/shared/atoms/swich/ThemeSwitcher';

import style from './navbar-top.module.css';
import { UserHasRole } from '@/features/shared/interfaces/UserHasRole';

export interface User {
phone: string | null;
email: string | null;
last_name: string | null;
first_name: string | null;
id: string;
image_id: string | null;
}
import style from './navbar-top.module.css';

type Props = {
isPublic: boolean;
user?: User;
user?: UserHasRole;
};

export const NavbarTop = (props: Props) => {
const { avatar, handleSetAvatar } = useContextUser();
const [isUserDropdownOpen, setIsUserDropdownOpen] = useState<boolean>(false);
const [isLangDropdownOpen, setIsLangDropdownOpen] = useState<boolean>(false);
const handleDropdownUser = () => {
Expand All @@ -33,6 +28,15 @@ export const NavbarTop = (props: Props) => {
setIsLangDropdownOpen(!isLangDropdownOpen);
setIsUserDropdownOpen(false);
};
const handleSetAvatarUser = () => {
if (props.user?.user_id.image_id) {
handleSetAvatar(props.user.user_id.image_id);
}
};

useEffect(() => {
handleSetAvatarUser();
}, []);

return (
<header className={style.container}>
Expand All @@ -46,6 +50,7 @@ export const NavbarTop = (props: Props) => {
<>
<ChangeLanguage isLangDropdownOpen={isLangDropdownOpen} handleDropdownLang={handleDropdownLang} />
<DropdownUser
avatar={avatar}
dataPerfil={dataPerfil}
style={style}
dataUser={dataUser}
Expand Down
9 changes: 8 additions & 1 deletion src/features/navbar/template/NavbarTopTemplate.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import React from 'react';

import { NavbarTop } from '@/features/navbar/organisms/NavbarTop';
import { fetchUser } from '@/features/shared/actions/fetchUsers';
import { handleGetFile } from '@/features/shared/actions/fileActions';
import { fetchUser } from '@/features/shared/actions/userActions';

type Props = {
isPublic: boolean;
};

export const NavbarTopTemplate = async (props: Props) => {
const user = props.isPublic ? undefined : await fetchUser();

if (user) {
const metadata = await handleGetFile(user.user_id.image_id);
user.user_id.image_id = metadata.path;
}

return <NavbarTop isPublic={props.isPublic} user={user} />;
};
Loading

0 comments on commit 405baa0

Please sign in to comment.