Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/courseTeam/CourseTeamPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useIntl } from '@openedx/frontend-base';
import messages from './messages';
import { Button, Tab, Tabs } from '@openedx/paragon';
import MembersContent from './components/MembersContent';
import RolesContent from './components/RolesContent';

const CourseTeamPage = () => {
const intl = useIntl();

return (
<>
<div className="d-flex justify-content-between align-items-center mb-3">
<h3 className="text-primary-700 mb-0">{intl.formatMessage(messages.courseTeamTitle)}</h3>
<Button variant="primary">+ {intl.formatMessage(messages.addTeamMember)}</Button>
</div>
<Tabs>
<Tab eventKey="members" title={intl.formatMessage(messages.membersTab)}>
<MembersContent />
</Tab>
<Tab eventKey="roles" title={intl.formatMessage(messages.rolesTab)}>
<RolesContent />
</Tab>
</Tabs>
</>
);
};

export default CourseTeamPage;
40 changes: 40 additions & 0 deletions src/courseTeam/components/MembersContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { useIntl } from '@openedx/frontend-base';
import { Button, DataTable } from '@openedx/paragon';
import messages from '../messages';

const MembersContent = () => {
const intl = useIntl();
const tableColumns = [
{ accessor: 'username', Header: intl.formatMessage(messages.username) },
{ accessor: 'email', Header: intl.formatMessage(messages.email) },
{ accessor: 'role', Header: intl.formatMessage(messages.role) },
];

const additionalColumns = [{
id: 'actions',
Header: intl.formatMessage(messages.actions),
Cell: () => (
<Button variant="link" size="inline">
{intl.formatMessage(messages.edit)}
</Button>
)
}];

return (
<div>
<DataTable
additionalColumns={additionalColumns}
columns={tableColumns}
data={[]}
RowStatusComponent={() => null}
>
<DataTable.TableControlBar />
<DataTable.Table />
<DataTable.EmptyTable content={intl.formatMessage(messages.noTeamMembers)} />
<DataTable.TableFooter />
</DataTable>
</div>
);
};

export default MembersContent;
42 changes: 42 additions & 0 deletions src/courseTeam/components/RolesContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useIntl } from '@openedx/frontend-base';
import messages from '../messages';

const rolesOrder = [
'staff',
'limitedStaff',
'admin',
'betaTesters',
'courseDataResearchers',
'discussionAdmin',
'discussionModerator',
'groupCommunityTA',
'communityTA'
];

const RolesContent = () => {
const intl = useIntl();
const isCCXCoachEnabled = false; // This would be determined if ccx coach role is present on roles list from API

return (
<div className="mt-4">
{
rolesOrder.map((role) => (
<div key={role} className="mb-4">
<h4 className="text-primary-500">{intl.formatMessage(messages[role])}</h4>
<p className="text-gray-700">{intl.formatMessage(messages[`${role}Description`])}</p>
</div>
))
}
{
isCCXCoachEnabled && (
<div className="mb-4">
<h4 className="text-primary-500">{intl.formatMessage(messages.ccxCoach)}</h4>
<p className="text-gray-700">{intl.formatMessage(messages.ccxCoachDescription)}</p>
</div>
)
}
</div>
);
};

export default RolesContent;
Empty file added src/courseTeam/data/api.ts
Empty file.
Empty file added src/courseTeam/data/apiHook.ts
Empty file.
Empty file.
156 changes: 156 additions & 0 deletions src/courseTeam/messages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import { defineMessages } from '@openedx/frontend-base';

const messages = defineMessages({
courseTeamTitle: {
id: 'instruct.courseTeam.page.title',
defaultMessage: 'Course Team Management',
description: 'Title for the course team page',
},
addTeamMember: {
id: 'instruct.courseTeam.addTeamMember',
defaultMessage: 'Add Team Member',
description: 'Button label for adding a team member',
},
membersTab: {
id: 'instruct.courseTeam.membersTab',
defaultMessage: 'Members',
description: 'Tab title for course team members',
},
rolesTab: {
id: 'instruct.courseTeam.rolesTab',
defaultMessage: 'Roles',
description: 'Tab title for course team roles',
},
username: {
id: 'instruct.courseTeam.username',
defaultMessage: 'Username',
description: 'Column header for team member username',
},
email: {
id: 'instruct.courseTeam.email',
defaultMessage: 'Email',
description: 'Column header for team member email',
},
role: {
id: 'instruct.courseTeam.role',
defaultMessage: 'Role',
description: 'Column header for team member role',
},
actions: {
id: 'instruct.courseTeam.actions',
defaultMessage: 'Actions',
description: 'Column header for team member actions',
},
edit: {
id: 'instruct.courseTeam.edit',
defaultMessage: 'Edit',
description: 'Button label for editing a team member',
},
noTeamMembers: {
id: 'instruct.courseTeam.noTeamMembers',
defaultMessage: 'No team members found.',
description: 'Message displayed when there are no team members',
},
staff: {
id: 'instruct.courseTeam.roles.staff',
defaultMessage: 'Staff',
description: 'Role name for staff members',
},
staffDescription: {
id: 'instruct.courseTeam.roles.staffDescription',
defaultMessage: 'Course team members with the Staff role help you manage your course. Staff can enroll and unenroll learners, as well as modify their grades and access all course data. Staff also have access to your course in Studio and Insights. Any users not yet enrolled in the course will be automatically enrolled when added as Staff.',
description: 'Description for staff role',
},
limitedStaff: {
id: 'instruct.courseTeam.roles.limitedStaff',
defaultMessage: 'Limited Staff',
description: 'Role name for limited staff members',
},
limitedStaffDescription: {
id: 'instruct.courseTeam.roles.limitedStaffDescription',
defaultMessage: 'Course team members with the Limited Staff role help you manage your course. Limited Staff can enroll and unenroll learners, as well as modify their grades and access all course data. Limited Staff don\'t have access to your course in Studio. Any users not yet enrolled in the course will be automatically enrolled when added as Limited Staff.',
description: 'Description for limited staff role',
},
admin: {
id: 'instruct.courseTeam.roles.admin',
defaultMessage: 'Admin',
description: 'Role name for admin members',
},
adminDescription: {
id: 'instruct.courseTeam.roles.adminDescription',
defaultMessage: 'Course team members with the Admin role help you manage your course. They can do all of the tasks that Staff can do, and can also add and remove the Staff and Admin roles, discussion moderation roles, and the beta tester role to manage course team membership. Any users not yet enrolled in the course will be automatically enrolled when added as Admin.',
description: 'Description for admin role',
},
betaTesters: {
id: 'instruct.courseTeam.roles.betaTesters',
defaultMessage: 'Beta Testers',
description: 'Role name for beta tester members',
},
betaTestersDescription: {
id: 'instruct.courseTeam.roles.betaTestersDescription',
defaultMessage: 'Beta Testers can see course content before other learners. They can make sure that the content works, but have no additional privileges. Any users not yet enrolled in the course will be automatically enrolled when added as Beta Tester.',
description: 'Description for beta tester role',
},
courseDataResearchers: {
id: 'instruct.courseTeam.roles.courseDataResearchers',
defaultMessage: 'Course Data Researchers',
description: 'Role name for course data researcher members',
},
courseDataResearchersDescription: {
id: 'instruct.courseTeam.roles.courseDataResearchersDescription',
defaultMessage: 'Course Data Researchers can access the data download tab. Any users not yet enrolled in the course will be automatically enrolled when added as Course Data Researcher.',
description: 'Description for course data researcher role',
},
discussionAdmin: {
id: 'instruct.courseTeam.roles.discussionAdmin',
defaultMessage: 'Discussion Admin',
description: 'Role name for discussion admin members',
},
discussionAdminDescription: {
id: 'instruct.courseTeam.roles.discussionAdminDescription',
defaultMessage: 'Discussion Admins can edit or delete any post, clear misuse flags, close and re-open threads, endorse responses, and see posts from all groups. Their posts are marked as \'staff\'. They can also add and remove the discussion moderation roles to manage course team membership. Any users not yet enrolled in the course will be automatically enrolled when added as Discussion Admin.',
description: 'Description for discussion admin role',
},
discussionModerator: {
id: 'instruct.courseTeam.roles.discussionModerator',
defaultMessage: 'Discussion Moderator',
description: 'Role name for discussion moderator members',
},
discussionModeratorDescription: {
id: 'instruct.courseTeam.roles.discussionModeratorDescription',
defaultMessage: 'Discussion Moderators can edit or delete any post, clear misuse flags, close and re-open threads, endorse responses, and see posts from all groups. Their posts are marked as \'staff\'. They cannot manage course team membership by adding or removing discussion moderation roles. Any users not yet enrolled in the course will be automatically enrolled when added as Discussion Moderator.',
description: 'Description for discussion moderator role',
},
groupCommunityTA: {
id: 'instruct.courseTeam.roles.groupCommunityTA',
defaultMessage: 'Group Community TA',
description: 'Role name for group community TA members',
},
groupCommunityTADescription: {
id: 'instruct.courseTeam.roles.groupCommunityTADescription',
defaultMessage: 'Group Community TAs are members of the community who help course teams moderate discussions. Group Community TAs see only posts by learners in their assigned group. They can edit or delete posts, clear flags, close and re-open threads, and endorse responses, but only for posts by learners in their group. Their posts are marked as \'Community TA\'. Any users not yet enrolled in the course will be automatically enrolled when added as Group Community TA.',
description: 'Description for group community TA role',
},
communityTA: {
id: 'instruct.courseTeam.roles.communityTA',
defaultMessage: 'Community TA',
description: 'Role name for community TA members',
},
communityTADescription: {
id: 'instruct.courseTeam.roles.communityTADescription',
defaultMessage: 'Community TAs are members of the community who help course teams moderate discussions. They can see posts by learners in their assigned cohort or enrollment track, and can edit or delete posts, clear flags, close or re-open threads, and endorse responses. Their posts are marked as \'Community TA\'. Any users not yet enrolled in the course will be automatically enrolled when added as Community TA.',
description: 'Description for community TA role',
},
ccxCoach: {
id: 'instruct.courseTeam.roles.ccxCoach',
defaultMessage: 'CCX Coach',
description: 'Role name for CCX coach members',
},
ccxCoachDescription: {
id: 'instruct.courseTeam.roles.ccxCoachDescription',
defaultMessage: 'CCX Coaches are able to create their own Custom Courses based on this course, which they can use to provide personalized instruction to their own students based in this course material.',
description: 'Description for CCX coach role',
}
});

export default messages;
11 changes: 6 additions & 5 deletions src/routes.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import CohortsPage from '@src/cohorts/CohortsPage';
import CourseInfoPage from '@src/courseInfo/CourseInfoPage';
import DateExtensionsPage from '@src/dateExtensions/DateExtensionsPage';
import CourseTeamPage from './courseTeam/CourseTeamPage';
import DataDownloadsPage from '@src/dataDownloads/DataDownloadsPage';
import DateExtensionsPage from '@src/dateExtensions/DateExtensionsPage';
import OpenResponsesPage from '@src/openResponses/OpenResponsesPage';

const routes = [
Expand All @@ -20,10 +21,10 @@ const routes = [
path: 'course_info',
element: <CourseInfoPage />
},
// {
// path: 'membership',
// element: <MembershipPage />
// },
{
path: 'course_team',
element: <CourseTeamPage />
},
{
path: 'cohorts',
element: <CohortsPage />
Expand Down