* fix: enhance DataTable pagination examples and improve display logic - Added a note in the DataTableStory component to clarify that examples show only the first page of data for demonstration purposes. - Adjusted pagination examples to reflect smaller datasets, changing the displayed data slices for better clarity and testing. - Updated the Pagination component to calculate and display the current record range more accurately based on the current page index and size. * chore(dependencies): update package versions for improved compatibility - Upgraded `@supabase/supabase-js` from `2.55.0` to `2.57.0` for enhanced functionality and performance. - Bumped `@tanstack/react-query` from `5.85.5` to `5.85.9` to incorporate the latest improvements. - Updated `ai` from `5.0.28` to `5.0.30` for better performance. - Incremented `nodemailer` from `7.0.5` to `7.0.6` for stability. - Updated `typescript-eslint` from `8.41.0` to `8.42.0` for improved type definitions and linting capabilities. - Adjusted various package dependencies across multiple components to ensure compatibility and stability. * chore(dependencies): update package versions for improved compatibility - Upgraded `@ai-sdk/openai` from `2.0.23` to `2.0.24` for enhanced functionality. - Bumped `@tanstack/react-query` from `5.85.9` to `5.86.0` to incorporate the latest improvements. - Updated `ai` from `5.0.30` to `5.0.33` for better performance. - Incremented `@types/node` from `24.3.0` to `24.3.1` for type safety enhancements. - Updated `dotenv` from `17.2.1` to `17.2.2` for stability. - Adjusted `tailwindcss` and related packages to `4.1.13` for improved styling capabilities. - Updated `react-i18next` from `15.7.3` to `15.7.3` to include the latest localization fixes. - Incremented `@sentry/nextjs` from `10.8.0` to `10.10.0` for enhanced monitoring features. - Updated various package dependencies across multiple components to ensure compatibility and stability. * fix(config): conditionally disable `devIndicators` in CI environment * feat(settings): encapsulate danger zone actions in a styled card component - Introduced a new `DangerZoneCard` component to enhance the visual presentation of danger zone actions in the team account settings. - Updated `TeamAccountDangerZone` to wrap deletion and leave actions within the `DangerZoneCard` for improved user experience. - Removed redundant card structure from `TeamAccountSettingsContainer` to streamline the component hierarchy. * fix(e2e): improve admin account tests for response handling and visibility checks - Enhanced the admin test suite by adding a check for the POST request method when waiting for the response from the `/admin/accounts` endpoint. - Reduced wait times in the `filterAccounts` function for improved test performance. - Updated the `selectAccount` function to ensure the account link is visible before clicking, enhancing reliability in the test flow. * chore(dependencies): update package versions for improved compatibility - Upgraded `@supabase/supabase-js` from `2.57.0` to `2.57.2` for enhanced functionality and performance. - Bumped `@tanstack/react-query` from `5.86.0` to `5.87.1` to incorporate the latest improvements. - Updated `i18next` from `25.5.1` to `25.5.2` for better localization support. - Incremented `eslint` from `9.34.0` to `9.35.0` for improved linting capabilities. - Adjusted various package dependencies across multiple components to ensure compatibility and stability. * feat(admin): enhance user ban and reactivation actions with success handling - Updated `AdminBanUserDialog` and `AdminReactivateUserDialog` components to handle success states based on the results of the respective actions. - Modified `banUserAction` and `reactivateUserAction` to return success status and log errors if the actions fail. - Introduced `revalidatePage` function to refresh the user account page after banning or reactivating a user. - Improved error handling in the dialogs to provide better feedback to the admin user. * feat(admin): refactor user ban and reactivation dialogs for improved structure and error handling - Introduced `BanUserForm` and `ReactivateUserForm` components to encapsulate form logic within the respective dialogs, enhancing readability and maintainability. - Updated the `AdminBanUserDialog` and `AdminReactivateUserDialog` components to utilize the new form components, streamlining the user interface. - Enhanced error handling to provide clearer feedback to the admin user during ban and reactivation actions. - Removed unnecessary revalidation calls in the server actions to optimize performance and maintain clarity in the action flow. - Added `@types/react-dom` dependency for improved type definitions. * refactor(admin): streamline user dialogs and server actions for improved clarity - Removed unnecessary `useRouter` imports from `AdminBanUserDialog` and `AdminReactivateUserDialog` components to simplify the code. - Updated `revalidateAdmin` function calls to use `revalidatePath` with specific paths, enhancing clarity in the server actions. - Ensured that the user dialogs maintain a clean structure while focusing on form logic and error handling.
253 lines
5.9 KiB
TypeScript
253 lines
5.9 KiB
TypeScript
'use server';
|
|
|
|
import { revalidatePath } from 'next/cache';
|
|
import { redirect } from 'next/navigation';
|
|
|
|
import { enhanceAction } from '@kit/next/actions';
|
|
import { getLogger } from '@kit/shared/logger';
|
|
import { getSupabaseServerAdminClient } from '@kit/supabase/server-admin-client';
|
|
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
|
|
|
import {
|
|
BanUserSchema,
|
|
DeleteAccountSchema,
|
|
DeleteUserSchema,
|
|
ImpersonateUserSchema,
|
|
ReactivateUserSchema,
|
|
} from './schema/admin-actions.schema';
|
|
import { CreateUserSchema } from './schema/create-user.schema';
|
|
import { ResetPasswordSchema } from './schema/reset-password.schema';
|
|
import { createAdminAccountsService } from './services/admin-accounts.service';
|
|
import { createAdminAuthUserService } from './services/admin-auth-user.service';
|
|
import { adminAction } from './utils/admin-action';
|
|
|
|
/**
|
|
* @name banUserAction
|
|
* @description Ban a user from the system.
|
|
*/
|
|
export const banUserAction = adminAction(
|
|
enhanceAction(
|
|
async ({ userId }) => {
|
|
const service = getAdminAuthService();
|
|
const logger = await getLogger();
|
|
|
|
logger.info({ userId }, `Super Admin is banning user...`);
|
|
|
|
const { error } = await service.banUser(userId);
|
|
|
|
if (error) {
|
|
logger.error({ error }, `Error banning user`);
|
|
|
|
return {
|
|
success: false,
|
|
};
|
|
}
|
|
|
|
logger.info({ userId }, `Super Admin has successfully banned user`);
|
|
|
|
revalidateAdmin();
|
|
|
|
return {
|
|
success: true,
|
|
};
|
|
},
|
|
{
|
|
schema: BanUserSchema,
|
|
},
|
|
),
|
|
);
|
|
|
|
/**
|
|
* @name reactivateUserAction
|
|
* @description Reactivate a user in the system.
|
|
*/
|
|
export const reactivateUserAction = adminAction(
|
|
enhanceAction(
|
|
async ({ userId }) => {
|
|
const service = getAdminAuthService();
|
|
const logger = await getLogger();
|
|
|
|
logger.info({ userId }, `Super Admin is reactivating user...`);
|
|
|
|
const { error } = await service.reactivateUser(userId);
|
|
|
|
if (error) {
|
|
logger.error({ error }, `Error reactivating user`);
|
|
|
|
return {
|
|
success: false,
|
|
};
|
|
}
|
|
|
|
revalidateAdmin();
|
|
|
|
logger.info({ userId }, `Super Admin has successfully reactivated user`);
|
|
|
|
return {
|
|
success: true,
|
|
};
|
|
},
|
|
{
|
|
schema: ReactivateUserSchema,
|
|
},
|
|
),
|
|
);
|
|
|
|
/**
|
|
* @name impersonateUserAction
|
|
* @description Impersonate a user in the system.
|
|
*/
|
|
export const impersonateUserAction = adminAction(
|
|
enhanceAction(
|
|
async ({ userId }) => {
|
|
const service = getAdminAuthService();
|
|
const logger = await getLogger();
|
|
|
|
logger.info({ userId }, `Super Admin is impersonating user...`);
|
|
|
|
return await service.impersonateUser(userId);
|
|
},
|
|
{
|
|
schema: ImpersonateUserSchema,
|
|
},
|
|
),
|
|
);
|
|
|
|
/**
|
|
* @name deleteUserAction
|
|
* @description Delete a user from the system.
|
|
*/
|
|
export const deleteUserAction = adminAction(
|
|
enhanceAction(
|
|
async ({ userId }) => {
|
|
const service = getAdminAuthService();
|
|
const logger = await getLogger();
|
|
|
|
logger.info({ userId }, `Super Admin is deleting user...`);
|
|
|
|
await service.deleteUser(userId);
|
|
|
|
logger.info({ userId }, `Super Admin has successfully deleted user`);
|
|
|
|
return redirect('/admin/accounts');
|
|
},
|
|
{
|
|
schema: DeleteUserSchema,
|
|
},
|
|
),
|
|
);
|
|
|
|
/**
|
|
* @name deleteAccountAction
|
|
* @description Delete an account from the system.
|
|
*/
|
|
export const deleteAccountAction = adminAction(
|
|
enhanceAction(
|
|
async ({ accountId }) => {
|
|
const service = getAdminAccountsService();
|
|
const logger = await getLogger();
|
|
|
|
logger.info({ accountId }, `Super Admin is deleting account...`);
|
|
|
|
await service.deleteAccount(accountId);
|
|
|
|
revalidateAdmin();
|
|
|
|
logger.info(
|
|
{ accountId },
|
|
`Super Admin has successfully deleted account`,
|
|
);
|
|
|
|
return redirect('/admin/accounts');
|
|
},
|
|
{
|
|
schema: DeleteAccountSchema,
|
|
},
|
|
),
|
|
);
|
|
|
|
/**
|
|
* @name createUserAction
|
|
* @description Create a new user in the system.
|
|
*/
|
|
export const createUserAction = adminAction(
|
|
enhanceAction(
|
|
async ({ email, password, emailConfirm }) => {
|
|
const adminClient = getSupabaseServerAdminClient();
|
|
const logger = await getLogger();
|
|
|
|
logger.info({ email }, `Super Admin is creating a new user...`);
|
|
|
|
const { data, error } = await adminClient.auth.admin.createUser({
|
|
email,
|
|
password,
|
|
email_confirm: emailConfirm,
|
|
});
|
|
|
|
if (error) {
|
|
logger.error({ error }, `Error creating user`);
|
|
throw new Error(`Error creating user: ${error.message}`);
|
|
}
|
|
|
|
logger.info(
|
|
{ userId: data.user.id },
|
|
`Super Admin has successfully created a new user`,
|
|
);
|
|
|
|
revalidatePath(`/admin/accounts`);
|
|
|
|
return {
|
|
success: true,
|
|
user: data.user,
|
|
};
|
|
},
|
|
{
|
|
schema: CreateUserSchema,
|
|
},
|
|
),
|
|
);
|
|
|
|
/**
|
|
* @name resetPasswordAction
|
|
* @description Reset a user's password by sending a password reset email.
|
|
*/
|
|
export const resetPasswordAction = adminAction(
|
|
enhanceAction(
|
|
async ({ userId }) => {
|
|
const service = getAdminAuthService();
|
|
const logger = await getLogger();
|
|
|
|
logger.info({ userId }, `Super Admin is resetting user password...`);
|
|
|
|
const result = await service.resetPassword(userId);
|
|
|
|
logger.info(
|
|
{ userId },
|
|
`Super Admin has successfully sent password reset email`,
|
|
);
|
|
|
|
return result;
|
|
},
|
|
{
|
|
schema: ResetPasswordSchema,
|
|
},
|
|
),
|
|
);
|
|
|
|
function revalidateAdmin() {
|
|
revalidatePath(`/admin/accounts/[id]`, 'page');
|
|
}
|
|
|
|
function getAdminAuthService() {
|
|
const client = getSupabaseServerClient();
|
|
const adminClient = getSupabaseServerAdminClient();
|
|
|
|
return createAdminAuthUserService(client, adminClient);
|
|
}
|
|
|
|
function getAdminAccountsService() {
|
|
const adminClient = getSupabaseServerAdminClient();
|
|
|
|
return createAdminAccountsService(adminClient);
|
|
}
|