Skip to content

Commit

Permalink
Updates to the dashboard functionality (#1756)
Browse files Browse the repository at this point in the history
* Updates to the dashboard functionality

- ~~Adds In Progress badges everywhere that a course is in progress #1692~~
- Display program enrollments even if there's no enrollments #1693
- Actually reload the data if we unenroll from something, rather than displaying stale data
  • Loading branch information
jkachel authored Jul 28, 2023
1 parent 7b8bd79 commit 6f7dbc5
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 66 deletions.
8 changes: 0 additions & 8 deletions frontend/public/scss/dashboard.scss
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,6 @@ $enrolled-passed-fg: #ffffff;
margin-right: .5rem;

}
.badge-in-progress {
color: black;
background-color: transparent;
border-color: black;
border: 1px;
border-radius: 4px;
border-style: solid;
}

.badge-enrolled-verified {
color: $enrolled-verified-fg;
Expand Down
28 changes: 25 additions & 3 deletions frontend/public/src/components/EnrolledItemCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ type EnrolledItemCardProps = {
isLoading: boolean,
toggleProgramDrawer: Function | null,
isProgramCard: boolean,
redirectToCourseHomepage: Function
redirectToCourseHomepage: Function,
onUnenroll: Function | null,
onUpdateDrawerEnrollment: Function | null
}

type EnrolledItemCardState = {
Expand Down Expand Up @@ -124,7 +126,7 @@ export class EnrolledItemCard extends React.Component<
}

async onRunUnenrollment(enrollment: RunEnrollment) {
const { deactivateEnrollment, addUserNotification } = this.props
const { deactivateEnrollment, addUserNotification, onUnenroll } = this.props

this.toggleRunUnenrollmentModalVisibility()

Expand All @@ -135,6 +137,9 @@ export class EnrolledItemCard extends React.Component<
if (isSuccessResponse(resp)) {
messageType = ALERT_TYPE_SUCCESS
userMessage = `You have been successfully unenrolled from ${enrollment.run.title}.`
if (onUnenroll !== undefined) {
onUnenroll()
}
} else {
messageType = ALERT_TYPE_DANGER
userMessage = `Something went wrong with your request to unenroll. Please contact support at ${SETTINGS.support_email}.`
Expand All @@ -155,7 +160,11 @@ export class EnrolledItemCard extends React.Component<
}

async onProgramUnenrollment(program: Program) {
const { deactivateProgramEnrollment, addUserNotification } = this.props
const {
deactivateProgramEnrollment,
addUserNotification,
onUnenroll
} = this.props

this.toggleProgramUnenrollmentModalVisibility()

Expand All @@ -166,6 +175,9 @@ export class EnrolledItemCard extends React.Component<
if (isSuccessResponse(resp)) {
messageType = ALERT_TYPE_SUCCESS
userMessage = `You have been successfully unenrolled from ${program.title}.`
if (onUnenroll !== undefined) {
onUnenroll()
}
} else {
throw new Error("program unenrollment failed")
}
Expand Down Expand Up @@ -566,6 +578,16 @@ export class EnrolledItemCard extends React.Component<
)
}

componentDidUpdate(prevProps: EnrolledItemCardProps) {
const { onUpdateDrawerEnrollment } = this.props

if (this.props.enrollment !== prevProps.enrollment) {
if (onUpdateDrawerEnrollment !== undefined) {
onUpdateDrawerEnrollment(this.props.enrollment)
}
}
}

renderProgramEnrollment() {
const { enrollment } = this.props
const { menuVisibility } = this.state
Expand Down
27 changes: 10 additions & 17 deletions frontend/public/src/components/EnrolledProgramList.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,40 @@
// @flow
import React from "react"

import { routes } from "../lib/urls"
import EnrolledItemCard from "./EnrolledItemCard"

import type { ProgramEnrollment, Program } from "../flow/courseTypes"

type EnrolledProgramListProps = {
enrollments: ProgramEnrollment[],
toggleDrawer: Function
toggleDrawer: Function,
onUnenroll: Function | null,
onUpdateDrawerEnrollment: Function | null
}

export class EnrolledProgramList extends React.Component<EnrolledProgramListProps> {
renderEnrolledProgramCard(enrollment: Program) {
const { toggleDrawer } = this.props
const { toggleDrawer, onUnenroll, onUpdateDrawerEnrollment } = this.props

return (
<EnrolledItemCard
key={`program-item-${enrollment.program.id}`}
enrollment={enrollment}
toggleProgramDrawer={toggleDrawer}
onUnenroll={onUnenroll}
onUpdateDrawerEnrollment={onUpdateDrawerEnrollment}
></EnrolledItemCard>
)
}

render() {
const { enrollments } = this.props

return enrollments && enrollments.length > 0 ? (
enrollments.map<ProgramEnrollment>(enrollment =>
enrollment.enrollments.length > 0
? this.renderEnrolledProgramCard(enrollment)
: null
return enrollments && enrollments.length > 0
? enrollments.map<ProgramEnrollment>(enrollment =>
this.renderEnrolledProgramCard(enrollment)
)
) : (
<div className="card no-enrollments p-3 p-md-5 rounded-0">
<h2>Enroll Now</h2>
<p>
You are not enrolled in any programs yet. Please{" "}
<a href={routes.root}>browse our programs</a>.
</p>
</div>
)
: null
}
}

Expand Down
16 changes: 2 additions & 14 deletions frontend/public/src/components/EnrolledProgramList_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ describe("EnrolledProgramList", () => {
<EnrolledProgramList
enrollments={userEnrollments}
toggleDrawer={toggleProgramDrawer}
onUnenroll={null}
onUpdateDrawerEnrollment={null}
></EnrolledProgramList>
)
})
Expand All @@ -35,18 +37,4 @@ describe("EnrolledProgramList", () => {

assert.isOk(inner)
})

it("shows a message if the user has no enrollments", async () => {
userEnrollments = []
const inner = await renderedCard()

const enrolledItems = inner.find(".no-enrollments")
assert.lengthOf(enrolledItems, 1)
assert.isTrue(
enrolledItems
.at(0)
.text()
.includes("You are not enrolled")
)
})
})
8 changes: 0 additions & 8 deletions frontend/public/src/components/ProgramCourseInfoCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,6 @@ export class ProgramCourseInfoCard extends React.Component<ProgramCourseInfoCard
<div className="row flex-grow-1">
{featuredImage}
<div className="col-12 col-md px-3 py-3 py-md-0 box">
<div className="align-content-start enrollment-mode-container w-100">
{courseRunStatusDetail !== null &&
courseRunStatusDetail.active ? (
<span className="badge badge-in-progress mr-2">
In Progress
</span>
) : null}
</div>
<div className="d-flex justify-content-between align-content-start flex-nowrap w-100 enrollment-mode-container flex-wrap pb-1">
<h2 className="my-0 mr-3">{course.title}</h2>
</div>
Expand Down
4 changes: 3 additions & 1 deletion frontend/public/src/components/ProgramEnrollmentDrawer.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ interface ProgramEnrollmentDrawerProps {
showDrawer: Function,
isHidden: boolean,
redirectToCourseHomepage: Function,
onUnenroll: Function | null,
}

export class ProgramEnrollmentDrawer extends React.Component<ProgramEnrollmentDrawerProps> {
renderCourseInfoCard(course: CourseDetailWithRuns) {
const { enrollment } = this.props
const { enrollment, onUnenroll } = this.props

let found = undefined

Expand Down Expand Up @@ -49,6 +50,7 @@ export class ProgramEnrollmentDrawer extends React.Component<ProgramEnrollmentDr
enrollment={found}
isProgramCard={true}
redirectToCourseHomepage={this.redirectToCourseHomepage}
onUnenroll={onUnenroll}
></EnrolledItemCard>
)
}
Expand Down
1 change: 0 additions & 1 deletion frontend/public/src/containers/ProductDetailEnrollApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ export class ProductDetailEnrollApp extends React.Component<
: this.getCurrentCourseRun()

if (!upgradeEnrollmentDialogVisibility) {
console.log(`creating enrollment for ${run.id}`)
createEnrollment(run)
} else {
window.location = "/dashboard/"
Expand Down
51 changes: 37 additions & 14 deletions frontend/public/src/containers/pages/DashboardPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ type DashboardPageProps = {
) => Promise<any>,
updateAddlFields: (currentUser: User) => Promise<any>,
addUserNotification: Function,
closeDrawer: Function
closeDrawer: Function,
forceRequest: Function | null
}

const DashboardTab = {
Expand All @@ -57,7 +58,7 @@ const DashboardTab = {

type DashboardPageState = {
programDrawerVisibility: boolean,
programDrawerEnrollments: ?(any[]),
programDrawerEnrollments: ProgramEnrollment | null,
currentTab: string,
showAddlProfileFieldsModal: boolean,
destinationUrl: string
Expand All @@ -82,6 +83,20 @@ export class DashboardPage extends React.Component<
})
}

updateDrawerEnrollments(enrollment: any) {
const { programDrawerEnrollments } = this.state

if (
programDrawerEnrollments !== null &&
programDrawerEnrollments.program &&
programDrawerEnrollments.program.id === enrollment.program.id
) {
this.setState({
programDrawerEnrollments: enrollment
})
}
}

toggleTab(tab: string) {
if (tab === DashboardTab.courses || tab === DashboardTab.programs) {
this.setState({ currentTab: tab })
Expand Down Expand Up @@ -140,19 +155,25 @@ export class DashboardPage extends React.Component<
}

renderCurrentTab() {
const { enrollments, programEnrollments } = this.props
const { enrollments, programEnrollments, forceRequest } = this.props

if (this.state.currentTab === DashboardTab.programs) {
return (
<div>
<h1 className="hide-element">Programs</h1>
<EnrolledProgramList
key={"enrolled-programs"}
enrollments={programEnrollments}
toggleDrawer={this.toggleDrawer.bind(this)}
></EnrolledProgramList>
</div>
)
if (programEnrollments.length === 0) {
this.setState({ currentTab: DashboardTab.courses })
} else {
return (
<div>
<h1 className="hide-element">Programs</h1>
<EnrolledProgramList
key={"enrolled-programs"}
enrollments={programEnrollments}
toggleDrawer={this.toggleDrawer.bind(this)}
onUpdateDrawerEnrollment={this.updateDrawerEnrollments.bind(this)}
onUnenroll={forceRequest}
></EnrolledProgramList>
</div>
)
}
}

return (
Expand All @@ -162,6 +183,7 @@ export class DashboardPage extends React.Component<
key={"enrolled-courses"}
enrollments={enrollments}
redirectToCourseHomepage={this.redirectToCourseHomepage.bind(this)}
onUnenroll={forceRequest}
></EnrolledCourseList>
</div>
)
Expand Down Expand Up @@ -206,7 +228,7 @@ export class DashboardPage extends React.Component<
}

render() {
const { isLoading, programEnrollments } = this.props
const { isLoading, programEnrollments, forceRequest } = this.props

const myCourseClasses = `dash-tab${
this.state.currentTab === DashboardTab.courses ? " active" : ""
Expand Down Expand Up @@ -255,6 +277,7 @@ export class DashboardPage extends React.Component<
this.setState({ programDrawerVisibility: false })
}
redirectToCourseHomepage={this.redirectToCourseHomepage}
onUnenroll={forceRequest}
></ProgramEnrollmentDrawer>

{this.renderAddlProfileFieldsModal()}
Expand Down

0 comments on commit 6f7dbc5

Please sign in to comment.