Skip to content

Commit

Permalink
feat: navbar & club info tag component (#923)
Browse files Browse the repository at this point in the history
Co-authored-by: Alder Whiteford <[email protected]>
Co-authored-by: Alder Whiteford <[email protected]>
  • Loading branch information
3 people authored May 29, 2024
1 parent c6daec3 commit fc151c4
Show file tree
Hide file tree
Showing 14 changed files with 1,078 additions and 5,738 deletions.
3 changes: 2 additions & 1 deletion frontend/mobile/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ module.exports = {
plugins: ['prettier', 'jest'],
rules: {
'prettier/prettier': 'error',
'react/react-in-jsx-scope': 'off'
'react/react-in-jsx-scope': 'off',
'react-native/no-inline-styles': 'off',
},
env: {
'jest/globals': true
Expand Down
5 changes: 4 additions & 1 deletion frontend/mobile/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@
"projectId": "9cfc60bc-2788-4837-9895-3fe0afdc13c5"
}
},
"owner": "generatesac"
"owner": "generatesac",
"packagerOpts": {
"config": "metro.config.js"
}
}
}
72 changes: 64 additions & 8 deletions frontend/mobile/app/(app)/(tabs)/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,84 @@ import React from 'react';

import { Tabs } from 'expo-router';

import { IconDefinition } from '@fortawesome/fontawesome-svg-core';
import { faCalendarDays } from '@fortawesome/free-solid-svg-icons/faCalendarDays';
import { faHouse } from '@fortawesome/free-solid-svg-icons/faHouse';
import { faUser } from '@fortawesome/free-solid-svg-icons/faUser';
import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome';

import { Text } from '@/app/(design-system)';
import { Box, Colors } from '@/app/(design-system)';

interface TabBarLabelProps {
focused: boolean;
title: string;
}

const TabBarLabel: React.FC<TabBarLabelProps> = ({ focused, title }) => (
<Text variant="caption-1" color={focused ? 'black' : 'gray'}>
{title}
</Text>
);

interface TabBarIconProps {
focused: boolean;
icon: IconDefinition;
}

const TabBarIcon: React.FC<TabBarIconProps> = ({ focused, icon }) => (
<Box paddingTop="m">
<FontAwesomeIcon
size={20}
color={focused ? 'black' : `${Colors.gray}`}
icon={icon}
/>
</Box>
);

const Layout = () => {
return (
<Tabs screenOptions={{ tabBarShowLabel: false }}>
<Tabs
screenOptions={{
tabBarShowLabel: true,
tabBarStyle: {
borderTopWidth: 1,
borderTopColor: '#00000066',
height: 85
}
}}
>
<Tabs.Screen
name="index"
options={{
title: 'home',
headerShown: false
title: 'Home',
headerShown: false,
tabBarLabel: ({ focused }) =>
TabBarLabel({ focused, title: 'Home' }),
tabBarIcon: ({ focused }) =>
TabBarIcon({ focused, icon: faHouse })
}}
/>
<Tabs.Screen
name="discover"
name="calendar"
options={{
title: 'search',
headerShown: false
title: 'Calendar',
headerShown: false,
tabBarLabel: ({ focused }) =>
TabBarLabel({ focused, title: 'Calendar' }),
tabBarIcon: ({ focused }) =>
TabBarIcon({ focused, icon: faCalendarDays })
}}
/>
<Tabs.Screen
name="profile"
options={{
title: 'profile',
headerShown: false
title: 'Profile',
headerShown: false,
tabBarLabel: ({ focused }) =>
TabBarLabel({ focused, title: 'Profile' }),
tabBarIcon: ({ focused }) =>
TabBarIcon({ focused, icon: faUser })
}}
/>
</Tabs>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Box, Tag } from '@/app/(design-system)';

const DiscoverPage = () => {
const CalendarPage = () => {
return (
<Box flex={1} alignItems="center" justifyContent="center" padding="m">
<Tag>Tag</Tag>
<Tag variant="darkRed">Calendar</Tag>
</Box>
);
};

export default DiscoverPage;
export default CalendarPage;
12 changes: 11 additions & 1 deletion frontend/mobile/app/(app)/(tabs)/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { StyleSheet, Text, View } from 'react-native';
import { StyleSheet, View } from 'react-native';

import { Text } from '@/app/(design-system)';
import { RecruitmentInfo } from '@/app/(design-system)/components/ClubRecruitment/RecruitmentInfo/ClubRecruitmentInfo';

const HomePage = () => {
return (
<View style={styles.container}>
<Text style={styles.title}>Hello</Text>
<RecruitmentInfo
recruitmentText="Fill out our application"
recruitingType="unrestricted"
isRecruiting={true}
recruitmentCycle="always"
color="aqua"
/>
</View>
);
};
Expand Down
5 changes: 0 additions & 5 deletions frontend/mobile/app/(auth)/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
import React from 'react';
import { Text, View } from 'react-native';

import { Button } from '../(design-system)/components/Button/Button';

const Welcome = () => {
return (
<View>
<Text>Welcome</Text>
<Button variant="standardButton" color="blue">
Hello
</Button>
</View>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React from 'react';

import { faCalendar } from '@fortawesome/free-regular-svg-icons/faCalendar';
import { faComments } from '@fortawesome/free-solid-svg-icons/faComments';
import { faPenToSquare } from '@fortawesome/free-solid-svg-icons/faPenToSquare';
import { RecruitmentCycle, RecruitmentType } from '@generatesac/lib';

import { Box, SACColors, createStyles } from '@/app/(design-system)';

import { RecruitmentItem } from '../RecruitmentItem/ClubRecruitmentItem';

interface RecruitmentInfoProps {
color: SACColors;
recruitmentCycle: RecruitmentCycle;
recruitingType: RecruitmentType;
isRecruiting?: boolean;
recruitmentText: string;
}

export const RecruitmentInfo = ({
recruitmentText,
color,
recruitmentCycle,
recruitingType,
isRecruiting = false
}: RecruitmentInfoProps) => {
return (
<Box {...styles.recruitmentInfo}>
<RecruitmentItem
icon={faCalendar}
title="Recruitment Cycle"
text={recruitmentCycle}
color={color}
/>
<RecruitmentItem
icon={faPenToSquare}
title={
isRecruiting
? 'Currently Recruiting'
: 'Currently Not Recruiting'
}
text={recruitmentText}
color={color}
/>
<RecruitmentItem
icon={faComments}
title="Application Type"
text={recruitingType}
color={color}
/>
</Box>
);
};

const styles = createStyles({
recruitmentInfo: {
padding: 'l',
flexDirection: 'row',
gap: 'm',
alignItems: 'stretch',
justifyContent: 'space-evenly'
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { IconDefinition } from '@fortawesome/fontawesome-svg-core';

import { Box, SACColors, Text, createStyles } from '@/app/(design-system)';
import { firstLetterUppercase } from '@/utils/string';

import { Icon } from '../../Icon/Icon';

interface RecruitmentItemProps {
icon: IconDefinition;
title: string;
text: string;
color: SACColors;
}

export const RecruitmentItem = ({
icon,
title,
text,
color
}: RecruitmentItemProps) => {
return (
<Box {...styles.recruitmentItem}>
<Box {...styles.recruitmentItemContent}>
<Icon size={'medium'} color={color} icon={icon} />
<Text variant="body-1" {...styles.recruitmentItemTitle}>
{firstLetterUppercase(title)}
</Text>
<Text variant="caption-1" style={{ textAlign: 'center' }}>
{firstLetterUppercase(text)}
</Text>
</Box>
</Box>
);
};

const styles = createStyles({
recruitmentItem: {
alignItems: 'center',
borderWidth: 1,
borderRadius: 'base',
borderColor: 'gray',
width: '33%'
},
recruitmentItemContent: {
paddingTop: 'm',
paddingBottom: 'm',
gap: 'xs',
flexDirection: 'column',
alignItems: 'center'
},
recruitmentItemTitle: {
textAlign: 'center',
fontWeight: '600'
}
});
10 changes: 7 additions & 3 deletions frontend/mobile/app/(design-system)/components/Icon/Icon.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IconDefinition } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome';

import { SACColors } from '../../shared/colors';
import { Colors, SACColors, defaultColor } from '../../shared/colors';
import { ComponentSizes } from '../../shared/types';
import { createStyles } from '../../theme';

Expand All @@ -11,12 +11,16 @@ type IconProps = {
color?: SACColors;
};

export const Icon: React.FC<IconProps> = ({ icon, size = 'medium', color }) => {
export const Icon: React.FC<IconProps> = ({
icon,
size = 'medium',
color = defaultColor
}) => {
return (
<FontAwesomeIcon
icon={icon}
size={styles[size].fontSize}
color={color}
color={Colors[color]}
/>
);
};
Expand Down
5 changes: 1 addition & 4 deletions frontend/mobile/metro.config.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require('expo/metro-config');

module.exports = (() => {
const config = getDefaultConfig(__dirname, {
isCSSEnabled: true
});
const config = getDefaultConfig(__dirname);

const { transformer, resolver } = config;

Expand Down
5 changes: 4 additions & 1 deletion frontend/mobile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"@react-navigation/native": "^6.0.2",
"@reduxjs/toolkit": "^2.2.5",
"@shopify/restyle": "^2.4.4",
"@svgr/core": "^8.1.0",
"expo": "~51.0.2",
"expo-dev-client": "~4.0.14",
"expo-font": "~12.0.5",
Expand All @@ -37,6 +38,8 @@
"expo-status-bar": "~1.12.1",
"expo-system-ui": "~3.0.4",
"expo-web-browser": "~13.0.3",
"font-awesome": "^4.7.0",
"path-dirname": "^1.0.2",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-native": "0.74.1",
Expand All @@ -45,6 +48,7 @@
"react-native-safe-area-context": "4.10.1",
"react-native-screens": "3.31.1",
"react-native-svg": "^15.3.0",
"react-native-svg-transformer": "^1.4.0",
"react-native-web": "~0.19.10",
"react-redux": "^9.1.2"
},
Expand All @@ -58,7 +62,6 @@
"jest": "^29.2.1",
"jest-expo": "~51.0.2",
"prettier": "^3.2.4",
"react-native-svg-transformer": "^1.4.0",
"react-test-renderer": "18.2.0",
"typescript": "~5.4.5"
},
Expand Down
3 changes: 3 additions & 0 deletions frontend/mobile/utils/string.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const firstLetterUppercase = (str: string) => {
return str.charAt(0).toUpperCase() + str.slice(1);
};
Loading

0 comments on commit fc151c4

Please sign in to comment.