Skip to content

Commit

Permalink
On-time exams (#562)
Browse files Browse the repository at this point in the history
* feat(explanation-average): created modal for averaging explanation, Ref #145

* feat(course-screen): changed the averages and explanations, Ref #145

* feat(averages-info): add the test text,add description for the masterAdmissionAverageGrade, Ref #145

* fix(course-screen): fix to average error for master

* fix(course-screen-modal): fix the layout of the bullet point,Ref #145

* fix(course-screen-modal): delete some not used export, and change the weight prop,Ref #145

* feat(services): webmail added (#481)

* feat(webmail): add the webmail button and the hooks for the authentication,Ref #473

* fix(webmail): webmail improvements

---------

Co-authored-by: FabrizioCostaMedich <[email protected]>
Co-authored-by: Emanuele Coricciati <[email protected]>

* fix(agenda): fix tablet agenda view (#480)

* fix(agenda): fix agenda layout on tablet

* fix(agenda): fix overlapping events

---------

Co-authored-by: Emanuele Coricciati <[email protected]>

* feat(courses): add external links in course info tab (#485)

* feat(link-course): create the section external links course in CourseInfoScreen.tsx

* feat(course-screen-info): add text, and change some controls when the status is loading, Ref #301

* feat(course-info): changed the layout of the links and the text , Ref #301

* fix(courses): fix translations and link indexes

* chore: update api spec

---------

Co-authored-by: FabrizioCostaMedich <[email protected]>
Co-authored-by: Emanuele Coricciati <[email protected]>
Co-authored-by: Cristina Ferrian <[email protected]>

* build: bump version v.1.6.5

* ci: upgrade pipeline, unify rubies, upgrade to react-native 0.72 (#487)

* ci: bump ios target sdk, enable macos github runners

* ci: try to break everything

* ci: try to break everything pt 2

* ci: try to unify ruby & co

* ci: move caching before npm install, bump action versions

* ci: upgrade ruby version

* ci: more ruby fixes

* ci: retry ruby fix

* ci: enforce pod install

* ci: react-native-permissions upgrade Podfile

---------

Co-authored-by: Mobile AppleDev <[email protected]>

* fix(tickets): fix ticket reply sent multiple times, Ref #479 (#491)

* fix(courses): fix link indexes (#490)

* fix(ui): fix bottom modal on rotation (#489)

* fix(webmail): fix unread count as string (#488)

* fix(places): max zoom incompatible with tiles max level (#486)

* fix: upgrade mapbox version to address ios xcprivacy issue (#492)

Co-authored-by: Mobile AppleDev <[email protected]>

* refactor(ui): changed accept/reject grade confirm messages

* fix(exams): new style exam screens (#500)

* fix(exams): fix style on exams screens

* fix(exams): do not show buttons when exam is not passed

* fix(exams): fix checks on canBeRejected and canBeAccepted loot boxes

* fix(exams): fix button position on ios and android

* fix(exams): fix position of button by platform

---------

Co-authored-by: Emanuele Coricciati <[email protected]>

* fix(exams): provide a feedback when an exam cannot be booked, Ref #495 (#499)

* fix(exams): provide a feedback when an exam cannot be booked, Ref #495

* fix(exams): fix icon not bookable and places not available, Refs #495

* fix(teaching): update file name failing when already scheduled (#496)

* build: bump version

* fix(exams): sort exams by date in the TeachingScreen.tsx, Ref #504 (#505)

* fix(login): enable login even when fcm is not enabled, but display warning (#515)

fixes: #513

* fix(exams): fix exam booked count and available count (#511)

* fix(courses): make search case-insensitive (#535)

* fix(courses): prioritize sorting by date, if they are the same sort by name in increasing order (#536)

* fix(tickets): fix issues in ticket format, update regex for links (#533)

Co-authored-by: Fabrizio Costa Medich <[email protected]>

* chore: upgrade to react native 0.76 (#557)

* ci: upgrade tests

* fix: fix android build for updated react native version

* fix: migration to mapbox 0.75.3

* build: upgrade to rn 0.76

* fix: fix types

* fix: update lock files

* fix: fix places types

* fix: fix lock files and format

* fix(places): added control to check if floorId exist and set his state

* fix(places): pass current floor when press a building

* fix(places): fix invalid styles on layers

* fix(places): add map loader

* fix(places): fix camera animation and stateful menu, remove map modal

---------

Co-authored-by: QcFe <[email protected]>
Co-authored-by: miky41195 <[email protected]>
Co-authored-by: FabrizioCostaMedich <[email protected]>
Co-authored-by: Cristina Ferrian <[email protected]>

* fix(profile): handle null smartcard and relocate fcm token

* fix(transcript): added explanations for grades and show only one average

* feat(explanation-average): created modal for averaging explanation, Ref #145

* feat(course-screen): changed the averages and explanations, Ref #145

* feat(averages-info): add the test text,add description for the masterAdmissionAverageGrade, Ref #145

* fix(course-screen): fix to average error for master

* fix(course-screen-modal): fix the layout of the bullet point,Ref #145

* fix(course-screen-modal): delete some not used export, and change the weight prop,Ref #145

* fix(profile): handle null smartcard and relocate fcm token

* fix(transcript): added explanations for grades and show only one average

* feat(transcript): added on-time exam scores to transcript section

* fix(transcript): changed text formula average

* fix(transcript): changed some text

* fix(transcript): change laude text

* fix(transcript): change some text

* fix(transcript): change some text

* fix(exams): fix typo

* fix(exams): fix typo lowercase

---------

Co-authored-by: Emanuele Coricciati <[email protected]>
Co-authored-by: Emanuele Coricciati <[email protected]>
Co-authored-by: Cristina Ferrian <[email protected]>
Co-authored-by: Cristina Ferrian <[email protected]>
Co-authored-by: Federico Cucinella <[email protected]>
Co-authored-by: Mobile AppleDev <[email protected]>
Co-authored-by: Umberto Pepato <[email protected]>
Co-authored-by: Emanuele Coricciati <[email protected]>
Co-authored-by: miky41195 <[email protected]>
  • Loading branch information
10 people authored Jan 28, 2025
1 parent ce66590 commit 04ddabd
Show file tree
Hide file tree
Showing 14 changed files with 854 additions and 294 deletions.
34 changes: 29 additions & 5 deletions assets/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,15 @@
"rejectGradeFeedback": "Evaluation rejected, it will be recorded in the next few hours",
"title": "Evaluation"
},
"recordedGradeScreen": {
"additionalPoint": "Additional Scores",
"recordedGradeTitle": "Recorded grade",
"staff": "Staff",
"teacher": "Holder",
"textModal": "Having taken the exam by the first useful session, you are awarded an additional score of 0.5 out of a maximum of 4.\nYou can consult your total on-time points on career",
"titleOnTimePoint": "On-time Exam points",
"ctaButtonModal": "Access your career"
},
"sectionHeader": {
"cta": "See all",
"ctaMoreSuffix": "({{- count}} more)"
Expand Down Expand Up @@ -740,13 +749,28 @@
"attendedCreditsLabel": "Attended credits",
"averages": "Averages",
"averagesAndGrades": "Averages and grades",
"estimatedFinalGrade": "Final grade",
"estimatedFinalGradePurged": "Estimated final grade",
"finalAverageLabel": "Final average",
"masterAdmissionAverage": "Master admission average",
"averageLabel": "Average grade for admission to the Final Examination",
"finalAverageLabelDescription":{
"description": "It is the average grade, weighted according to the credits relating to each exam with a grade*, adjusted for the {{-excludedCreditsNumber}} worst credits",
"formula": "sum (grade * credits) / sum of credits,\nexcluding the {{-excludedCreditsNumber}} worst credits"
},
"laude": "*Honours does not count toward the calculation",
"masterAdmissionAverage": "Master admission average grade",
"masterAdmissionAverageLabelDescription":{
"description":"It is the average grade, weighted according to the credits relating to each exam with grade*, adjusted for the worst n credits\n(To find out more about n, refer to the Student Guide)",
"formula":"sum (grade * credits) / sum of credits\n(excluding the n worst credits)"
},
"NB": "NB",
"NBDescription": "These definitions are indicative. To find out more, refer to the Student Guide.\nOnly graded exams are considered in all average grade above.",
"onTimeScores": "On-time Exams points",
"pointTitle": "Scores",
"pointModal": "The total of the Exam on-time points earned. This value can never exceed the maximum allowed by the degree program.\nTo find out more, refer to the Student Guide.",
"thisYear": "This academic year",
"title": "Career",
"weightedAverageLabel": "Weighted average",
"weightedAverageLabelDescription":{
"description":"This is the average, weighted according to the credits relating to each exam with a grade*",
"formula": "sum (grade * credits) / sum of credits"
},
"yourCareer": "Your career"
},
"videoControls": {
Expand Down
34 changes: 29 additions & 5 deletions assets/translations/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,15 @@
"rejectGradeFeedback": "Valutazione rifiutata, verrà registrata nelle prossime ore",
"title": "Valutazione"
},
"recordedGradeScreen": {
"additionalPoint": "Punteggi aggiuntivi",
"recordedGradeTitle": "Valutazione Registrata",
"staff": "Docente",
"teacher": "Titolare",
"textModal": "Avendo sostenuto l’esame entro la prima sessione utile, ti viene riconosciuto un punteggio aggiuntivo di 0.5 su un massimo di 4.\nPuoi consultate il totale dei tuoi punteggi on-time su carriera",
"titleOnTimePoint": "Punti Esame on-time",
"ctaButtonModal": "Accedi alla tua cariera"
},
"sectionHeader": {
"cta": "Vedi tutti",
"ctaMoreSuffix": "(altri {{- count}})"
Expand Down Expand Up @@ -740,13 +749,28 @@
"attendedCreditsLabel": "Crediti frequentati",
"averages": "Medie",
"averagesAndGrades": "Medie e voti",
"estimatedFinalGrade": "Voto di laurea",
"estimatedFinalGradePurged": "Voto di laurea depurato",
"finalAverageLabel": "Media depurata",
"masterAdmissionAverage": "Media di ammissione al secondo livello",
"averageLabel": "Media di ammissione all’esame di laurea",
"finalAverageLabelDescription":{
"description": "E’ la media, pesata in funzione dei crediti relativi ad ogni esame con voto*, depurata dei {{-excludedCreditsNumber}} peggiori crediti",
"formula": "sum (voto * crediti) / sum crediti,\nescludendo i peggiori {{-excludedCreditsNumber}} crediti"
},
"laude": "*Le lodi non concorrono al calcolo",
"masterAdmissionAverage": "Media di ammissione al II liv",
"masterAdmissionAverageLabelDescription":{
"description":"È la media, pesata in funzione dei crediti relativi ad ogni esame con voto*, depurata degli n peggiori crediti\n(Per conoscere n, consulta la Guida Studenti)",
"formula":"sum (voto * crediti) / sum crediti\n(escludendo gli n peggiori crediti)"
},
"NB": "NB",
"NBDescription": "Queste definizioni sono indicative. Per conoscere i dettagli, consulta la Guida Studenti del tuo corso.\nIn tutte le medie sopra riportate sono considerati esclusivamente gli esami con voto.",
"onTimeScores": "Punti Esami on-time",
"pointTitle": "Punteggi",
"pointModal": "Il totale dei punti on-time acquisiti. Il valore non può mai superare il massimo previsto dal corso di laurea.\nPer saperne di più, consulta la Guida Studenti.",
"thisYear": "Questo anno accademico",
"title": "Carriera",
"weightedAverageLabel": "Media ponderata",
"weightedAverageLabelDescription":{
"description":"E’ la media, pesata in funzione dei crediti relativi ad ogni esame con voto*",
"formula": "sum (voto * crediti) / sum crediti"
},
"yourCareer": "La tua carriera"
},
"videoControls": {
Expand Down
4 changes: 2 additions & 2 deletions lib/ui/components/Metric.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { CardProps } from './Card';
import { Text, Props as TextProps } from './Text';

type Props = ViewProps & {
title: string;
title?: string;
value: string | number | JSX.Element;
color?: string;
valueStyle?: TextProps['style'];
Expand All @@ -19,7 +19,7 @@ export const Metric = ({ title, value, color, ...rest }: CardProps & Props) => {

return (
<View {...rest}>
<Text>{title}</Text>
{title && <Text>{title}</Text>}
{['string', 'number'].includes(typeof value) ? (
<Text
style={[
Expand Down
41 changes: 21 additions & 20 deletions lib/ui/components/ModalContent.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { PropsWithChildren } from 'react';
import { View } from 'react-native';
import { StyleSheet, View } from 'react-native';

import { faTimes } from '@fortawesome/free-solid-svg-icons';
import { HeaderAccessory } from '@lib/ui/components/HeaderAccessory';
Expand All @@ -19,7 +19,6 @@ export const ModalContent = ({
title,
}: PropsWithChildren<Props>) => {
const styles = useStylesheet(createStyles);

return (
<View style={styles.container}>
<HeaderAccessory
Expand All @@ -42,21 +41,23 @@ const createStyles = ({
shapes,
fontSizes,
fontWeights,
}: Theme) => ({
container: {
backgroundColor: colors.surface,
borderTopRightRadius: shapes.md,
borderTopLeftRadius: shapes.md,
},
header: {
borderTopRightRadius: shapes.md,
borderTopLeftRadius: shapes.md,
paddingVertical: spacing[1],
},
headerLeft: { padding: spacing[3] },
modalTitle: {
fontSize: fontSizes.md,
fontWeight: fontWeights.semibold,
color: colors.prose,
},
});
}: Theme) =>
StyleSheet.create({
container: {
backgroundColor: colors.surface,
borderTopRightRadius: shapes.md,
borderTopLeftRadius: shapes.md,
maxHeight: '100%',
},
header: {
borderTopRightRadius: shapes.md,
borderTopLeftRadius: shapes.md,
paddingVertical: spacing[1],
},
headerLeft: { padding: spacing[3] },
modalTitle: {
fontSize: fontSizes.md,
fontWeight: fontWeights.semibold,
color: colors.prose,
},
});
73 changes: 47 additions & 26 deletions lib/ui/components/SectionHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ import {
TextProps,
TextStyle,
TouchableOpacity,
TouchableOpacityProps,
View,
} from 'react-native';

import { Props as FAProps } from '@fortawesome/react-native-fontawesome';
import { IconButton } from '@lib/ui/components/IconButton';
import { Separator } from '@lib/ui/components/Separator';
import { Link, useNavigation } from '@react-navigation/native';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
Expand All @@ -23,12 +26,16 @@ interface Props {
subtitle?: string;
subtitleStyle?: StyleProp<TextStyle>;
ellipsizeTitle?: boolean;
linkTo?: To<any>;
linkToMoreCount?: number;
trailingItem?: JSX.Element;
separator?: boolean;
accessible?: boolean;
accessibilityLabel?: string | undefined;
linkTo?: To<any>;
trailingItem?: JSX.Element;
trailingIcon?: Pick<FAProps, 'size' | 'icon' | 'color'> &
TouchableOpacityProps & {
iconStyle?: FAProps['style'];
};
}

/**
Expand All @@ -46,6 +53,7 @@ export const SectionHeader = ({
linkToMoreCount,
separator = true,
trailingItem,
trailingIcon,
}: Props) => {
const styles = useStylesheet(createStyles);
const { t } = useTranslation();
Expand All @@ -59,18 +67,25 @@ export const SectionHeader = ({

const Header = () => {
return (
<View style={styles.innerContainer}>
<View style={{ ...styles.innerContainer }}>
<View style={styles.titleContainer}>
{separator && <Separator />}
<Text
accessible={false}
variant="heading"
style={[styles.title, titleStyle]}
accessibilityRole="header"
{...ellipsis}
>
{title}
</Text>

<View style={{ ...styles.innerTitleContainer }}>
<Text
accessible={false}
variant="heading"
style={[styles.title, titleStyle, styles.titleContainer]}
accessibilityRole="header"
{...ellipsis}
>
{title}
</Text>
{trailingIcon && (
<IconButton {...{ size: 16, ...trailingIcon, noPadding: true }} />
)}
</View>

{subtitle && (
<Text
accessible={false}
Expand All @@ -83,20 +98,20 @@ export const SectionHeader = ({
</Text>
)}
</View>
{trailingItem
? trailingItem
: linkTo && (
<Link to={linkTo} accessible={true} accessibilityRole="button">
<Text variant="link">
{t('sectionHeader.cta')}
{(linkToMoreCount ?? 0) > 0 &&
' ' +
t('sectionHeader.ctaMoreSuffix', {
count: linkToMoreCount,
})}
</Text>
</Link>
)}
{trailingItem && trailingItem}

{linkTo && (
<Link to={linkTo} accessible={true} accessibilityRole="button">
<Text variant="link">
{t('sectionHeader.cta')}
{(linkToMoreCount ?? 0) > 0 &&
' ' +
t('sectionHeader.ctaMoreSuffix', {
count: linkToMoreCount,
})}
</Text>
</Link>
)}
</View>
);
};
Expand Down Expand Up @@ -152,4 +167,10 @@ const createStyles = ({ spacing, colors }: Theme) =>
titleContainer: {
flex: 1,
},
innerTitleContainer: {
alignItems: 'center',
flexDirection: 'row',
padding: 0,
margin: 0,
},
});
31 changes: 22 additions & 9 deletions src/core/components/BottomModal.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { PropsWithChildren } from 'react';
import { View, useWindowDimensions } from 'react-native';
import { PropsWithChildren, useRef } from 'react';
import { ScrollView, View } from 'react-native';
import Modal from 'react-native-modal';

import { SCREEN_HEIGHT, SCREEN_WIDTH } from '@gorhom/bottom-sheet';

export type BottomModalProps = PropsWithChildren<{
visible: boolean;
onClose?: () => void;
Expand All @@ -18,7 +20,17 @@ export const BottomModal = ({
dismissable && onClose?.();
};

const { width, height } = useWindowDimensions();
const scrollViewRef = useRef<ScrollView>(null);

const handleScrollTo = (position: {
x?: number;
y?: number;
animated?: boolean;
}) => {
if (scrollViewRef.current) {
scrollViewRef.current.scrollTo(position);
}
};

return (
<Modal
Expand All @@ -33,14 +45,15 @@ export const BottomModal = ({
animationIn="slideInUp"
animationOut="slideOutUp"
backdropColor="black"
deviceHeight={height}
deviceWidth={width}
swipeDirection="down"
backdropTransitionInTiming={400}
backdropTransitionOutTiming={400}
useNativeDriver
deviceHeight={SCREEN_HEIGHT}
deviceWidth={SCREEN_WIDTH}
swipeDirection={['down']}
supportedOrientations={['landscape', 'portrait']}
onBackdropPress={handleCloseModal}
scrollTo={handleScrollTo}
useNativeDriver={false}
useNativeDriverForBackdrop
onSwipeComplete={handleCloseModal}
>
<View>{children}</View>
</Modal>
Expand Down
12 changes: 12 additions & 0 deletions src/features/teaching/components/TeachingNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useTranslation } from 'react-i18next';
import { Platform } from 'react-native';

import { useTheme } from '@lib/ui/hooks/useTheme';
import { ExamGrade } from '@polito/api-client';
import { NavigatorScreenParams } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

Expand All @@ -23,6 +24,7 @@ import { PlacesStackParamList } from '../../places/components/PlacesNavigator';
import { CpdSurveysScreen } from '../../surveys/screens/CpdSurveysScreen';
import { TranscriptTopTabsNavigator } from '../../transcript/navigation/TranscriptTopTabsNavigator';
import { ProvisionalGradeScreen } from '../../transcript/screens/ProvisionalGradeScreen';
import { RecordedGradeScreen } from '../../transcript/screens/RecordedGradeScreen';
import { ExamQuestionScreen } from '../screens/ExamQuestionScreen';
import { ExamRequestScreen } from '../screens/ExamRequestScreen';
import { ExamRescheduleScreen } from '../screens/ExamRescheduleScreen';
Expand All @@ -42,6 +44,7 @@ export type TeachingStackParamList = CourseSharedScreensParamList &
MessagesModal: undefined;
Transcript: undefined;
ProvisionalGrade: { id: number };
RecordedGrade: { grade: ExamGrade };
OnboardingModal: undefined;
PlacesTeachingStack: NavigatorScreenParams<PlacesStackParamList>;
CpdSurveys: { categoryId: string; typeId: string; typeName: string };
Expand Down Expand Up @@ -147,6 +150,15 @@ export const TeachingNavigator = () => {
headerBackTitleVisible: false,
}}
/>
<Stack.Screen
name="RecordedGrade"
component={RecordedGradeScreen}
options={{
headerTitle: t('recordedGradeScreen.recordedGradeTitle'),
headerLargeTitle: false,
headerBackTitleVisible: false,
}}
/>
<Stack.Screen
name="OnboardingModal"
component={OnboardingModal}
Expand Down
Loading

0 comments on commit 04ddabd

Please sign in to comment.