-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #749 from eduhub-org/develop
Onboarding improved, various other improvements and fixes
- Loading branch information
Showing
35 changed files
with
868 additions
and
1,130 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
name: Update PR Description | ||
|
||
on: | ||
pull_request: | ||
types: | ||
- opened | ||
- synchronize | ||
|
||
jobs: | ||
update_pr: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v2 | ||
with: | ||
fetch-depth: 0 # Important: this fetches all branches | ||
|
||
- name: Fetch additional branches | ||
run: | | ||
git fetch origin staging:staging | ||
git fetch origin develop:develop | ||
- name: Fetch commit messages and update PR description | ||
run: | | ||
# Fetch commit messages | ||
messages=$(git log --pretty=format:"- %s" staging..develop) | ||
# Update PR description | ||
gh pr edit ${{ github.event.pull_request.number }} \ | ||
--add-label "auto-updated" \ | ||
--body "$messages" | ||
env: | ||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
.../default/1696496688342_create_or_replace_function_set_invitation_expiration_date/down.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
-- Could not auto-generate a down migration. | ||
-- Please write an appropriate down migration for the SQL below: | ||
-- CREATE OR REPLACE FUNCTION "public"."set_invitation_expiration_date"() | ||
-- RETURNS TRIGGER AS $$ | ||
-- BEGIN | ||
-- IF (TG_OP = 'INSERT' AND NEW.status = 'INVITED') OR | ||
-- (TG_OP = 'UPDATE' AND NEW.status = 'INVITED') THEN | ||
-- NEW."invitationExpirationDate" = NOW() + interval '2 days'; | ||
-- END IF; | ||
-- RETURN NEW; | ||
-- END; | ||
-- $$ LANGUAGE plpgsql; | ||
|
||
-- CREATE TRIGGER "set_invitation_expiration_date_trigger" | ||
-- BEFORE INSERT OR UPDATE ON "public"."CourseEnrollment" | ||
-- FOR EACH ROW | ||
-- EXECUTE PROCEDURE "public"."set_invitation_expiration_date"(); | ||
-- COMMENT ON TRIGGER "set_invitation_expiration_date_trigger" ON "public"."CourseEnrollment" | ||
-- IS 'trigger to set default value of column "invitationExpirationDate" to two days after creation when status is set or updated to INVITED'; |
17 changes: 17 additions & 0 deletions
17
...ns/default/1696496688342_create_or_replace_function_set_invitation_expiration_date/up.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
CREATE OR REPLACE FUNCTION "public"."set_invitation_expiration_date"() | ||
RETURNS TRIGGER AS $$ | ||
BEGIN | ||
IF (TG_OP = 'INSERT' AND NEW.status = 'INVITED') OR | ||
(TG_OP = 'UPDATE' AND NEW.status = 'INVITED') THEN | ||
NEW."invitationExpirationDate" = NOW() + interval '2 days'; | ||
END IF; | ||
RETURN NEW; | ||
END; | ||
$$ LANGUAGE plpgsql; | ||
|
||
CREATE TRIGGER "set_invitation_expiration_date_trigger" | ||
BEFORE INSERT OR UPDATE ON "public"."CourseEnrollment" | ||
FOR EACH ROW | ||
EXECUTE PROCEDURE "public"."set_invitation_expiration_date"(); | ||
COMMENT ON TRIGGER "set_invitation_expiration_date_trigger" ON "public"."CourseEnrollment" | ||
IS 'trigger to set default value of column "invitationExpirationDate" to two days after creation when status is set or updated to INVITED'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
{ | ||
"singleQuote": true | ||
"singleQuote": true, | ||
"printWidth": 120 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
66 changes: 66 additions & 0 deletions
66
frontend-nx/apps/edu-hub/components/CourseContent/ActionButtons/ApplyButton.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import useTranslation from 'next-translate/useTranslation'; | ||
import { FC } from 'react'; | ||
import Trans from 'next-translate/Trans'; | ||
|
||
import { Course_Course_by_pk } from '../../../queries/__generated__/Course'; | ||
import { Button } from '../../common/Button'; | ||
|
||
interface IProps { | ||
course: Course_Course_by_pk; | ||
onClickApply: () => void; | ||
} | ||
|
||
export const ApplyButton: FC<IProps> = ({ course, onClickApply }) => { | ||
const { t, lang } = useTranslation('course-page'); | ||
const now = new Date(); | ||
now.setHours(0, 0, 0, 0); // reset hours, minutes, seconds, and milliseconds | ||
|
||
console.log(new Date()); | ||
console.log(course.applicationEnd); | ||
|
||
// check if current date is after application deadline | ||
const currentDate = new Date(); | ||
currentDate.setHours(0, 0, 0, 0); | ||
|
||
if (course.applicationEnd <= currentDate) { | ||
return ( | ||
<div className="bg-gray-300 p-4"> | ||
<Trans | ||
i18nKey="course-application:status.applicationPeriodEnded" | ||
components={{ | ||
a: ( | ||
<a | ||
href="https://opencampus.substack.com" | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
className="underline" | ||
/> | ||
), | ||
}} | ||
/> | ||
</div> | ||
); | ||
} else { | ||
return ( | ||
<div className="flex flex-1 flex-col justify-center items-center"> | ||
<Button | ||
filled | ||
inverted | ||
onClick={onClickApply} | ||
disabled={now > course.applicationEnd} | ||
className="bg-edu-course-current" | ||
> | ||
{t('applyNow')} | ||
</Button> | ||
<span className="text-xs mt-4 text-white"> | ||
{t('application_deadline')} | ||
{course.applicationEnd?.toLocaleDateString(lang, { | ||
year: 'numeric', | ||
month: '2-digit', | ||
day: '2-digit', | ||
}) ?? ''} | ||
</span> | ||
</div> | ||
); | ||
} | ||
}; |
170 changes: 170 additions & 0 deletions
170
frontend-nx/apps/edu-hub/components/CourseContent/ActionButtons/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
import useTranslation from 'next-translate/useTranslation'; | ||
import { Dispatch, FC, SetStateAction, useCallback, useState } from 'react'; | ||
|
||
import { CourseEnrollmentStatus_enum } from '../../../__generated__/globalTypes'; | ||
import { useUser } from '../../../hooks/user'; | ||
import { CourseWithEnrollment_Course_by_pk_CourseEnrollments } from '../../../queries/__generated__/CourseWithEnrollment'; | ||
|
||
import { ApplyButton } from './ApplyButton'; | ||
import { ApplicationModal } from './ApplicationModal'; | ||
|
||
import { Button } from '../../common/Button'; | ||
|
||
import { Course_Course_by_pk } from '../../../queries/__generated__/Course'; | ||
import { useIsLoggedIn } from '../../../hooks/authentication'; | ||
import { signIn } from 'next-auth/react'; | ||
|
||
interface CourseLinkInfosProps { | ||
course: Course_Course_by_pk; | ||
} | ||
|
||
const CourseLinkInfos: FC<CourseLinkInfosProps> = ({ course }) => { | ||
const { t } = useTranslation(); | ||
|
||
const onlineLocation = course.CourseLocations.find((location) => location.locationOption === 'ONLINE'); | ||
|
||
return ( | ||
<div className="flex justify-center items-center"> | ||
{onlineLocation && onlineLocation.defaultSessionAddress && ( | ||
<div className="mx-4"> | ||
{/* <a | ||
href={onlineLocation.defaultSessionAddress} | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
className="text-white inline-block max-w-[100px]" | ||
> | ||
{t('course-page:to-online-meeting')} | ||
</a> */} | ||
<Button | ||
as="a" | ||
href={onlineLocation.defaultSessionAddress} | ||
filled | ||
inverted | ||
// className="bg-edu-course-current" | ||
> | ||
{t('course:toOnlineMeeting')} | ||
</Button> | ||
</div> | ||
)}{' '} | ||
<div className="mx-4"> | ||
<Button | ||
as="a" | ||
href={course.chatLink} | ||
filled | ||
inverted | ||
// className="bg-edu-course-current" | ||
> | ||
{t('course:toCourseChat')} | ||
</Button> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
interface ActionButtonsProps { | ||
course: Course_Course_by_pk; | ||
courseEnrollment: CourseWithEnrollment_Course_by_pk_CourseEnrollments; | ||
setOnboardingModalOpen: Dispatch<SetStateAction<boolean>>; | ||
} | ||
|
||
export const ActionButtons: FC<ActionButtonsProps> = ({ course, courseEnrollment, setOnboardingModalOpen }) => { | ||
const [isApplicationModalVisible, setApplicationModalVisible] = useState(false); | ||
const { t } = useTranslation('course-application'); | ||
const isLoggedIn = useIsLoggedIn(); | ||
|
||
const user = useUser(); | ||
|
||
const showModal = useCallback(() => { | ||
if (user) { | ||
setApplicationModalVisible(true); | ||
} | ||
}, [user]); | ||
const hideApplicationModal = useCallback(() => setApplicationModalVisible(false), []); | ||
|
||
let content = null; | ||
|
||
if (!courseEnrollment) { | ||
content = <ApplyButton course={course} onClickApply={showModal} />; | ||
} else { | ||
const status = courseEnrollment.status; | ||
|
||
switch (status) { | ||
case CourseEnrollmentStatus_enum.ABORTED: { | ||
content = <span className="bg-gray-300 p-4">{t('status.aborted')}</span>; | ||
break; | ||
} | ||
case CourseEnrollmentStatus_enum.APPLIED: { | ||
content = <span className="bg-gray-300 p-4">{t('status.applied')}</span>; | ||
break; | ||
} | ||
case CourseEnrollmentStatus_enum.REJECTED: { | ||
content = <span className="bg-gray-300 p-4">{t('status.rejected')}</span>; | ||
break; | ||
} | ||
case CourseEnrollmentStatus_enum.CANCELLED: { | ||
content = <span className="bg-gray-300 p-4">{t('status.cancelled')}</span>; | ||
break; | ||
} | ||
case CourseEnrollmentStatus_enum.INVITED: { | ||
if (courseEnrollment.invitationExpirationDate.setHours(0, 0, 0, 0) >= new Date().setHours(0, 0, 0, 0)) { | ||
content = ( | ||
<div className="flex flex-col sm:flex-row sm:items-center"> | ||
<div className="bg-gray-300 p-4 mb-6 sm:mb-0 sm:w-2/3 sm:mr-5">{t('status.invited')}</div> | ||
<Button | ||
filled | ||
inverted | ||
onClick={() => setOnboardingModalOpen(true)} | ||
className="bg-edu-course-current sm:w-1/3" | ||
> | ||
{t('acceptInvitation')} | ||
</Button> | ||
</div> | ||
); | ||
} else { | ||
content = <span className="bg-gray-300 p-4">{t('status.invitation_expired')}</span>; | ||
} | ||
break; | ||
} | ||
case CourseEnrollmentStatus_enum.CONFIRMED: { | ||
content = <CourseLinkInfos course={course} />; | ||
break; | ||
} | ||
case CourseEnrollmentStatus_enum.COMPLETED: { | ||
content = <CourseLinkInfos course={course} />; | ||
break; | ||
} | ||
default: { | ||
content = null; | ||
} | ||
} | ||
} | ||
|
||
const signInHandler = () => { | ||
console.log('signIN!'); | ||
return signIn('keycloak'); | ||
}; | ||
|
||
const hasExternalRegistration = course.externalRegistrationLink !== null && course.externalRegistrationLink !== ''; | ||
const eventHandler = () => { | ||
window.open(course.externalRegistrationLink, '_blank'); | ||
}; | ||
|
||
return ( | ||
<> | ||
<div className="flex mx-auto mb-10"> | ||
{hasExternalRegistration ? ( | ||
<div className="mx-auto mb-10"> | ||
<ApplyButton course={course} onClickApply={eventHandler} /> | ||
</div> | ||
) : isLoggedIn && !hasExternalRegistration ? ( | ||
content | ||
) : ( | ||
<div className="mx-auto mb-10"> | ||
<ApplyButton course={course} onClickApply={signInHandler} /> | ||
</div> | ||
)} | ||
</div> | ||
<ApplicationModal visible={isApplicationModalVisible} closeModal={hideApplicationModal} course={course} /> | ||
</> | ||
); | ||
}; |
Oops, something went wrong.