diff --git a/app.config.js b/app.config.js index ad60097..4027cb1 100644 --- a/app.config.js +++ b/app.config.js @@ -67,6 +67,7 @@ module.exports = { backgroundColor: '#ffffff', }, // Add your custom intent filters here for Deep Linking + softwareKeyboardLayoutMode: 'pan', intentFilters: [ { action: 'VIEW', diff --git a/package.json b/package.json index 14ba915..2a07317 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "expo": "51.0.28", + "expo-device": "~6.0.2", "expo-font": "~12.0.10", "expo-image": "~1.12.13", "expo-linking": "^6.3.1", diff --git a/src/app/_layout.tsx b/src/app/_layout.tsx index 1c28ec3..c3da049 100644 --- a/src/app/_layout.tsx +++ b/src/app/_layout.tsx @@ -138,8 +138,6 @@ function RootLayoutNav() { title: 'Modal', presentation: 'modal', animation: 'fade_from_bottom', - - /** You have the ability to add left and right header JSX/TSX component here fx.: a Pressable Icon component or a Close Icon module*/ headerRight: () => , headerLeft: () => null, }} diff --git a/src/app/authenticationMiddleware.tsx b/src/app/authenticationMiddleware.tsx index 98383fb..f68e9f3 100644 --- a/src/app/authenticationMiddleware.tsx +++ b/src/app/authenticationMiddleware.tsx @@ -11,11 +11,6 @@ import getWindowDimensions from '@/lib/utils/getWindowDimension'; // @see https://reactnative.dev/docs/animations const authenticationMiddleware: React.FC = () => { const { width, height } = getWindowDimensions(); - /*const [loaded, error] = useFonts({ - PlaypenBold: require('src/assets/fonts/playpenBold.ttf'), - PlaypenRegular: require('src/assets/fonts/PlaypenSans-Regular.ttf'), - }); */ - const handleImagePosition = () => { if (width > 600) { return { @@ -30,9 +25,6 @@ const authenticationMiddleware: React.FC = () => { } }; - /*if (!loaded && !error) { - return null; - } */ const retrievedStyling = handleImagePosition(); return ( @@ -47,20 +39,10 @@ const authenticationMiddleware: React.FC = () => { /> - + Class Scheduler - + Welcome to CCNY Class Schedule Pro, your go-to app for managing class schedules, course information and more at CCNY! @@ -70,12 +52,7 @@ const authenticationMiddleware: React.FC = () => { router.push('/signin'); }} > - + Sign In{'\t'} @@ -83,16 +60,10 @@ const authenticationMiddleware: React.FC = () => { { - // TODO : Implement this screen router.push('/signup'); }} > - + Sign Up {'\b'} diff --git a/src/app/index.tsx b/src/app/index.tsx index 0843e0c..1f4b9cf 100644 --- a/src/app/index.tsx +++ b/src/app/index.tsx @@ -7,6 +7,8 @@ import Svg, { Path } from 'react-native-svg'; import getWindowDimensions from '@/lib/utils/getWindowDimension'; type FadeInViewProps = PropsWithChildren<{ style: ViewStyle }>; + +// TODO : ! https://blog.logrocket.com/react-native-push-notifications-complete-guide/ --> notification system guide const FadeInView: React.FC = (props) => { const fadeAnim = useRef(new Animated.Value(0)).current; // opacity initial : 0 useEffect(() => { @@ -36,19 +38,16 @@ const Landing: React.FC = () => { width: 0, height: 0, }); - /*const [loaded, error] = useFonts({ - Sofadi: require('src/assets/fonts/SofadiOne-Regular.ttf'), - }); */ const { width, height } = getWindowDimensions(); useEffect(() => { if (width > 600) { setCurrentImageStyling('w-[600px] h-[600px] justify-center object-none m-auto mt-1'); setTitleFont( - 'flex text-white font-Pacifico font-bold text-8xl items-center justify-center mx-auto mt-6' + 'flex text-white font-Pacifico font-bold text-8xl items-center justify-center mx-auto mt-6 font-mono' ); setSecondaryTextFont( - 'mx-auto flex items-center justify-center text-white text-4xl leading-8 mt-4' + 'mx-auto flex items-center justify-center text-white text-4xl leading-8 mt-4 font-sans' ); // ipads and tablets setSvgDimensions({ @@ -58,12 +57,12 @@ const Landing: React.FC = () => { } else { setCurrentImageStyling('w-80 h-80 justify-center object-none object-center m-auto mt-1'); setTitleFont( - 'flex text-white font-Pacifico font-bold text-5xl items-center justify-center mx-auto mt-6' + 'flex text-white font-Pacifico font-bold text-5xl items-center justify-center mx-auto mt-6 font-mono' ); if (height > 700) { // large phones setSecondaryTextFont( - 'mx-auto flex items-center justify-center text-white text-3xl leading-8 mt-4' + 'mx-auto flex items-center justify-center text-white text-3xl leading-8 mt-4 font-sans' ); setSvgDimensions({ width: 45, @@ -71,9 +70,8 @@ const Landing: React.FC = () => { }); } else { setSecondaryTextFont( - 'mx-auto flex items-center justify-center text-white text-2xl leading-8 mt-4' + 'mx-auto flex items-center justify-center text-white text-2xl leading-8 mt-4 font-sans' ); - // small/mid-sized phones setSvgDimensions({ width: 35, height: 35, @@ -83,10 +81,6 @@ const Landing: React.FC = () => { }, [width, height]); const imagePath = require('src/assets/images/Landing-Screen-Image-Updated.png'); - /* if (!loaded && !error) { - return null; - } */ - return ( { height={40} /> CCNY - - Class Schedule Manager - + Class Schedule Manager { - // TODO : Convert the types - const [titleFontStyling, setTitleFontStyling] = useState(''); - const [secondaryTextStyling, setSecondaryTextStyling] = useState(''); - const [imagePositionStyling, setImagePositionStyling] = useState(''); - const [emailInput, setEmailInput] = useState(''); - const [emailInputStyling, setEmailInputStyling] = useState(''); - const [passwordInput, setPasswordInput] = useState(''); - const [buttonStyling, setButtonStyling] = useState(''); - // same styling for confirm password - const [passwordInputStyling, setPasswordInputStyling] = useState(''); - const [confirmPasswordInput, setConfirmPasswordInput] = useState(''); const { width, height } = getWindowDimensions(); - - // TODO : Continue this implementation - useEffect(() => { - if (width > 600 && height > 700) { - // ipad styling - setTitleFontStyling('mt-14 text-white text-[55px]'); - setImagePositionStyling('-top-[48px] items-center justify-center mx-auto bg-transparent'); - setSecondaryTextStyling('text-white text-[35px] text-center px-14'); - setPasswordInputStyling( - 'bg-[#2f2f2f] text-[#94a3b8] h-[40px] m-[12px] border-spacing-1 text-2xl p-[10px] rounded-full pl-10' - ); - setEmailInputStyling( - 'bg-[#2f2f2f] text-[#94a3b8] h-[40px] m-[12px] border-spacing-1 text-2xl p-[10px] rounded-full pl-10 mt-5' - ); - setButtonStyling( - 'bg-white w-[700px] h-[60px] justify-center rounded-full items-center mx-auto mt-7 active:bg-gray-100 active:opacity-30' - ); - } else { - if (height > 700) { - // larger phones - setTitleFontStyling('text-white text-3xl mt-8'); - setImagePositionStyling('-top-[40px] items-center justify-center mx-auto mb-5'); - setSecondaryTextStyling('text-white mt-2 text-lg text-center px-8'); - setPasswordInputStyling( - 'bg-[#2f2f2f] text-[#94a3b8] h-[40px] m-[12px] border-spacing-1 text-lg p-[10px] rounded-full pl-10' - ); - setEmailInputStyling( - 'bg-[#2f2f2f] text-[#94a3b8] h-[40px] m-[12px] border-spacing-1 text-lg p-[10px] rounded-full pl-10 mt-8' - ); - setButtonStyling( - 'bg-white w-96 h-12 justify-center rounded-full items-center mx-auto mt-6 active:bg-gray-100 active:opacity-30' - ); - } else { - setTitleFontStyling('text-white text-2xl mt-6'); - setImagePositionStyling('-top-2 items-center justify-center mx-auto'); - setSecondaryTextStyling('text-white mt-1 text-md text-center px-10'); - setPasswordInputStyling( - 'bg-[#2f2f2f] text-[#94a3b8] h-[38px] m-[12px] border-spacing-1 text-md rounded-full pl-10' - ); - setEmailInputStyling( - 'bg-[#2f2f2f] text-[#94a3b8] h-[40px] m-[12px] border-spacing-1 text-md rounded-full pl-10 mt-6' - ); - setButtonStyling( - 'bg-white w-80 h-12 justify-center rounded-full items-center mx-auto mt-4 active:bg-gray-100 active:opacity-30' - ); - } - } - }, [width, height]); - - // width can be static + const { titleFontStyling, secondaryTextStyling } = getSignupStyles(); let inputBoxWidth = width * 0.9; - - // height needs to be adjusted based on different screen sizes let inputBoxHeight = height * 0.07; return ( - - + + - - - Join CCNY Schedule Pro! - - - Explore and manage class schedules efficiently - - {/**TODO : Implement a map to iteraete and implement the inputs as needed, abstract it or make it dynamic */} - - Keyboard.dismiss()} - > - Keyboard.dismiss()} - > - { - // TODO : Implement this screen - router.push('/onboardingGetStarted'); - }} - > - - Sign Up {'\b'} - - - - + Join CCNY Schedule Pro! + Explore and manage class schedules efficiently + + + + ); }; diff --git a/src/components/core/signupButton/index.tsx b/src/components/core/signupButton/index.tsx new file mode 100644 index 0000000..9ea6c98 --- /dev/null +++ b/src/components/core/signupButton/index.tsx @@ -0,0 +1,28 @@ +import { DimensionValue, Pressable, Text } from 'react-native'; +import { AntDesign } from '@expo/vector-icons'; +import { Href, useRouter } from 'expo-router'; + +interface SignUpButton { + width: DimensionValue | undefined; + height: DimensionValue | undefined; + route: Href; +} +// component should start with captial letter +export const SignupButton = ({ width, height, route }: SignUpButton) => { + const router = useRouter(); + return ( + router.push(route)} + > + + Sign Up {'\b'} + + + + ); +}; diff --git a/src/components/core/textInputComponent/getSignupStyles.ts b/src/components/core/textInputComponent/getSignupStyles.ts new file mode 100644 index 0000000..7ee550f --- /dev/null +++ b/src/components/core/textInputComponent/getSignupStyles.ts @@ -0,0 +1,62 @@ +import React from 'react'; +import getWindowDimensions from '@/lib/utils/getWindowDimension'; + +export const getSignupStyles = () => { + const [titleFontStyling, setTitleFontStyling] = React.useState(''); + const [secondaryTextStyling, setSecondaryTextStyling] = React.useState(''); + const [emailInputStyling, setEmailInputStyling] = React.useState(''); + const [passwordInputStyling, setPasswordInputStyling] = React.useState(''); + const { width, height } = getWindowDimensions(); + + React.useEffect(() => { + if (width > 600 && height > 700) { + // ipad styling + setTitleFontStyling('mt-14 text-white text-[55px] font-serif'); + setSecondaryTextStyling('text-white text-[35px] text-center px-14 my-7'); + setPasswordInputStyling( + 'bg-[#2f2f2f] text-[#94a3b8] h-[40px] m-[12px] border-spacing-1 text-2xl p-[10px] rounded-full pl-10' + ); + setEmailInputStyling( + 'bg-[#2f2f2f] text-[#94a3b8] h-[40px] m-[12px] border-spacing-1 text-2xl p-[10px] rounded-full pl-10 mt-5' + ); + } else if (height > 700 && width > 430) { + // larger phones + setTitleFontStyling('text-white text-3xl mt-8 font-serif'); + setSecondaryTextStyling('text-white mt-2 text-lg text-center px-8'); + setPasswordInputStyling( + 'bg-[#2f2f2f] text-[#94a3b8] h-[40px] m-[12px] border-spacing-1 text-lg p-[10px] rounded-full pl-10' + ); + setEmailInputStyling( + 'bg-[#2f2f2f] text-[#94a3b8] h-[40px] m-[12px] border-spacing-1 text-lg p-[10px] rounded-full pl-10 mt-8' + ); + } + // TODO : bootleg fix + else if (width === 414) { + setTitleFontStyling('text-white text-xl mt-4 font-serif text-center'); + setSecondaryTextStyling('text-white mt-1 text-md text-center px-10'); + setPasswordInputStyling( + 'bg-[#2f2f2f] text-[#94a3b8] h-[38px] m-[12px] border-spacing-1 text-md rounded-full pl-10' + ); + setEmailInputStyling( + 'bg-[#2f2f2f] text-[#94a3b8] h-[40px] m-[12px] border-spacing-1 text-md rounded-full pl-10 mt-6' + ); + } else { + setTitleFontStyling('text-white text-2xl mt-6 font-serif'); + //setImagePositionStyling('items-center justify-center mx-auto mt-3'); + setSecondaryTextStyling('text-white mt-1 text-md text-center px-10'); + setPasswordInputStyling( + 'bg-[#2f2f2f] text-[#94a3b8] h-[38px] m-[12px] border-spacing-1 text-md rounded-full pl-10' + ); + setEmailInputStyling( + 'bg-[#2f2f2f] text-[#94a3b8] h-[40px] m-[12px] border-spacing-1 text-md rounded-full pl-10 mt-6' + ); + } + }, [width, height]); + + return { + titleFontStyling, + secondaryTextStyling, + emailInputStyling, + passwordInputStyling, + }; +}; diff --git a/src/components/core/textInputComponent/index.tsx b/src/components/core/textInputComponent/index.tsx new file mode 100644 index 0000000..e836e6e --- /dev/null +++ b/src/components/core/textInputComponent/index.tsx @@ -0,0 +1,87 @@ +import { useState } from 'react'; +import { View, TextInput, Keyboard } from 'react-native'; +import getWindowDimensions from '@/lib/utils/getWindowDimension'; +import { getSignupStyles } from './getSignupStyles'; + +// ! useRef can be used to store the session cookie for logged in users +export const TextInputComponent = () => { + const { width, height } = getWindowDimensions(); + const currentStyles = getSignupStyles(); + + const dimensions = { + width: width * 0.9, + height: height * 0.07, + }; + const [emailInput, setEmailInput] = useState(); + const [passwordInput, setPasswordInput] = useState(''); + const [confirmPasswordInput, setConfirmPasswordInput] = useState(''); + + // @see https://www.ifelsething.com/post/get-value-react-native-text-input/ + // proper input handling + const handleEmailInput = (e: any) => { + setEmailInput(e.nativeEvent.text); + }; + + const handlePasswordInput = (e: any) => { + setPasswordInput(e.nativeEvent.text); + }; + + const handleConfirmPasswordInput = (e: any) => { + setConfirmPasswordInput(e.nativeEvent.text); + }; + + const TextInputArray = [ + { + id: 1, + dimensions: dimensions, + tailwindStyling: currentStyles.emailInputStyling, + placeholderText: 'Enter Your Email', + onChangeFunction: (newEmail: any) => handleEmailInput(newEmail), + value: emailInput, + isPassword: false, + blur: true, + }, + { + id: 2, + dimensions: dimensions, + tailwindStyling: currentStyles.passwordInputStyling, + placeholderText: 'Enter your password', + onChangeFunction: (newPassword: any) => handlePasswordInput(newPassword), + value: passwordInput, + isPassword: true, + blur: false, + }, + { + id: 3, + dimensions: dimensions, + tailwindStyling: currentStyles.passwordInputStyling, + placeholderText: 'Retype your password', + onChangeFunction: (confirmNewPassword: any) => handleConfirmPasswordInput(confirmNewPassword), + value: confirmPasswordInput, + isPassword: true, + blur: false, + }, + ]; + return ( + + {TextInputArray.map((TextInputIter) => ( + + ))} + + ); +}; diff --git a/yarn.lock b/yarn.lock index 3367d7e..0d6ee71 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4039,6 +4039,13 @@ expo-constants@~16.0.0: "@expo/config" "~9.0.0" "@expo/env" "~0.3.0" +expo-device@~6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/expo-device/-/expo-device-6.0.2.tgz#9bc3eccd16509c2819c225cc2ca8f7c3e3bdd11e" + integrity sha512-sCt91CuTmAuMXX4SlFOn4lIos2UIr8vb0jDstDDZXys6kErcj0uynC7bQAMreU5uRUTKMAl4MAMpKt9ufCXPBw== + dependencies: + ua-parser-js "^0.7.33" + expo-eas-client@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/expo-eas-client/-/expo-eas-client-0.12.0.tgz#e8b6f7d33873e6f630f37f7bfc41646ae7b0b2a9" @@ -8138,6 +8145,11 @@ typescript@^5.3.3: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.2.tgz#d1de67b6bef77c41823f822df8f0b3bcff60a5a0" integrity sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw== +ua-parser-js@^0.7.33: + version "0.7.39" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.39.tgz#c71efb46ebeabc461c4612d22d54f88880fabe7e" + integrity sha512-IZ6acm6RhQHNibSt7+c09hhvsKy9WUr4DVbeq9U8o71qxyYtJpQeDxQnMrVqnIFMLcQjHO0I9wgfO2vIahht4w== + ua-parser-js@^1.0.35: version "1.0.38" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.38.tgz#66bb0c4c0e322fe48edfe6d446df6042e62f25e2"