Skip to content

Commit

Permalink
Merge pull request #65 from stevebrownlee/develop
Browse files Browse the repository at this point in the history
Transferring students release
  • Loading branch information
stevebrownlee authored May 16, 2024
2 parents 3fa9ea9 + 2c16c02 commit af52d8d
Show file tree
Hide file tree
Showing 19 changed files with 1,471 additions and 437 deletions.
1,206 changes: 1,024 additions & 182 deletions package-lock.json

Large diffs are not rendered by default.

50 changes: 0 additions & 50 deletions src/buttons.css
Original file line number Diff line number Diff line change
@@ -1,53 +1,3 @@
.isometric-button {
position: relative;
display: inline-block;
padding: 0.5rem 1.5rem;
font-size: 0.8rem;
font-weight: bold;
text-align: center;
text-decoration: none;
border-radius: 0.4rem;
box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
transition: background-color 0.2s, box-shadow 0.2s;
}

.isometric-button:hover {
filter: brightness(95%);
cursor:pointer;
}

/* Color variations */
.isometric-button.small {
font-size: smaller;
padding: 0.25rem 0.4rem;
}

.isometric-button.red {
background-color: firebrick;
color: white;
}

.isometric-button.yellow {
background-color: goldenrod;
color: black;
}

.isometric-button.blue {
background-color: rgb(69, 161, 253);
color: white;
}

.isometric-button.gray {
background-color: gray;
color: white;
}

.isometric-button.pink {
background-color: rgb(201, 131, 144);
color: white;
}


.btn-github {
color: #fff;
background-color: #444;
Expand Down
2 changes: 1 addition & 1 deletion src/card.css
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
-webkit-box-flex: 1;
-ms-flex: 1 1 auto;
flex: 1 1 auto;
padding: 1.25rem;
padding: 0 1.25rem 0.8rem 1.25rem;
}

.card-title {
Expand Down
14 changes: 14 additions & 0 deletions src/components/cohorts/Cohort.css
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,20 @@
background-color: rgb(214, 230, 230);
}

.student--found {
padding: 0.2rem 0 0.2rem 0.5rem;
background-color: rgb(214, 230, 230);
margin: 0.2rem 0;
border-radius: 0.1rem;
border: 1px dashed rgb(180, 208, 208);
font-size: 0.8rem;
}

.student--found:hover {
background-color: rgb(180, 208, 208);
cursor: pointer;
}

.cohort__details {
display: flex;
flex-direction: row;
Expand Down
158 changes: 79 additions & 79 deletions src/components/cohorts/CohortDetails.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import React, { useContext, useEffect, useState } from "react"
import { Badge, Button, Dialog, TextArea, Text, Flex, MagnifyingGlassIcon } from '@radix-ui/themes'
import { TextField } from '@radix-ui/themes'

import { AssessmentContext } from "../assessments/AssessmentProvider.js"
import { CohortContext } from "./CohortProvider.js"
import { Toast, configureToasts } from "toaster-js"
import { CourseContext } from "../course/CourseProvider.js"
import { useHistory } from "react-router-dom"
import { CopyIcon } from "../../svgs/CopyIcon.js"

import { fetchIt } from "../utils/Fetch.js"
import Settings from "../Settings.js"
import { CohortStudentAddDialog } from "./CohortStudentAddDialog.js"
import { CohortInvitationLink } from "./CohortInvitationLink.js"

export const CohortDetails = () => {
const initialState = {
Expand All @@ -25,6 +30,7 @@ export const CohortDetails = () => {
updateCohort
} = useContext(CohortContext)
const { migrateCohortToServerSide, capstoneSeason, setCapstoneSeason } = useContext(CourseContext)

const history = useHistory()

useEffect(() => {
Expand Down Expand Up @@ -85,7 +91,6 @@ export const CohortDetails = () => {
}



return (
<div className="overlay--cohort">
<div className="card" style={{
Expand Down Expand Up @@ -152,30 +157,10 @@ export const CohortDetails = () => {
/>
</div>

<div className="form-group form-group--row">
<label className="label--smallrow" htmlFor="zoom_url">Zoom Session</label>
<input onChange={updateState}
value={info.zoom_url ?? ""}
type="url" controltype="string"
id="zoom_url" className="form-control form-control--row form-control--small"
/>
</div>

<button className="isometric-button blue" onClick={saveURLs}>Save URLs</button>
<Button color="blue" onClick={saveURLs}>Save URLs</Button>
</div>

<div className="cohort__detail cohort__detail--medium">
<h3>Invitation Link</h3>

<div style={{ margin: "1rem 0" }}>
Send this link to incoming students to assign them to your cohort
</div>

<span className="fakeLink readonly">
{`${Settings.apiHost}/auth/github/url?cohort=${activeCohortDetails.id}&v=1`}
<CopyIcon text={`${Settings.apiHost}/auth/github/url?cohort=${activeCohortDetails.id}&v=1`} />
</span>

<h3 style={{ margin: "3rem 0 0 0" }}>Dates</h3>

<div style={{ margin: "1rem 0" }}>
Expand All @@ -198,62 +183,70 @@ export const CohortDetails = () => {
</div>
</div>

<h2>Active</h2>
<div className="capstoneToggle">
<input defaultChecked={activeCohortDetails.active}
onChange={(evt) => {
evt.target.ariaChecked = evt.target.checked

const cohortObject = {
id: activeCohortDetails.id,
active: evt.target.checked
}
return fetchIt(`${Settings.apiHost}/cohorts/${activeCohortDetails.id}/active`,
{
method: "PUT",
body: JSON.stringify(cohortObject)
})
.then(() => {
getCohort(activeCohortDetails.id)
new Toast("Cohort updated", Toast.TYPE_INFO, Toast.TIME_SHORT)
})
}} id="toggle" className="toggle" type="checkbox" role="switch" name="toggle" value="on" />
<label htmlFor="toggle" className="slot">
<span className="slot__label">OFF</span>
<span className="slot__label">ON</span>
</label>
<div className="curtain"></div>
</div>
<CohortInvitationLink activeCohortDetails={activeCohortDetails} />

<Flex as="div" direction="row" align="start">
<div>
<h3>Active</h3>
<div className="capstoneToggle">
<input defaultChecked={activeCohortDetails.active}
onChange={(evt) => {
evt.target.ariaChecked = evt.target.checked

const cohortObject = {
id: activeCohortDetails.id,
active: evt.target.checked
}
return fetchIt(`${Settings.apiHost}/cohorts/${activeCohortDetails.id}/active`,
{
method: "PUT",
body: JSON.stringify(cohortObject)
})
.then(() => {
getCohort(activeCohortDetails.id)
new Toast("Cohort updated", Toast.TYPE_INFO, Toast.TIME_SHORT)
})
}} id="toggle" className="toggle" type="checkbox" role="switch" name="toggle" value="on" />
<label htmlFor="toggle" className="slot">
<span className="slot__label">OFF</span>
<span className="slot__label">ON</span>
</label>
<div className="curtain"></div>
</div>
</div>

<h2>Capstone Season</h2>
<div className="capstoneToggle">
<input checked={capstoneSeason.includes(activeCohortDetails.id)}
onChange={(evt) => {
evt.target.ariaChecked = evt.target.checked

const localStorageSeasons = localStorage.getItem("capstoneSeason")
const cohortsInCapstoneSeason = localStorageSeasons
? new Set([...JSON.parse(localStorageSeasons)])
: new Set()

if (evt.target.checked) {
cohortsInCapstoneSeason.add(activeCohortDetails.id)
}
else {
cohortsInCapstoneSeason.delete(activeCohortDetails.id)
}

const capstoneSeasonCohorts = Array.from(cohortsInCapstoneSeason)
setCapstoneSeason(capstoneSeasonCohorts)
localStorage.setItem("capstoneSeason", JSON.stringify(capstoneSeasonCohorts))

}} id="toggle" className="toggle" type="checkbox" role="switch" name="toggle" />
<label htmlFor="toggle" className="slot">
<span className="slot__label">OFF</span>
<span className="slot__label">ON</span>
</label>
<div className="curtain"></div>
</div>
<div>
<h3>Capstone Season</h3>
<div className="capstoneToggle">
<input checked={capstoneSeason.includes(activeCohortDetails.id)}
onChange={(evt) => {
evt.target.ariaChecked = evt.target.checked

const localStorageSeasons = localStorage.getItem("capstoneSeason")
const cohortsInCapstoneSeason = localStorageSeasons
? new Set([...JSON.parse(localStorageSeasons)])
: new Set()

if (evt.target.checked) {
cohortsInCapstoneSeason.add(activeCohortDetails.id)
}
else {
cohortsInCapstoneSeason.delete(activeCohortDetails.id)
}

const capstoneSeasonCohorts = Array.from(cohortsInCapstoneSeason)
setCapstoneSeason(capstoneSeasonCohorts)
localStorage.setItem("capstoneSeason", JSON.stringify(capstoneSeasonCohorts))

}} id="toggle" className="toggle" type="checkbox" role="switch" name="toggle" />
<label htmlFor="toggle" className="slot">
<span className="slot__label">OFF</span>
<span className="slot__label">ON</span>
</label>
<div className="curtain"></div>
</div>
</div>
</Flex>
</div>

<div className="cohort__detail">
Expand All @@ -277,11 +270,18 @@ export const CohortDetails = () => {
activeCohortDetails.coaches?.map(coach => <div key={`coach--${coach.name}`} className="instructor--badge cohort__coach">{coach.name}</div>)
}
</div>

<h3>Students</h3>
<div className="cohort__coaches">
{activeCohortDetails.students} active students
</div>

<CohortStudentAddDialog />
</div>
</div>
</div>
</div>
</div>
</div>
</div >
)
}
20 changes: 20 additions & 0 deletions src/components/cohorts/CohortInvitationLink.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from "react"
import { CopyIcon } from "../../svgs/CopyIcon.js"
import Settings from "../Settings.js"

export const CohortInvitationLink = ({ activeCohortDetails }) => {
return (
<>
<h3>Invitation Link</h3>

<div style={{ margin: "1rem 0" }}>
Send this link to incoming students to assign them to your cohort
</div>

<span className="fakeLink readonly">
{`${Settings.apiHost}/auth/github/url?cohort=${activeCohortDetails.id}&v=1`}
<CopyIcon text={`${Settings.apiHost}/auth/github/url?cohort=${activeCohortDetails.id}&v=1`} />
</span>
</>
)
}
4 changes: 1 addition & 3 deletions src/components/cohorts/CohortList.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ export const CohortList = () => {
const history = useHistory()

useEffect(() => {
if (cohorts.length === 0) {
getRecentCohorts()
}
getRecentCohorts()
}, [])

const getRecentCohorts = () => getCohorts({ limit: 6 })
Expand Down
4 changes: 2 additions & 2 deletions src/components/cohorts/CohortProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ export const CohortProvider = (props) => {
const user = getCurrentUser()

const getCohorts = useCallback((options={}) => {
const limit = options.limit ? `?limit=${options.limit}` : null
const active = options.active ? `?active=${options.active}` : null
const limit = options.limit ? `?limit=${options.limit}` : ""
const active = options.active ? `?active=${options.active}` : ""

return fetchIt(`${Settings.apiHost}/cohorts${limit || active}`)
.then(data => setCohorts(data))
Expand Down
Loading

0 comments on commit af52d8d

Please sign in to comment.