Skip to content

Commit

Permalink
feat(i18n): localize table column labels for achievements, leaderboar…
Browse files Browse the repository at this point in the history
…d, and videos

Updated table column labels across achievements, leaderboard, and videos components to support localization:

- Replaced hardcoded column names with translatable messages using `react-intl`.
- Added new translation keys for columns like "Title," "Rank," "Actions," and "Published."
- Improved maintainability and accessibility for non-English-speaking users.

This ensures all table headers are properly localized.
  • Loading branch information
phungmanhcuong committed Dec 17, 2024
1 parent eed61a6 commit 03d38e1
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FC, memo } from 'react';
import { defineMessages, FormattedMessage } from 'react-intl';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import { DragIndicator } from '@mui/icons-material';
import { Switch, Typography } from '@mui/material';
import equal from 'fast-deep-equal';
Expand Down Expand Up @@ -30,6 +30,30 @@ const translations = defineMessages({
id: 'course.achievement.AchievementTable.noAchievement',
defaultMessage: 'No achievement',
},
badge: {
id: 'course.achievement.AchievementTable.badge',
defaultMessage: 'Badge',
},
title: {
id: 'course.achievement.AchievementTable.title',
defaultMessage: 'Title',
},
description: {
id: 'course.achievement.AchievementTable.description',
defaultMessage: 'Description',
},
requirements: {
id: 'course.achievement.AchievementTable.requirements',
defaultMessage: 'Requirements',
},
published: {
id: 'course.achievement.AchievementTable.published',
defaultMessage: 'Published',
},
actions: {
id: 'course.achievement.AchievementTable.actions',
defaultMessage: 'Actions',
},
});

const styles = {
Expand All @@ -42,6 +66,7 @@ const styles = {

const AchievementTable: FC<Props> = (props) => {
const { achievements, permissions, onTogglePublished, isReordering } = props;
const { formatMessage: t } = useIntl();

if (achievements && achievements.length === 0) {
return (
Expand Down Expand Up @@ -104,7 +129,7 @@ const AchievementTable: FC<Props> = (props) => {
},
{
name: 'badge',
label: 'Badge',
label: t(translations.badge),
options: {
filter: false,
sort: false,
Expand All @@ -128,7 +153,7 @@ const AchievementTable: FC<Props> = (props) => {
},
{
name: 'title',
label: 'Title',
label: t(translations.title),
options: {
filter: false,
sort: false,
Expand All @@ -149,7 +174,7 @@ const AchievementTable: FC<Props> = (props) => {
},
{
name: 'description',
label: 'Description',
label: t(translations.description),
options: {
filter: false,
sort: false,
Expand All @@ -170,7 +195,7 @@ const AchievementTable: FC<Props> = (props) => {
},
{
name: 'conditions',
label: 'Requirements',
label: t(translations.requirements),
options: {
filter: false,
sort: false,
Expand All @@ -194,7 +219,7 @@ const AchievementTable: FC<Props> = (props) => {
if (permissions?.canManage) {
columns.push({
name: 'published',
label: 'Published',
label: t(translations.published),
options: {
filter: false,
sort: false,
Expand All @@ -218,7 +243,7 @@ const AchievementTable: FC<Props> = (props) => {
});
columns.push({
name: 'id',
label: 'Actions',
label: t(translations.actions),
options: {
filter: false,
sort: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ const translations = defineMessages({
id: 'course.achievement.AchievementAward.AchievementAwardManager.note',
defaultMessage:
'If an Achievement has conditions associated with it, \
Coursemology will automatically award achievements when the student meets those conditions. ',
Coursemology will automatically award achievements when the student meets those conditions. ',
},
noUser: {
id: 'course.achievement.AchievementAward.AchievementAwardManager.noUser',
Expand Down Expand Up @@ -242,7 +242,7 @@ const AchievementAwardManager: FC<Props> = (props) => {
},
{
name: 'id',
label: 'Obtained Achievement',
label: columnHeadLabelAchievement,
options: {
filter: false,
search: false,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { FC } from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { Grid } from '@mui/material';
import { green, red } from '@mui/material/colors';
import { TableColumns, TableOptions } from 'types/components/DataTable';
Expand All @@ -12,8 +13,36 @@ interface Props {
selectedUserIds: Set<number>;
}

const translations = defineMessages({
name: {
id: 'course.achievement.AchievementAward.AchievementAwardSummary.name',
defaultMessage: 'Name',
},
userType: {
id: 'course.achievement.AchievementAward.AchievementAwardSummary.userType',
defaultMessage: 'User Type',
},
awardedStudents: {
id: 'course.achievement.AchievementAward.AchievementAwardSummary.awardedStudents',
defaultMessage: 'Awarded Students',
},
revokedStudents: {
id: 'course.achievement.AchievementAward.AchievementAwardSummary.revokedStudents',
defaultMessage: 'Revoked Students',
},
phantomStudent: {
id: 'course.achievement.AchievementAward.AchievementAwardSummary.phantomStudent',
defaultMessage: 'Phantom Student',
},
normalStudent: {
id: 'course.achievement.AchievementAward.AchievementAwardSummary.normalStudent',
defaultMessage: 'Normal Student',
},
});

const AchievementAwardSummary: FC<Props> = (props) => {
const { achievementUsers, initialObtainedUserIds, selectedUserIds } = props;
const { formatMessage: t } = useIntl();

const removedUserIds = new Set(
[...initialObtainedUserIds].filter(
Expand Down Expand Up @@ -57,22 +86,21 @@ const AchievementAwardSummary: FC<Props> = (props) => {
const awardedTableColumns: TableColumns[] = [
{
name: 'name',
label: 'Name',
label: t(translations.name),
options: {
filter: false,
},
},
{
name: 'phantom',
label: 'User Type',
label: t(translations.userType),
options: {
search: false,
customBodyRenderLite: (dataIndex): string => {
const isPhantom = awardedUsers[dataIndex].phantom;
if (isPhantom) {
return 'Phantom Student';
}
return 'Normal Student';
return isPhantom
? t(translations.phantomStudent)
: t(translations.normalStudent);
},
},
},
Expand All @@ -81,22 +109,21 @@ const AchievementAwardSummary: FC<Props> = (props) => {
const removedTableColumns: TableColumns[] = [
{
name: 'name',
label: 'Name',
label: t(translations.name),
options: {
filter: false,
},
},
{
name: 'phantom',
label: 'User Type',
label: t(translations.userType),
options: {
search: false,
customBodyRenderLite: (dataIndex): string => {
const isPhantom = removedUsers[dataIndex].phantom;
if (isPhantom) {
return 'Phantom Student';
}
return 'Normal Student';
return isPhantom
? t(translations.phantomStudent)
: t(translations.normalStudent);
},
},
},
Expand All @@ -109,15 +136,15 @@ const AchievementAwardSummary: FC<Props> = (props) => {
columns={awardedTableColumns}
data={awardedUsers}
options={awardedTableOptions}
title={`Awarded Students (${awardedUsers.length})`}
title={`${t(translations.awardedStudents)} (${awardedUsers.length})`}
/>
</Grid>
<Grid item xs={6}>
<DataTable
columns={removedTableColumns}
data={removedUsers}
options={removedTableOptions}
title={`Revoked Students (${removedUsers.length})`}
title={`${t(translations.revokedStudents)} (${removedUsers.length})`}
/>
</Grid>
</Grid>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FC, memo, useEffect, useState } from 'react';
import { defineMessages, FormattedMessage } from 'react-intl';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import { Avatar, AvatarGroup, Box, Tooltip } from '@mui/material';
import { TableColumns } from 'types/components/DataTable';
import {
Expand Down Expand Up @@ -48,6 +48,30 @@ const translations = defineMessages({
id: 'course.leaderboard.LeaderboardTable.achievements',
defaultMessage: 'Achievements',
},
rank: {
id: 'course.leaderboard.LeaderboardTable.rank',
defaultMessage: 'Rank',
},
name: {
id: 'course.leaderboard.LeaderboardTable.name',
defaultMessage: 'Name',
},
level: {
id: 'course.leaderboard.LeaderboardTable.level',
defaultMessage: 'Level',
},
averageExperience: {
id: 'course.leaderboard.LeaderboardTable.averageExperience',
defaultMessage: 'Average Experience',
},
averageAchievements: {
id: 'course.leaderboard.LeaderboardTable.averageAchievements',
defaultMessage: 'Average Achievements',
},
members: {
id: 'course.leaderboard.LeaderboardTable.members',
defaultMessage: 'Members',
},
});

const styles = {
Expand Down Expand Up @@ -78,6 +102,7 @@ const styles = {

const LeaderboardTable: FC<Props> = (props: Props) => {
const { data, id: tableType } = props;
const { formatMessage: t } = useIntl();
const tabletView = useMedia.MinWidth('sm');
const phoneView = useMedia.MinWidth('xs');
const [maxAvatars, setMaxAvatars] = useState(6);
Expand All @@ -95,7 +120,7 @@ const LeaderboardTable: FC<Props> = (props: Props) => {
const columns: TableColumns[] = [
{
name: 'id',
label: 'Rank',
label: t(translations.rank),
options: {
filter: false,
sort: false,
Expand All @@ -116,7 +141,7 @@ const LeaderboardTable: FC<Props> = (props: Props) => {
| LeaderboardAchievement[];
columns.push({
name: 'name',
label: 'Name',
label: t(translations.name),
options: {
filter: false,
sort: false,
Expand Down Expand Up @@ -157,7 +182,7 @@ const LeaderboardTable: FC<Props> = (props: Props) => {
columns.push(
{
name: 'level',
label: 'Level',
label: t(translations.level),
options: {
filter: false,
sort: false,
Expand All @@ -172,7 +197,7 @@ const LeaderboardTable: FC<Props> = (props: Props) => {
},
{
name: 'experience',
label: 'Experience',
label: t(translations.experience),
options: {
filter: false,
sort: false,
Expand All @@ -192,7 +217,7 @@ const LeaderboardTable: FC<Props> = (props: Props) => {
const achievementData = data as LeaderboardAchievement[];
columns.push({
name: 'achievements',
label: 'Achievements',
label: t(translations.achievements),
options: {
filter: false,
sort: false,
Expand Down Expand Up @@ -249,7 +274,7 @@ const LeaderboardTable: FC<Props> = (props: Props) => {
columns.push(
{
name: 'name',
label: 'Name',
label: t(translations.name),
options: {
filter: false,
sort: false,
Expand All @@ -268,7 +293,7 @@ const LeaderboardTable: FC<Props> = (props: Props) => {
},
{
name: 'members',
label: 'Members',
label: t(translations.members),
options: {
filter: false,
sort: false,
Expand Down Expand Up @@ -306,7 +331,7 @@ const LeaderboardTable: FC<Props> = (props: Props) => {
const groupPointData = data as GroupLeaderboardPoints[];
columns.push({
name: 'points',
label: 'Average Experience',
label: t(translations.averageExperience),
options: {
filter: false,
sort: false,
Expand All @@ -332,7 +357,7 @@ const LeaderboardTable: FC<Props> = (props: Props) => {
const groupAchievementData = data as GroupLeaderboardAchievement[];
columns.push({
name: 'achievements',
label: 'Average Achievements',
label: t(translations.averageAchievements),
options: {
filter: false,
sort: false,
Expand Down
Loading

0 comments on commit 03d38e1

Please sign in to comment.