Skip to content

PROD - gamification / skills management consolidation. SSO users option #1123

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jun 26, 2025
Merged
3 changes: 2 additions & 1 deletion src/apps/admin/src/AdminApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Outlet, Routes } from 'react-router-dom'

import { routerContext, RouterContextData } from '~/libs/core'

import { AdminAppContextProvider, Layout, SWRConfigProvider } from './lib'
import { AdminAppContextProvider, LayoutProps, SWRConfigProvider, useLayout } from './lib'
import { toolTitle } from './admin-app.routes'
import './lib/styles/index.scss'

Expand All @@ -14,6 +14,7 @@ const AdminApp: FC = () => {
const { getChildRoutes }: RouterContextData = useContext(routerContext)
// eslint-disable-next-line react-hooks/exhaustive-deps -- missing dependency: getChildRoutes
const childRoutes = useMemo(() => getChildRoutes(toolTitle), [])
const { Layout }: { Layout: FC<LayoutProps> } = useLayout()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding error handling for the useLayout() hook in case it returns an unexpected value or fails to provide the Layout component.


useEffect(() => {
document.body.classList.add('admin-app')
Expand Down
59 changes: 59 additions & 0 deletions src/apps/admin/src/admin-app.routes.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { baseDetailPath, createBadgePath } from '~/apps/gamification-admin'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import statement for baseDetailPath and createBadgePath should be checked to ensure these paths are correct and that the modules exist in the specified location. If these imports are not used in the file, consider removing them to keep the code clean.

import { AppSubdomain, ToolTitle } from '~/config'
import {
lazyLoad,
Expand All @@ -9,12 +10,15 @@ import {

import {
billingAccountRouteId,
gamificationAdminRouteId,
manageChallengeRouteId,
manageReviewRouteId,
permissionManagementRouteId,
platformRouteId,
rootRoute,
userManagementRouteId,
} from './config/routes.config'
import { platformSkillRouteId } from './platform/routes.config'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider organizing the imports alphabetically for better readability and consistency.


const AdminApp: LazyLoadedComponent = lazyLoad(() => import('./AdminApp'))

Expand Down Expand Up @@ -107,6 +111,24 @@ const PermissionAddGroupMembersPage: LazyLoadedComponent = lazyLoad(
'PermissionAddGroupMembersPage',
)

const Platform: LazyLoadedComponent = lazyLoad(() => import('./platform/Platform'))
const SkillManagement: LazyLoadedComponent = lazyLoad(
() => import('./platform/skill-management/SkillManagement'),
)
const SkillManagementLandingPage: LazyLoadedComponent = lazyLoad(
() => import('./platform/skill-management/LandingPage'),
'LandingPage',
)
const BadgeDetailPage: LazyLoadedComponent = lazyLoad(
() => import('../../gamification-admin/src/pages/badge-detail/BadgeDetailPage'),
)
const BadgeListingPage: LazyLoadedComponent = lazyLoad(
() => import('../../gamification-admin/src/pages/badge-listing/BadgeListingPage'),
)
const CreateBadgePage: LazyLoadedComponent = lazyLoad(
() => import('../../gamification-admin/src/pages/create-badge/CreateBadgePage'),
)

export const toolTitle: string = ToolTitle.admin

export const adminRoutes: ReadonlyArray<PlatformRoute> = [
Expand Down Expand Up @@ -256,6 +278,43 @@ export const adminRoutes: ReadonlyArray<PlatformRoute> = [
id: permissionManagementRouteId,
route: permissionManagementRouteId,
},

// Platform Management Module
{
children: [
{
children: [
{
element: <SkillManagementLandingPage />,
id: 'skills-landing-page',
route: '',

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider specifying a more descriptive route path instead of an empty string for better clarity and maintainability.

},
],
element: <SkillManagement />,
id: platformSkillRouteId,
route: platformSkillRouteId,
},
{
element: (
<BadgeListingPage
rootPage={`${rootRoute}/${platformRouteId}/${gamificationAdminRouteId}`}
/>
),
route: gamificationAdminRouteId,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that the rootPage prop is correctly constructed and that all variables used in the template literal are defined and imported as needed.

},
{
element: <CreateBadgePage />,
route: `${gamificationAdminRouteId}${createBadgePath}`,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verify that createBadgePath is defined and correctly imported to avoid runtime errors.

},
{
element: <BadgeDetailPage />,
route: `${gamificationAdminRouteId}${baseDetailPath}/:id`,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that baseDetailPath is defined and correctly imported. Also, confirm that the dynamic segment :id is handled properly in the application logic.

},
],
element: <Platform />,
id: platformRouteId,
route: platformRouteId,
},
],
domain: AppSubdomain.admin,
element: <AdminApp />,
Expand Down
2 changes: 2 additions & 0 deletions src/apps/admin/src/config/routes.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ export const manageReviewRouteId = 'review-management'
export const userManagementRouteId = 'user-management'
export const billingAccountRouteId = 'billing-account'
export const permissionManagementRouteId = 'permission-management'
export const gamificationAdminRouteId = 'gamification-admin'
export const platformRouteId = 'platform'
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@
position: relative;
}

.blockForm {
display: flex;
flex-direction: column;
gap: 20px;
position: relative;
}

.actionButtons {
display: flex;
justify-content: flex-end;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export const DialogEditUserEmail: FC<Props> = (props: Props) => {
className={classNames(styles.container, props.className)}
onSubmit={handleSubmit(onSubmit)}
>
<div>
<div className={styles.blockForm}>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider verifying if the styles.blockForm class is defined and used correctly in the stylesheet. Ensure it does not conflict with existing styles or cause unintended layout changes.

<InputText
type='text'
name='id'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
.modal {
width: 800px !important;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid using !important unless absolutely necessary, as it can make the CSS harder to maintain and override.

}

.container {
display: flex;
flex-direction: column;
gap: 20px;
position: relative;
align-items: flex-start;

th:first-child {
padding-left: 16px !important;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using !important should be avoided if possible. Consider refactoring the CSS to achieve the desired effect without it.

}
}

.tableCell {
white-space: break-spaces !important;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of !important can lead to specificity issues in CSS. Try to refactor the styles to avoid using it.

text-align: left !important;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider removing !important to maintain cleaner and more manageable CSS.

}

.actionButtons {
display: flex;
justify-content: flex-end;
gap: 6px;
width: 100%;
}

.btnActions {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .btnActions class appears to have the same styles as .actionButtons. Consider consolidating these classes if they serve the same purpose.

display: flex;
justify-content: flex-end;
gap: 6px;
}

.blockAction {
width: 120px;
}

.loadingSpinnerContainer {
position: relative;
height: 100px;

.spinner {
background: none;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .spinner class is defined twice with the same background: none; style. Consider consolidating these styles to avoid redundancy.

}
}

.dialogLoadingSpinnerContainer {
position: absolute;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
bottom: 0;
height: 64px;
left: 0;

.spinner {
background: none;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .spinner class is defined twice with the same background: none; style. Consider consolidating these styles to avoid redundancy.

}
}

.desktopTable {
td {
vertical-align: middle;
}
}

.mobileTable {
width: 100%;
}
Loading