Skip to content

Commit

Permalink
feat(front): add job application badge (#69)
Browse files Browse the repository at this point in the history
* chore(front): rename file

* chore(front): update dependencies

* feat(front): add application status badge
  • Loading branch information
Kuruyia authored Feb 15, 2024
1 parent 7ddc7b8 commit 0c0ad64
Show file tree
Hide file tree
Showing 13 changed files with 334 additions and 187 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class JobOfferService(
recommendation.id // Assuming Recommendation has an 'id' field representing its ID
}

if (recommendationIds.size === 0) {
if (recommendationIds.isEmpty()) {
val requestJobOffers = RequestResponseFactory.newRequest(requestId)
.setGetUserJobOffersRequest(
Jobs.GetUserJobOffersRequest.newBuilder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class GetMultipleJobOffers(private val jobOfferService: JobOfferService) : Funct
val reactiveResponse = jobOfferService.findMultipleWithJobAndCompanyAndApplicationStatus(jobOfferIds)
.map { jobOffer ->
JobOfferWithJobAndCompanyToProto().convert(jobOffer)
.setStatusValue(jobOffer.jobApplicationStatus)
}
.reduce(GetMultipleJobOffersResponse.newBuilder()) { builder, jobOffer ->
builder.addJobOffers(jobOffer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ interface JobOfferRepository : ReactiveCrudRepository<JobOffer, UUID> {
jo.salary as jobOfferSalary,
jc.title as jobCategoryTitle,
j.title as jobTitle,
COALESCE(ja.status, -1) as jobApplicationStatus
ja.status as jobApplicationStatus
FROM jobOffer jo
JOIN company c ON jo.company = c.id
JOIN job j ON jo.job = j.id
Expand Down
5 changes: 5 additions & 0 deletions front/assets/translations/en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
},
"applied": {
"jobOfferAppliedList": "Applications"
},
"status": {
"pending": "Pending",
"accepted": "Accepted",
"rejected": "Rejected"
}
},
"messaging": {
Expand Down
5 changes: 5 additions & 0 deletions front/assets/translations/fr_FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
},
"applied": {
"jobOfferAppliedList": "Candidatures"
},
"status": {
"pending": "En attente",
"accepted": "Accepté",
"rejected": "Refusé"
}
},
"messaging": {
Expand Down
321 changes: 140 additions & 181 deletions front/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion front/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"expo-web-browser": "~12.8.2",
"i18n-js": "^4.3.2",
"react": "^18.2.0",
"react-native": "0.73.2",
"react-native": "0.73.4",
"react-native-pager-view": "6.2.3",
"react-native-paper": "^5.12.3",
"react-native-paper-dates": "^0.21.8",
Expand Down
15 changes: 14 additions & 1 deletion front/src/components/jobOffers/JobOfferContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Alert, StyleSheet, View } from 'react-native';
import { Button, Text, useTheme } from 'react-native-paper';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';

import JobOfferStatusBadge from '@/components/jobOffers/JobOfferStatusBadge';
import { JobOffer, JobOfferStatus } from '@/models/entities/jobOffer';
import { usePostApplyJobOfferMutation } from '@/store/api/jobOfferApiSlice';
import i18n from '@/utils/i18n';
Expand All @@ -19,9 +20,13 @@ const styles = StyleSheet.create({
gap: 16,
},
horizontalContainer: {
alignItems: 'center',
flexDirection: 'row',
gap: 12,
},
offerTitle: {
flex: 1,
},
sectionContainer: {
gap: 8,
},
Expand Down Expand Up @@ -77,7 +82,15 @@ const JobOfferContent: FC<JobOfferContentProps> = ({ jobOffer }) => {
return (
<View style={styles.container}>
<View style={styles.sectionContainer}>
<Text variant='titleLarge'>{`${jobOffer.title}`}</Text>
<View style={styles.horizontalContainer}>
<Text
variant='titleLarge'
style={styles.offerTitle}
>{`${jobOffer.title}`}</Text>

<JobOfferStatusBadge status={jobOffer.status} />
</View>

<View style={styles.sectionContainer}>
<View style={styles.horizontalContainer}>
<MaterialCommunityIcons
Expand Down
14 changes: 13 additions & 1 deletion front/src/components/jobOffers/JobOfferItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { StyleSheet, View } from 'react-native';
import { Text, TouchableRipple, useTheme } from 'react-native-paper';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';

import JobOfferStatusBadge from '@/components/jobOffers/JobOfferStatusBadge';
import { JobOffer } from '@/models/entities/jobOffer';

/**
Expand All @@ -17,6 +18,9 @@ const styles = StyleSheet.create({
flexDirection: 'row',
gap: 12,
},
offerTitle: {
flex: 1,
},
sectionContainer: {
gap: 8,
},
Expand Down Expand Up @@ -50,7 +54,15 @@ const JobOfferItem: FC<JobOfferItemProps> = ({ onItemPress, jobOffer }) => {
<TouchableRipple onPress={() => onItemPress?.(jobOffer)}>
<View style={styles.container}>
<View style={styles.sectionContainer}>
<Text variant='titleLarge'>{`${jobOffer.title}`}</Text>
<View style={styles.horizontalContainer}>
<Text
variant='titleLarge'
style={styles.offerTitle}
>{`${jobOffer.title}`}</Text>

<JobOfferStatusBadge status={jobOffer.status} />
</View>

<Text>{`${jobOffer.description}`}</Text>
</View>

Expand Down
122 changes: 122 additions & 0 deletions front/src/components/jobOffers/JobOfferStatusBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { FC } from 'react';
import { StyleSheet, View, useColorScheme } from 'react-native';
import { Text } from 'react-native-paper';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';

import { JobOfferStatus } from '@/models/entities/jobOffer';
import i18n from '@/utils/i18n';
import { DarkBadgeColorPalette, LightBadgeColorPalette } from '@/utils/theme';

/**
* The styles for the JobOfferStatusBadge component.
*/
const styles = StyleSheet.create({
badge: {
borderRadius: 6,
paddingHorizontal: 8,
paddingVertical: 6,
},
horizontalContainer: {
alignItems: 'center',
flexDirection: 'row',
gap: 8,
},
});

/**
* Props for the JobOfferStatusBadge component.
*/
type JobOfferStatusBadgeProps = {
/**
* The application status to display.
*/
status: JobOfferStatus;
};

/**
* Small badge for displaying the application status of a job offer.
* @constructor
*/
const JobOfferStatusBadge: FC<JobOfferStatusBadgeProps> = ({
status,
}: {
status: JobOfferStatus;
}) => {
// Get the correct color palette
const colorScheme = useColorScheme();
const colorPalette =
colorScheme === 'dark' ? DarkBadgeColorPalette : LightBadgeColorPalette;

// Render nothing if the offer has not been applied to
if (status === JobOfferStatus.NOT_APPLIED) {
return null;
}

switch (status) {
case JobOfferStatus.APPLIED:
return (
<View
style={[
styles.badge,
styles.horizontalContainer,
{
backgroundColor: colorPalette.orange.backgroundColor,
},
]}
>
<MaterialCommunityIcons
name='clock-outline'
size={20}
style={{ color: colorPalette.orange.textColor }}
/>
<Text style={{ color: colorPalette.orange.textColor }}>
{i18n.t('jobOffer.status.pending')}
</Text>
</View>
);
case JobOfferStatus.ACCEPTED:
return (
<View
style={[
styles.badge,
styles.horizontalContainer,
{
backgroundColor: colorPalette.green.backgroundColor,
},
]}
>
<MaterialCommunityIcons
name='check'
size={20}
style={{ color: colorPalette.green.textColor }}
/>
<Text style={{ color: colorPalette.green.textColor }}>
{i18n.t('jobOffer.status.accepted')}
</Text>
</View>
);
case JobOfferStatus.REJECTED:
return (
<View
style={[
styles.badge,
styles.horizontalContainer,
{
backgroundColor: colorPalette.red.backgroundColor,
},
]}
>
<MaterialCommunityIcons
name='close-circle-outline'
size={20}
style={{ color: colorPalette.red.textColor }}
/>
<Text style={{ color: colorPalette.red.textColor }}>
{i18n.t('jobOffer.status.rejected')}
</Text>
</View>
);
}
};

export default JobOfferStatusBadge;
2 changes: 1 addition & 1 deletion front/src/pages/jobOffer/JobOfferApplicationNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { createNativeStackNavigator } from '@react-navigation/native-stack';
import PaperNavigationBar from '@/components/utils/PaperNavigationBar';
import i18n from '@/utils/i18n';

import JobOfferApplicationPage from './JobOfferApplicationPage';
import JobOfferPage, { JobOfferPageParams } from './JobOfferPage';
import JobOfferApplicationPage from './jobOfferApplicationPage';

/**
* The parameter list for the JobOffersNav navigator.
Expand Down
30 changes: 30 additions & 0 deletions front/src/utils/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,3 +271,33 @@ export const DarkTheme = deepmerge(AdaptedNavigationDarkTheme, {
},
fonts: configureFonts({ config: FontConfig }),
});

export const LightBadgeColorPalette = {
orange: {
backgroundColor: '#FFDCBE',
textColor: '#2D1600',
},
green: {
backgroundColor: '#B1F49D',
textColor: '#002200',
},
red: {
backgroundColor: '#FFDAD4',
textColor: '#410000',
},
};

export const DarkBadgeColorPalette = {
orange: {
backgroundColor: '#6A3C00',
textColor: '#FFDCBE',
},
green: {
backgroundColor: '#16520E',
textColor: '#B1F49D',
},
red: {
backgroundColor: '#7D2B20',
textColor: '#FFDAD4',
},
};

0 comments on commit 0c0ad64

Please sign in to comment.