fix bug invite user

This commit is contained in:
vergiLgood1 2025-03-23 06:28:39 +07:00
parent 0af8a9be0b
commit 398ca613ba
9 changed files with 54 additions and 32 deletions

View File

@ -52,7 +52,7 @@ function SubSubItemComponent({ item }: { item: SubSubItem }) {
asChild
className={
isActive
? "bg-primary/10 active text-primary"
? "bg-primary/40 active text-primary"
: ""
}
>
@ -77,7 +77,7 @@ function SubItemComponent({ item }: { item: SubItem }) {
asChild
className={
isActive
? "bg-primary/10 active text-primary"
? "bg-primary/40 active text-primary"
: ""
}
>
@ -99,7 +99,7 @@ function SubItemComponent({ item }: { item: SubItem }) {
<SidebarMenuButton
className={
isActive
? "bg-primary/10 active text-primary"
? "bg-primary/40 active text-primary"
: ""
}
>
@ -138,7 +138,7 @@ function RecursiveNavItem({ item, index }: { item: NavItem; index: number }) {
asChild
className={
isActive
? "bg-primary/10 active text-primary"
? "bg-primary/40 active text-primary"
: ""
}
>
@ -166,7 +166,7 @@ function RecursiveNavItem({ item, index }: { item: NavItem; index: number }) {
tooltip={item.title}
className={
isActive
? "bg-primary/10 active text-primary"
? "bg-primary/40 active text-primary"
: ""
}
>

View File

@ -143,17 +143,21 @@ export default function UserManagement() {
user={detailUser}
open={isSheetOpen}
onOpenChange={setIsSheetOpen}
onUserUpdate={() => refetch()}
onUserUpdate={() => { }}
/>
)}
<AddUserDialog open={isAddUserOpen} onOpenChange={setIsAddUserOpen} onUserAdded={() => refetch()} />
<AddUserDialog
open={isAddUserOpen}
onOpenChange={setIsAddUserOpen}
onUserAdded={() => { }}
/>
<InviteUserDialog open={isInviteUserOpen} onOpenChange={setIsInviteUserOpen} onUserInvited={() => refetch()} />
{updateUser && (
<UserProfileSheet
open={isUpdateOpen}
onOpenChange={setIsUpdateOpen}
userData={updateUser}
onUserUpdated={() => refetch()}
onUserUpdated={() => { }}
/>
)}
</div>

View File

@ -14,6 +14,7 @@ import { IBanDuration, IBanUserSchema, ICredentialsBanUserSchema } from '@/src/e
import { ICreateUserSchema } from '@/src/entities/models/users/create-user.model';
import { IUpdateUserSchema } from '@/src/entities/models/users/update-user.model';
import { ICredentialsInviteUserSchema } from '@/src/entities/models/users/invite-user.model';
import { ICredentialGetUserByEmailSchema } from '@/src/entities/models/users/read-user.model';
export async function banUser(id: string, ban_duration: IBanDuration) {
const instrumentationService = getInjection('IInstrumentationService');
@ -116,9 +117,7 @@ export async function getCurrentUser() {
{ recordResponse: true },
async () => {
try {
const getCurrentUserController = getInjection(
'IGetCurrentUserController'
);
const getCurrentUserController = getInjection('IGetCurrentUserController');
return await getCurrentUserController();
} catch (err) {
@ -182,7 +181,7 @@ export async function getUserById(id: string) {
);
}
export async function getUserByEmail(email: string) {
export async function getUserByEmail(credential: ICredentialGetUserByEmailSchema) {
const instrumentationService = getInjection('IInstrumentationService');
return await instrumentationService.instrumentServerAction(
'getUserByEmail',
@ -192,7 +191,7 @@ export async function getUserByEmail(email: string) {
const getUserByEmailController = getInjection(
'IGetUserByEmailController'
);
return await getUserByEmailController({ email });
return await getUserByEmailController({ email: credential.email });
} catch (err) {

View File

@ -7,11 +7,14 @@ import { CreateUserSchema, defaulICreateUserSchemaValues, ICreateUserSchema } fr
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { defaulIInviteUserSchemaValues, IInviteUserSchema, InviteUserSchema } from '@/src/entities/models/users/invite-user.model';
import { useQueryClient } from '@tanstack/react-query';
export const useAddUserDialogHandler = ({ onUserAdded, onOpenChange }: {
onUserAdded: () => void;
onOpenChange: (open: boolean) => void;
}) => {
const queryClient = useQueryClient();
const { createUser, isPending } = useCreateUserMutation();
const {
@ -38,7 +41,11 @@ export const useAddUserDialogHandler = ({ onUserAdded, onOpenChange }: {
await createUser(data, {
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["users"] });
toast.success("User created successfully.");
onUserAdded();
onOpenChange(false);
reset();
@ -76,6 +83,7 @@ export const useInviteUserHandler = ({ onUserInvited, onOpenChange }: {
onOpenChange: (open: boolean) => void;
}) => {
const queryClient = useQueryClient();
const { inviteUser, isPending } = useInviteUserMutation();
const {
@ -95,7 +103,11 @@ export const useInviteUserHandler = ({ onUserInvited, onOpenChange }: {
const onSubmit = handleSubmit(async (data) => {
await inviteUser(data, {
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["users"] });
toast.success("Invitation sent");
onUserInvited();
onOpenChange(false);
reset();

View File

@ -40,7 +40,7 @@ const useUsersAction = () => {
const getUserByEmailQuery = (email: string) => ({
queryKey: ["user", "email", email],
queryFn: async () => await getUserByEmail(email)
queryFn: async () => await getUserByEmail({ email })
});
const getUserByUsernameQuery = (username: string) => ({

View File

@ -17,7 +17,7 @@
--popover-foreground: 0 0% 10%; /* #1a1a1a */
/* Warna utama: hijau Supabase #006239 */
--primary: 155% 100% 19%; /* #006239 */
--primary: 155 100% 19%; /* #006239 */
--primary-foreground: 0 0% 100%; /* #ffffff untuk kontras pada hijau */
/* Sekunder: abu-abu terang untuk elemen pendukung */
@ -41,13 +41,13 @@
--input: 0 0% 80%; /* #cccccc */
/* Ring: sama dengan primary untuk fokus */
--ring: 155% 100% 19%; /* #006239 */
--ring: 155 100% 19%; /* #006239 */
/* Radius: sudut membulat ringan */
--radius: 0.5rem;
/* Chart: gunakan hijau Supabase dan variasi */
--chart-1: 155% 100% 19%; /* #006239 */
--chart-1: 155 100% 19%; /* #006239 */
--chart-2: 160 60% 45%; /* sedikit lebih gelap */
--chart-3: 165 55% 40%;
--chart-4: 170 50% 35%;
@ -56,12 +56,12 @@
/* Sidebar: mirip dengan kartu di mode terang */
--sidebar-background: 0 0% 98%; /* #fafafa */
--sidebar-foreground: 0 0% 10%; /* #1a1a1a */
--sidebar-primary: 155% 100% 19%; /* #006239 */
--sidebar-primary: 155 100% 19%; /* #006239 */
--sidebar-primary-foreground: 0 0% 100%; /* #ffffff */
--sidebar-accent: 0 0% 96%; /* #f5f5f5 */
--sidebar-accent-foreground: 0 0% 10%; /* #1a1a1a */
--sidebar-border: 0 0% 85%; /* #d9d9d9 */
--sidebar-ring: 155% 100% 19%; /* #006239 */
--sidebar-ring: 155 100% 19%; /* #006239 */
}
.dark {
@ -78,7 +78,7 @@
--popover-foreground: 0 0% 85%; /* #d9d9d9 */
/* Warna utama: hijau Supabase tetap digunakan */
--primary: 155% 100% 19%; /* #006239 */
--primary: 155 100% 19%; /* #006239 */
--primary-foreground: 0 0% 100%; /* #ffffff */
/* Sekunder: abu-abu gelap untuk elemen pendukung */
@ -102,10 +102,10 @@
--input: 0 0% 20%; /* #333333 */
/* Ring: sama dengan primary */
--ring: 155% 100% 19%; /* #006239 */
--ring: 155 100% 19%; /* #006239 */
/* Chart: sama seperti mode terang */
--chart-1: 155% 100% 19%; /* #006239 */
--chart-1: 155 100% 19%; /* #006239 */
--chart-2: 160 60% 45%;
--chart-3: 165 55% 40%;
--chart-4: 170 50% 35%;
@ -114,12 +114,12 @@
/* Sidebar: abu-abu gelap */
--sidebar-background: 0 0% 15%; /* #262626 */
--sidebar-foreground: 0 0% 85%; /* #d9d9d9 */
--sidebar-primary: 155% 100% 19%; /* #006239 */
--sidebar-primary: 155 100% 19%; /* #006239 */
--sidebar-primary-foreground: 0 0% 100%; /* #ffffff */
--sidebar-accent: 0 0% 20%; /* #333333 */
--sidebar-accent-foreground: 0 0% 85%; /* #d9d9d9 */
--sidebar-border: 0 0% 25%; /* #404040 */
--sidebar-ring: 155% 100% 19%; /* #006239 */
--sidebar-ring: 155 100% 19%; /* #006239 */
}
}

View File

@ -1,4 +1,4 @@
import { VerifyOtpSchema } from "@/src/entities/models/auth/verify-otp.model"
import { IVerifyOtpSchema } from "@/src/entities/models/auth/verify-otp.model"
import { IUsersRepository } from "../../repositories/users.repository.interface"
import { IAuthenticationService } from "../../services/authentication.service.interface"
import { IInstrumentationService } from "../../services/instrumentation.service.interface"
@ -12,15 +12,18 @@ export const verifyOtpUseCase = (
instrumentationService: IInstrumentationService,
authenticationService: IAuthenticationService,
usersRepository: IUsersRepository
) => async (input: VerifyOtpSchema): Promise<void> => {
) => async (input: IVerifyOtpSchema): Promise<void> => {
return await instrumentationService.startSpan({ name: "verifyOtp Use Case", op: "function" },
async () => {
const user = await usersRepository.getUserByEmail(input.email)
const user = await usersRepository.getUserByEmail({ email: input.email })
if (!user) {
throw new NotFoundError("User not found")
}
console.log("email = ", user.email)
await authenticationService.verifyOtp({
email: input.email,
token: input.token

View File

@ -14,11 +14,12 @@ export const inviteUserUseCase = (
) => async (credential: ICredentialsInviteUserSchema): Promise<IUserSchema> => {
return await instrumentationService.startSpan({ name: "inviteUser Use Case", op: "function" },
async () => {
const existingUser = await usersRepository.getUserByEmail(credential)
if (existingUser) {
throw new AuthenticationError("User already exists")
}
// const existingUser = await usersRepository.getUserByEmail(credential)
// if (existingUser) {
// throw new AuthenticationError("User already exists")
// }
const invitedUser = await usersRepository.inviteUser(credential)

View File

@ -18,6 +18,9 @@ export const verifyOtpController =
) =>
async (input: Partial<z.infer<typeof verifyOtpInputSchema>>) => {
return await instrumentationService.startSpan({ name: "verifyOtp Controller" }, async () => {
// console.log("input", input)
const { data, error: inputParseError } = verifyOtpInputSchema.safeParse(input)
if (inputParseError) {