diff --git a/.gitignore b/.gitignore index f69ec69..db3ea61 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ expo-debug.log /.expo-shared .env .DS_Store +/Lib/* # Go *.exe diff --git a/Taskfile.yaml b/Taskfile.yaml index 768fc88..9512e7e 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -1,6 +1,10 @@ version: "3" tasks: + dev: + cmds: + - cd scripts && ./tunnel.sh + run: cmds: - cd scripts && ./run.sh diff --git a/client-new/.eslintrc.js b/client-new/.eslintrc.js new file mode 100644 index 0000000..1679505 --- /dev/null +++ b/client-new/.eslintrc.js @@ -0,0 +1,12 @@ +module.exports = { + root: true, + extends: ['@react-native-community', 'plugin:prettier/recommended'], + plugins: ['prettier', 'jest'], + rules: { + 'prettier/prettier': 'error', + 'react/react-in-jsx-scope': 'off' + }, + env: { + 'jest/globals': true + } +}; diff --git a/client-new/.prettierrc b/client-new/.prettierrc new file mode 100644 index 0000000..6b7043e --- /dev/null +++ b/client-new/.prettierrc @@ -0,0 +1,9 @@ +{ + "printWidth": 80, + "tabWidth": 2, + "semi": true, + "singleQuote": true, + "trailingComma": "none", + "bracketSpacing": true, + "arrowParens": "always" +} diff --git a/client-new/App.tsx b/client-new/App.tsx index 2e0626c..974913a 100644 --- a/client-new/App.tsx +++ b/client-new/App.tsx @@ -1,9 +1,9 @@ -import { StatusBar } from "expo-status-bar"; -import { StyleSheet, Text, View } from "react-native"; -import Router from "./src/navigation/Router"; -import { NativeBaseProvider, extendTheme } from "native-base"; -import { SafeAreaProvider } from "react-native-safe-area-context"; -import { AuthProvider } from "./src/contexts/AuthContext"; +import { StatusBar } from 'expo-status-bar'; +import { StyleSheet, Text, View } from 'react-native'; +import Router from './src/navigation/Router'; +import { NativeBaseProvider, extendTheme } from 'native-base'; +import { SafeAreaProvider } from 'react-native-safe-area-context'; +import { AuthProvider } from './src/contexts/AuthContext'; import { useFonts, DMSans_400Regular, @@ -11,64 +11,108 @@ import { DMSans_500Medium, DMSans_500Medium_Italic, DMSans_700Bold, - DMSans_700Bold_Italic, -} from "@expo-google-fonts/dm-sans"; + DMSans_700Bold_Italic +} from '@expo-google-fonts/dm-sans'; +import React from 'react'; + +import { QueryClient, QueryClientProvider } from 'react-query'; + +const queryClient = new QueryClient(/*{ + defaultOptions: { + queries: { + refetchOnWindowFocus: false + } + } +}*/); + +import {Inter_400Regular, Inter_600SemiBold } from '@expo-google-fonts/inter'; + export default function App() { const [fontsLoaded] = useFonts({ + "MADE Dillan": require("./assets/fonts/MADE-Dillan.otf"), + "Roca Heavy": require("./assets/fonts/Roca-Bold.ttf"), + "Roca Light": require("./assets/fonts/Roca-Light.ttf"), + "Roca Regular": require("./assets/fonts/Roca-Regular.ttf"), + DMSans_400Regular, DMSans_400Regular_Italic, DMSans_500Medium, DMSans_500Medium_Italic, DMSans_700Bold, + DMSans_700Bold_Italic, + Inter_400Regular, + Inter_600SemiBold }); const theme = extendTheme({ fontConfig: { DM_Sans: { Regular: { - normal: "DMSans_400Regular", - italic: "DMSans_400Regular_Italic", + normal: 'DMSans_400Regular', + italic: 'DMSans_400Regular_Italic' }, Medium: { - normal: "DMSans_500Medium", - italic: "DMSans_500Medium_Italic", + normal: 'DMSans_500Medium', + italic: 'DMSans_500Medium_Italic' }, Bold: { normal: "DMSans_700Bold", italic: "DMSans_700Bold_Italic", }, }, + Roca_One: { + Light: { + normal: "Roca Light", + }, + Regular: { + normal: "Roca Regular", + }, + Bold: { + normal: "Roca Heavy", + }, + }, + Inter: { + Regular: { + normal: "Inter_400Regular", + }, + Bold: { + normal: "Inter_600SemiBold", + }, + }, }, colors: { - deepEvergreen: "#0C362F", - muteEggplant: "#251B22", + deepEvergreen: '#0C362F', + muteEggplant: '#251B22' }, fonts: { madeDillan: "MADE Dillan", // access fontFamily="madeDillan" dmSans: "DM_Sans", // access fontFamily={"dmSans"} fontWeight={"Regular"} fontStyle={"normal"} + rocaOne: "Roca_One", // access fontFamily={"rocaOne"} fontWeight={"Regular"} fontStyle={"normal"} + inter: "Inter", // access fontFamily={"inter"} fontWeight={"Regular"} fontStyle={"normal"} }, }); return ( - - - - - getUser() - - - + + + + + + + + + ); } const styles = StyleSheet.create({ container: { flex: 1, - backgroundColor: "#fff", - alignItems: "center", - justifyContent: "center", - }, + backgroundColor: '#fff', + alignItems: 'center', + justifyContent: 'center' + } }); diff --git a/client-new/README.md b/client-new/README.md new file mode 100644 index 0000000..aee3b64 --- /dev/null +++ b/client-new/README.md @@ -0,0 +1,27 @@ +# Frontend Installs & Learning References + + +### Installations +[Installing Node](https://nodejs.org/en/download/) + +[Installing the React Native Development Environment](https://reactnative.dev/docs/environment-setup) + + + +### Learning References + +#### React Native +[React Native Documentation](https://github.com/reactnative.dev/docs/getting-started) + +[React Native in Action (book)](https://learning.oreilly.com/library/view/react-native-in/9781617294051/) + +[Professional React Native](https://learning.oreilly.com/library/view/professional-react-native/9781800563681/) + +#### TypeScript +[TypeScript Documentation](https://www.typescriptlang.org/docs/) + +[TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/intro.html) + +[Learning TypeScript (book)](https://learning.oreilly.com/library/view/learning-typescript/9781098110321/) + +[Programming TypeScript (book)](https://learning.oreilly.com/library/view/programming-typescript/9781492037644/) diff --git a/client-new/assets/fonts/Roca-Bold.ttf b/client-new/assets/fonts/Roca-Bold.ttf new file mode 100644 index 0000000..b760937 Binary files /dev/null and b/client-new/assets/fonts/Roca-Bold.ttf differ diff --git a/client-new/assets/fonts/Roca-Light.ttf b/client-new/assets/fonts/Roca-Light.ttf new file mode 100644 index 0000000..36e2a77 Binary files /dev/null and b/client-new/assets/fonts/Roca-Light.ttf differ diff --git a/client-new/assets/fonts/Roca-Regular.ttf b/client-new/assets/fonts/Roca-Regular.ttf new file mode 100644 index 0000000..9057496 Binary files /dev/null and b/client-new/assets/fonts/Roca-Regular.ttf differ diff --git a/client-new/babel.config.js b/client-new/babel.config.js index 2900afe..fec1e69 100644 --- a/client-new/babel.config.js +++ b/client-new/babel.config.js @@ -1,6 +1,24 @@ -module.exports = function(api) { +module.exports = function (api) { api.cache(true); return { presets: ['babel-preset-expo'], + plugins: [ + [ + 'module-resolver', + { + root: ['./src'], + alias: { + '@/components': './src/components', + '@/screens': './src/screens', + '@/utils': './src/utils', + '@/assets': './src/assets', + '@/interfaces': './src/interfaces', + '@/contexts': './src/contexts', + '@/services': './src/services', + '@/navigation': './src/navigation' + } + } + ] + ] }; }; diff --git a/client-new/package.json b/client-new/package.json index a419dec..bcf522a 100644 --- a/client-new/package.json +++ b/client-new/package.json @@ -4,23 +4,39 @@ "main": "node_modules/expo/AppEntry.js", "scripts": { "start": "expo start", - "android": "expo start --android", - "ios": "expo start --ios", + "android": "expo run:android", + "ios": "expo run:ios", "web": "expo start --web", - "ts:check": "tsc" + "lint": "eslint . --ext .js,.jsx,.ts,.tsx", + "format": "prettier --write \"src/**/*.{js,jsx,ts,tsx}\"", + "test": "jest --passWithNoTests" + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "*.{js,jsx,ts,tsx}": [ + "prettier --write", + "git add" + ] }, "dependencies": { "@expo-google-fonts/dm-sans": "^0.2.3", + "@expo-google-fonts/inter": "^0.2.3", "@react-native-community/slider": "^4.4.3", + "@react-navigation/bottom-tabs": "^6.5.11", "@react-navigation/native": "^6.1.8", "@react-navigation/native-stack": "^6.9.14", + "@ronradtke/react-native-markdown-display": "^8.0.0", "@types/react": "^18.2.28", "@types/react-dom": "^18.2.13", "@types/react-native": "^0.72.3", "axios": "^1.6.0", "expo": "~49.0.13", "expo-dev-client": "^2.4.11", - "expo-font": "^11.6.0", + "expo-font": "~11.4.0", "expo-secure-store": "^12.5.0", "expo-status-bar": "~1.6.0", "firebase": "^10.5.0", @@ -35,11 +51,12 @@ "react-native-safe-area-context": "^4.7.2", "react-native-screens": "^3.25.0", "react-native-svg": "^13.14.0", - "react-native-vector-icons": "^10.0.0" + "react-native-vector-icons": "^10.0.0", + "react-query": "^3.39.3" }, "devDependencies": { "@babel/core": "^7.20.0", "typescript": "^5.1.3" }, "private": true -} \ No newline at end of file +} diff --git a/client-new/src/components/homescreen components/HomeScreenGuideCard.tsx b/client-new/src/components/homescreen components/HomeScreenGuideCard.tsx new file mode 100644 index 0000000..c2ed607 --- /dev/null +++ b/client-new/src/components/homescreen components/HomeScreenGuideCard.tsx @@ -0,0 +1,35 @@ +import { View, Text } from 'native-base'; + +type HSGCProps = { + title: string; + description: string; +}; + +const HomeScreenGuideCard: React.FC = (props) => { + return ( + + + {props.title} + + {props.description} + + + + ); +}; + +export default HomeScreenGuideCard; diff --git a/client-new/src/components/homescreen components/HomeScreenGuides.tsx b/client-new/src/components/homescreen components/HomeScreenGuides.tsx new file mode 100644 index 0000000..6eae358 --- /dev/null +++ b/client-new/src/components/homescreen components/HomeScreenGuides.tsx @@ -0,0 +1,24 @@ +import React from "react"; +import { View, Text, ScrollView } from "native-base"; // Import NativeBase components +import HomeScreenGuideCard from "./HomeScreenGuideCard"; + +type GuidesProps = { + guides: { + title: string; + description: string; + }[]; + }; + +const GuidesComponent: React.FC = ({ guides }) => { + return ( + + {guides.map((item, index) => ( + + + + ))} + + ); +}; + +export default GuidesComponent; diff --git a/client-new/src/components/homescreen components/HomeScreenTaskCard.tsx b/client-new/src/components/homescreen components/HomeScreenTaskCard.tsx new file mode 100644 index 0000000..f0b6a0a --- /dev/null +++ b/client-new/src/components/homescreen components/HomeScreenTaskCard.tsx @@ -0,0 +1,50 @@ +import { View, Text } from "native-base"; + + +type HSTCProps = { + title: String, + description: String, + progress: number +}; + +const HomeScreenTaskCard: React.FC = (props) => { + + return ( + + + {props.title} + {props.description} + + + + {props.progress}% + + + ); +}; + +export default HomeScreenTaskCard; \ No newline at end of file diff --git a/client-new/src/components/homescreen components/HomeScreenTasks.tsx b/client-new/src/components/homescreen components/HomeScreenTasks.tsx new file mode 100644 index 0000000..14e8051 --- /dev/null +++ b/client-new/src/components/homescreen components/HomeScreenTasks.tsx @@ -0,0 +1,56 @@ +import { View, Text } from "native-base"; +import HomeScreenTaskCard from "./HomeScreenTaskCard"; + +type YourJourneyProps = { + tasks: { + task_name: string; + task_description: string; + progress: number; + }[]; +}; + +const YourJourneyComponent: React.FC = ({ tasks }) => { + // Get the first three tasks + const displayedTasks = tasks.slice(0, 3); + + return ( + + + + Your Journey + + + See all + + + + + {displayedTasks.map((item, index) => ( + + + + ))} + + + ); +}; + +export default YourJourneyComponent; \ No newline at end of file diff --git a/client-new/src/components/icons/GuidesIcon.tsx b/client-new/src/components/icons/GuidesIcon.tsx new file mode 100644 index 0000000..f7911ee --- /dev/null +++ b/client-new/src/components/icons/GuidesIcon.tsx @@ -0,0 +1,32 @@ +import React from "react"; +import Svg, { G, Path, Defs, ClipPath, Rect } from 'react-native-svg'; + +interface GuidesIcon { + focused: boolean; +} + +const GuidesIcon = ({focused}) => { + return ( + + + + + + + + + + + + + + + + + + + ); + }; + + + export default GuidesIcon; diff --git a/client-new/src/components/icons/HomeIcon.tsx b/client-new/src/components/icons/HomeIcon.tsx new file mode 100644 index 0000000..892e87d --- /dev/null +++ b/client-new/src/components/icons/HomeIcon.tsx @@ -0,0 +1,17 @@ +import React from "react"; +import Svg, { G, Path, Defs, ClipPath, Rect } from 'react-native-svg'; + +interface HomeIconProps { + focused: boolean; +} + +const HomeIcon: React.FC = ({ focused }) => ( + + + + ); + + + export default HomeIcon; diff --git a/client-new/src/components/icons/MarketplaceIcon.tsx b/client-new/src/components/icons/MarketplaceIcon.tsx new file mode 100644 index 0000000..7b93c10 --- /dev/null +++ b/client-new/src/components/icons/MarketplaceIcon.tsx @@ -0,0 +1,24 @@ +import React from "react"; +import Svg, { G, Path, Defs, ClipPath, Rect } from 'react-native-svg'; + +interface MarketplaceIcon { + focused: boolean; +} + +const MarketplaceIcon = ({focused}) => { + return ( + + + + + + + + + + + ); + }; + + + export default MarketplaceIcon; diff --git a/client-new/src/components/icons/ProfileIcon.tsx b/client-new/src/components/icons/ProfileIcon.tsx new file mode 100644 index 0000000..da4f160 --- /dev/null +++ b/client-new/src/components/icons/ProfileIcon.tsx @@ -0,0 +1,25 @@ +import React from "react"; +import Svg, { G, Path, Defs, ClipPath, Rect } from 'react-native-svg'; + +interface ProfileIcon { + focused: boolean; +} + +const ProfileIcon = ({focused}) => { + return ( + + + + + + + + + + + + ); + }; + + + export default ProfileIcon; diff --git a/client-new/src/components/icons/TaskIcon.tsx b/client-new/src/components/icons/TaskIcon.tsx new file mode 100644 index 0000000..86b43c2 --- /dev/null +++ b/client-new/src/components/icons/TaskIcon.tsx @@ -0,0 +1,29 @@ +import React from "react"; +import Svg, { G, Path, Defs, ClipPath, Rect } from 'react-native-svg'; + +interface TaskIcon { + focused: boolean; +} + +const TaskIcon = ({focused}) => { + return ( + + + + + + + + + + + + + + + + ); + }; + + + export default TaskIcon; diff --git a/client-new/src/components/reusable/Circle.tsx b/client-new/src/components/reusable/Circle.tsx index 92c5764..f73c0bf 100644 --- a/client-new/src/components/reusable/Circle.tsx +++ b/client-new/src/components/reusable/Circle.tsx @@ -1,5 +1,5 @@ -import { View, Text } from "native-base"; -import { border } from "native-base/lib/typescript/theme/styled-system"; +import { View } from "native-base"; +import React from "react"; import { widthPercentageToDP as w, heightPercentageToDP as h, @@ -11,7 +11,6 @@ type CircleProps = { }; export default function Circle(props: CircleProps) { - const borderWidth = props.border ? 1 : 0 return ( @@ -26,4 +25,4 @@ export default function Circle(props: CircleProps) { > ); -} +} \ No newline at end of file diff --git a/client-new/src/components/reusable/CircleProgress.tsx b/client-new/src/components/reusable/CircleProgress.tsx new file mode 100644 index 0000000..e3b21bc --- /dev/null +++ b/client-new/src/components/reusable/CircleProgress.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { View, Text } from 'native-base'; + +type CircularProgressProps = { + progress: number; +} + +export default function CircleProgress(props: CircularProgressProps) { + return ( + + + + {props.progress}% + + + + ); +}; \ No newline at end of file diff --git a/client-new/src/components/reusable/CircleProgressBar.tsx b/client-new/src/components/reusable/CircleProgressBar.tsx index c453e73..9c9b9fc 100644 --- a/client-new/src/components/reusable/CircleProgressBar.tsx +++ b/client-new/src/components/reusable/CircleProgressBar.tsx @@ -1,9 +1,10 @@ import { View } from "native-base"; -import Circle from "./Circle"; +import Circle from "@/components/reusable/Circle"; import { widthPercentageToDP as w, heightPercentageToDP as h, } from "react-native-responsive-screen"; +import React from "react"; type CircleProgressBarProps = { totalCircles: number; @@ -15,11 +16,11 @@ export default function CircleProgressBar(props: CircleProgressBarProps) { for (let i = 0; i < props.totalCircles; i++) { if (i === 0 && props.completedCircles === 0) { - circles.push(); + circles.push(); } else if (i < props.completedCircles) { - circles.push(); + circles.push(); } else if (i === props.completedCircles) { - circles.push(); + circles.push(); } else { circles.push(); } diff --git a/client-new/src/components/reusable/CompaniesFooter.tsx b/client-new/src/components/reusable/CompaniesFooter.tsx index 613a984..92ad917 100644 --- a/client-new/src/components/reusable/CompaniesFooter.tsx +++ b/client-new/src/components/reusable/CompaniesFooter.tsx @@ -3,6 +3,7 @@ import { widthPercentageToDP as w, heightPercentageToDP as h, } from "react-native-responsive-screen"; +import React from "react"; export default function CompaniesFooter() { return ( diff --git a/client-new/src/components/reusable/LegacyWordmark.tsx b/client-new/src/components/reusable/LegacyWordmark.tsx index 9d2fa58..05f40b4 100644 --- a/client-new/src/components/reusable/LegacyWordmark.tsx +++ b/client-new/src/components/reusable/LegacyWordmark.tsx @@ -1,9 +1,21 @@ +import React from "react"; import { Text, View } from "native-base"; +import { SvgXml } from "react-native-svg"; + +const LegacyLogo = ` + + + + + +`; + export default function LegacyWordmark() { return ( - - - Legacy Wordmark + + + + Legacy ); diff --git a/client-new/src/components/reusable/LetsGo.tsx b/client-new/src/components/reusable/LetsGo.tsx index 028839d..04a3ed5 100644 --- a/client-new/src/components/reusable/LetsGo.tsx +++ b/client-new/src/components/reusable/LetsGo.tsx @@ -1,4 +1,6 @@ import { Text, View } from "native-base"; +import React from "react"; + export default function LetsGo() { return ( <> diff --git a/client-new/src/components/reusable/QuestionaireBox.tsx b/client-new/src/components/reusable/QuestionaireBox.tsx index 2899e22..c590277 100644 --- a/client-new/src/components/reusable/QuestionaireBox.tsx +++ b/client-new/src/components/reusable/QuestionaireBox.tsx @@ -4,7 +4,7 @@ import { widthPercentageToDP as w, heightPercentageToDP as h, } from "react-native-responsive-screen"; -import ResponseSlider from "./ResponseSlider"; +import ResponseSlider from "@/components/reusable/ResponseSlider"; type QuestionaireBoxProps = { text1: string; diff --git a/client-new/src/components/reusable/ResponseSlider.tsx b/client-new/src/components/reusable/ResponseSlider.tsx index 8be22cc..1d5f3ef 100644 --- a/client-new/src/components/reusable/ResponseSlider.tsx +++ b/client-new/src/components/reusable/ResponseSlider.tsx @@ -3,6 +3,7 @@ import { widthPercentageToDP as w, heightPercentageToDP as h, } from "react-native-responsive-screen"; +import React from "react"; export default function ResponseSlider() { const bigCircle = ( diff --git a/client-new/src/components/reusable/SquareButton.tsx b/client-new/src/components/reusable/SquareButton.tsx index 2aaabf1..0f9db4d 100644 --- a/client-new/src/components/reusable/SquareButton.tsx +++ b/client-new/src/components/reusable/SquareButton.tsx @@ -1,4 +1,5 @@ import { Button, Text } from "native-base"; +import React from "react"; type SquareButtonProps = { title: string; diff --git a/client-new/src/contexts/AuthContext.tsx b/client-new/src/contexts/AuthContext.tsx index de05403..1fc6b9f 100644 --- a/client-new/src/contexts/AuthContext.tsx +++ b/client-new/src/contexts/AuthContext.tsx @@ -6,9 +6,9 @@ import { signInWithEmailAndPassword, signOut, } from "firebase/auth"; -import { auth } from "../../firebase"; +import { auth } from "@/utils/firebase"; import { getItemAsync, setItemAsync, deleteItemAsync } from "expo-secure-store"; -import { authService } from "../services/authService"; +import { signIn, signUp } from "@/services/authService"; type AuthContextData = { user: FirebaseUser | null; @@ -54,37 +54,46 @@ export const AuthProvider: React.FC = ({ children }) => { } async function createAccount( - fullName: string, username: string, + email: string, password: string ) { try { - const user = await createUserWithEmailAndPassword( - auth, - username, - password - ); + const user = await createUserWithEmailAndPassword(auth, email, password); + + console.log("user firebase", user); // FIGURE OUT PERSONA_ID and where it comes from - const data = await authService.signUp({ - full_name: fullName, + console.log("user info", { + username: username, + email: email, + password: password, + firebase_id: user.user.uid, + }); + + const data = await signUp({ + email: email, username: username, password: password, - persona_id: 1, firebase_id: user.user.uid, }); + console.log("user signup didnt fail"); return true; } catch (error) { + console.log("User Signup Failed"); return error; } } const login = async (username: string, password: string) => { + console.log("username", username); + console.log("password", username); try { const user = await signInWithEmailAndPassword(auth, username, password); - authService.signIn(username, password, user.user.uid); + signIn(username, password, user.user.uid); return true; } catch (error) { + console.log("Error"); return error; } }; diff --git a/client-new/src/contexts/OnboardingContext.tsx b/client-new/src/contexts/OnboardingContext.tsx index fde647d..da4c61c 100644 --- a/client-new/src/contexts/OnboardingContext.tsx +++ b/client-new/src/contexts/OnboardingContext.tsx @@ -1,5 +1,6 @@ import { createContext, useContext, useState } from "react"; -import { IOnboardingFlowState } from "../interfaces/IOnboardingFlowState"; +import { IOnboardingFlowState } from "@/interfaces/IOnboardingFlowState"; +import React from "react"; type OnboardingContextData = { page: number; diff --git a/client-new/src/interfaces/IAction.ts b/client-new/src/interfaces/IAction.ts new file mode 100644 index 0000000..48bd311 --- /dev/null +++ b/client-new/src/interfaces/IAction.ts @@ -0,0 +1,52 @@ +export type IAction = IInput | ISelect | ITextArea | ICheckbox | IRadio; + +export type IActionList = { + actions: IAction[]; +}; + +export type IInput = { + action_type: string; + label: string; + name: string; + required: boolean; + type: string; + placeholder: string; + description?: string; +}; + +export type ISelect = { + action_type: string; + label: string; + name: string; + required: boolean; + options: string[]; + placeholder: string; + description: string; +}; + +export type ITextArea = { + action_type: string; + label: string; + name: string; + required: boolean; + placeholder: string; + description: string; +}; + +export type ICheckbox = { + action_type: string; + label: string; + name: string; + required: boolean; + options: string[]; + description: string; +}; + +export type IRadio = { + action_type: string; + label: string; + name: string; + required: boolean; + options: string[]; + description: string; +}; diff --git a/client-new/src/interfaces/IGuide.tsx b/client-new/src/interfaces/IGuide.ts similarity index 100% rename from client-new/src/interfaces/IGuide.tsx rename to client-new/src/interfaces/IGuide.ts diff --git a/client-new/src/interfaces/IOnboardingFlowState.tsx b/client-new/src/interfaces/IOnboardingFlowState.ts similarity index 100% rename from client-new/src/interfaces/IOnboardingFlowState.tsx rename to client-new/src/interfaces/IOnboardingFlowState.ts diff --git a/client-new/src/types/Persona.ts b/client-new/src/interfaces/IPersona.ts similarity index 80% rename from client-new/src/types/Persona.ts rename to client-new/src/interfaces/IPersona.ts index a0706d0..43dd6bb 100644 --- a/client-new/src/types/Persona.ts +++ b/client-new/src/interfaces/IPersona.ts @@ -1,4 +1,4 @@ -export type Persona = { +export interface IPersona { ID: number; CreatedAt: Date; UpdatedAt: Date; diff --git a/client-new/src/interfaces/ISubTask.ts b/client-new/src/interfaces/ISubTask.ts new file mode 100644 index 0000000..6dd21a3 --- /dev/null +++ b/client-new/src/interfaces/ISubTask.ts @@ -0,0 +1,10 @@ +import { IActionList } from "./IAction"; + +export interface ISubTask { + id: number; + task_name: string; + task_description: string; + task_id: number; + action: IActionList; + action_state: string; + } \ No newline at end of file diff --git a/client-new/src/interfaces/IUser.tsx b/client-new/src/interfaces/IUser.ts similarity index 67% rename from client-new/src/interfaces/IUser.tsx rename to client-new/src/interfaces/IUser.ts index 1866e86..3731fe4 100644 --- a/client-new/src/interfaces/IUser.tsx +++ b/client-new/src/interfaces/IUser.ts @@ -1,7 +1,7 @@ export interface IUser { - full_name: string; username: string; + email: string password: string; - persona_id: number; + persona_id?: number; firebase_id: string; } diff --git a/client-new/src/navigation/AppStack.tsx b/client-new/src/navigation/AppStack.tsx index ae5dd9e..e1533ff 100644 --- a/client-new/src/navigation/AppStack.tsx +++ b/client-new/src/navigation/AppStack.tsx @@ -1,5 +1,5 @@ import { createNativeStackNavigator } from "@react-navigation/native-stack"; -import HomeScreen from "../screens/app/HomeScreen"; +import HomeScreen from "../screens/app/BottomTabNavigator"; const Stack = createNativeStackNavigator(); @@ -10,7 +10,8 @@ export default function AppStack() { screenOptions={{ headerShown: false, }}> - + ); -} \ No newline at end of file +} diff --git a/client-new/src/navigation/AuthStack.tsx b/client-new/src/navigation/AuthStack.tsx index f0288d9..73d0f02 100644 --- a/client-new/src/navigation/AuthStack.tsx +++ b/client-new/src/navigation/AuthStack.tsx @@ -1,8 +1,9 @@ import { createNativeStackNavigator } from "@react-navigation/native-stack"; -import LoginScreen from "../screens/auth/LoginScreen"; -import SignUpScreen from "../screens/auth/SignUpScreen"; -import AccessScreen from "../screens/auth/AccessScreen"; +import LoginScreen from "@/screens/auth/LoginScreen"; +import SignUpScreen from "@/screens/auth/SignUpScreen"; +import AccessScreen from "@/screens/auth/AccessScreen"; import OnboardingStack from "./OnboardingStack"; +import React from "react"; const Stack = createNativeStackNavigator(); diff --git a/client-new/src/navigation/OnboardingStack.tsx b/client-new/src/navigation/OnboardingStack.tsx index 7f1f6d9..a606c8c 100644 --- a/client-new/src/navigation/OnboardingStack.tsx +++ b/client-new/src/navigation/OnboardingStack.tsx @@ -5,7 +5,7 @@ import SignUpTransitionScreen from "../screens/auth/SignUpTransitionScreen"; import PersonaScreen from "../screens/auth/PersonaScreen"; import LandingScreen from "../screens/auth/LandingScreen"; import QuizSectionIntroScreen from "../screens/auth/QuizSectionIntroScreen"; -import HomeScreen from "../screens/app/HomeScreen"; +import HomeScreen from "../screens/app/BottomTabNavigator"; const Stack = createNativeStackNavigator(); @@ -16,7 +16,6 @@ export default function OnboardingStack() { initialRouteName="Sign Up Transition Screen" screenOptions={{ headerShown: false, - }} > diff --git a/client-new/src/screens/app/BottomTabNavigator.tsx b/client-new/src/screens/app/BottomTabNavigator.tsx new file mode 100644 index 0000000..61dd9ec --- /dev/null +++ b/client-new/src/screens/app/BottomTabNavigator.tsx @@ -0,0 +1,58 @@ +import React from 'react'; +import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; +import HomeScreen from './HomeScreen'; +import GuideScreen from './GuideScreen'; +import TaskScreen from './TaskScreen'; +import MapScreen from './MarketplaceScreen'; +import ProfileScreen from './ProfileScreen'; + +import HomeIcon from '../../components/icons/HomeIcon'; +import GuidesIcon from '../../components/icons/GuidesIcon'; +import MarketplaceIcon from '../../components/icons/MarketplaceIcon'; +import TaskIcon from '../../components/icons/TaskIcon'; +import ProfileIcon from '../../components/icons/ProfileIcon'; + +const Tab = createBottomTabNavigator(); + +const TabNavigator = () => { + return ( + ({ + headerShown: false, + tabBarIcon: ({ focused }) => { + let iconComponent; + + if (route.name === 'Home') { + iconComponent = ; + } else if (route.name === 'Guides') { + iconComponent = ; + } else if (route.name === 'Tasks') { + iconComponent = ; + } else if (route.name === 'Marketplace') { + iconComponent = ; + } else if (route.name === 'Profile') { + iconComponent = ; + } + return iconComponent; + }, + tabBarStyle: { + backgroundColor: '#FFF9EE', + borderTopWidth: 1, + paddingTop: 10, + paddingBottom: 10, + + }, + tabBarLabel: '' + })} + > + + + + + + + + ); +}; + +export default TabNavigator; \ No newline at end of file diff --git a/client-new/src/screens/app/GuideScreen.tsx b/client-new/src/screens/app/GuideScreen.tsx index b26e558..91fcad8 100644 --- a/client-new/src/screens/app/GuideScreen.tsx +++ b/client-new/src/screens/app/GuideScreen.tsx @@ -1,13 +1,31 @@ -import { ScrollView, Box, View, Text, Image } from "native-base"; -import { useEffect, useState } from "react"; -import { IGuide } from "../../interfaces/IGuide"; -import { getMonth } from "../../utils/DateUtils"; -import { moderateScale, verticalScale } from "../../utils/FontSizeUtils"; +import { ScrollView, Box, View, Text, Image } from 'native-base'; +import { useEffect, useState } from 'react'; import { widthPercentageToDP as wp, - heightPercentageToDP as hp, -} from "react-native-responsive-screen"; -import { getGuide } from "../../services/GuideService"; + heightPercentageToDP as hp +} from 'react-native-responsive-screen'; +import { IGuide } from '../../interfaces/IGuide'; +import { getMonth } from '../../utils/DateUtils'; +import { moderateScale, verticalScale } from '../../utils/FontSizeUtils'; +import { getGuide } from '../../services/GuideService'; +import Markdown from '@ronradtke/react-native-markdown-display'; +import React from 'react'; + +const MarkdownWrapper: React.FC = ({ children }) => { + return ( + + + {children} + + + ); +}; const GuideScreen = (props) => { // props should include a guideName field. @@ -17,102 +35,91 @@ const GuideScreen = (props) => { const fetchGuide = async (guideName: string) => { try { const guide = await getGuide(guideName); - console.log("initialize guide success: ", guide); setState(guide); + console.log('initialize guide success: ', guide); } catch (err) { - console.log("failed to initialize guide: ", err); + console.log('failed to initialize guide: ', err); } }; - fetchGuide(props.guideName); }, [props.guideName]); return ( state && ( - - - + + + {state.title} {state.sub_title} - + barack Written by {state.author} - + {state.mins_read.toString()} min read - {getMonth(new Date(state.date).getMonth())}{" "} - {new Date(state.date).getDay().toString()},{" "} + {getMonth(new Date(state.date).getMonth())}{' '} + {new Date(state.date).getDay().toString()},{' '} {new Date(state.date).getFullYear().toString()} - - - {state.full_text} - + + {state.full_text} diff --git a/client-new/src/screens/app/HomeScreen.tsx b/client-new/src/screens/app/HomeScreen.tsx index cf6a6ab..8ef6737 100644 --- a/client-new/src/screens/app/HomeScreen.tsx +++ b/client-new/src/screens/app/HomeScreen.tsx @@ -1,177 +1,90 @@ -import { KeyboardAvoidingView, View, Text, } from "native-base"; +import { KeyboardAvoidingView, View, Text, ScrollView } from "native-base"; import { StyleSheet } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; -import { useAuth } from "../../contexts/AuthContext"; +import { useAuth } from "@/contexts/AuthContext"; import { - widthPercentageToDP as w, - heightPercentageToDP as h, + widthPercentageToDP as w, + heightPercentageToDP as h, } from "react-native-responsive-screen"; -import LegacyWordmark from "../../components/reusable/LegacyWordmark"; +import LegacyWordmark from "@/components/reusable/LegacyWordmark"; import { SvgUri } from "react-native-svg"; -// import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; -import { NavigationContainer } from '@react-navigation/native'; +import { useEffect, useState } from "react"; +import { getTasks } from "../../services/TaskService"; +import { getUser } from "../../services/UserService"; +import { moderateScale, verticalScale } from "../../utils/FontSizeUtils"; +import HomeScreenTasks from "../../components/homescreen components/HomeScreenTasks"; +import HomeScreenGuides from "../../components/homescreen components/HomeScreenGuides"; export default function HomeScreen() { - const { user, logout } = useAuth(); - const testData = [ - { - title: 'Acknowledge Your Aversion to End-Of-Life-Planning', - description: 'Lorem ipsum dolor sit amet consectetur. Ornare vestibulum.', - progress: 33, - }, - { - title: 'Create Familiarity with the Process', - description: 'Lorem ipsum dolor sit amet consectetur. Ornare vestibulum.', - progress: 10, - }, - { - title: 'Define Your Values and Priorities', - description: 'Lorem ipsum dolor sit amet consectetur. Ornare vestibulum.', - progress: 0, - }, - ]; + const { user, logout } = useAuth(); - return ( - <> - - - + const [tasks, setTasks] = useState([]) - - - - Hello Amanda! - - + useEffect(() => { + const fetchTasks = async () => { + const response = await getTasks("1") + // keep only the first 5 tasks + const firstThreeTasks = response.slice(0, 5) + setTasks(firstThreeTasks) + } + fetchTasks() + }, []) - - - - Your Journey - - - See all - - + // const [users, setUsers] = useState([]) - - {testData.map((item, index) => ( - - - - ))} - - - - - - - ); -} + // useEffect(() => { + // const fetchUsers = async () => { + // const response = await getUser("1") + // setTasks(response) + // } + // fetchUsers() + // }, []) + + + const guideData = [ + { title: 'Guide 1', description: 'Lorem ipsum dolor sit amet consectetur. Ornare vestibulum.' }, + { title: 'Guide 2', description: 'Lorem ipsum dolor sit amet consectetur. Ornare vestibulum.' }, + { title: 'Guide 3', description: 'Lorem ipsum dolor sit amet consectetur. Ornare vestibulum.' }, + ]; + + return ( + <> + + + + + + + + Hello Amanda! + + -const Card = (props) => { - return ( - - - - {props.title} - - - {props.description} - - - - - - - - {props.progress}% - - - - ); -}; + + + + + + + + Guides + + + See all + + + + + + + + + ); +} diff --git a/client-new/src/screens/app/MarketplaceScreen.tsx b/client-new/src/screens/app/MarketplaceScreen.tsx new file mode 100644 index 0000000..4c15543 --- /dev/null +++ b/client-new/src/screens/app/MarketplaceScreen.tsx @@ -0,0 +1,7 @@ +export default function MapScreen() { + + return ( + <> + + ); +} diff --git a/client-new/src/screens/app/ProfileScreen.tsx b/client-new/src/screens/app/ProfileScreen.tsx new file mode 100644 index 0000000..fcd4ab7 --- /dev/null +++ b/client-new/src/screens/app/ProfileScreen.tsx @@ -0,0 +1,7 @@ +export default function ProfileScreen() { + + return ( + <> + + ); +} diff --git a/client-new/src/screens/app/SubTaskScreen.tsx b/client-new/src/screens/app/SubTaskScreen.tsx new file mode 100644 index 0000000..771ca9f --- /dev/null +++ b/client-new/src/screens/app/SubTaskScreen.tsx @@ -0,0 +1,37 @@ +import FormComponent from '@/utils/Actions'; +import { getActions } from '@/services/SubTaskService'; +import { IAction, IActionList } from '@/interfaces/IAction'; +import { useEffect, useState } from 'react'; +import React from 'react'; +import { ENDPOINT } from '@/services/const'; +import { useQuery } from 'react-query'; +import { Text } from 'native-base'; + +const SubTaskScreen = ({ subtask_id }) => { + const [state, setState] = useState(null); + // props should include a id field + + const { isLoading, error, data } = useQuery( + ['fetchActions', subtask_id], + () => getActions(subtask_id) + ); + + console.log('action fetched: ', data); // {"actions": [{"action_type": "input", "label": "Full Legal Name", "name": "full_name", "placeholder": "Enter your full legal name", "required": true, "type": "text"}, {"action_type": "input", "description": "Please enter your date of birth in the format: MM/DD/YYYY", "label": "Date of Birth", "name": "date_of_birth", "placeholder": "MM/DD/YYYY", "required": true, "type": "date"}, {"action_type": "input", "description": "Please provide your 9-digit social security number", "label": "Social Security Number", "name": "ssn", "placeholder": "Enter your social security number", "required": true, "type": "text"}, {"action_type": "input", "description": "Please provide your complete current residential address", "label": "Current Address", "name": "current_address", "placeholder": "Enter your current address", "required": true, "type": "text"}, {"action_type": "input", "description": "Please provide a valid phone number where you can be reached", "label": "Phone Number", "name": "phone_number", "placeholder": "Enter your phone number", "required": true, "type": "tel"}, {"action_type": "input", "description": "Please provide a valid email address for communication purposes", "label": "Email Address", "name": "email", "placeholder": "Enter your email address", "required": true, "type": "email"}, {"action_type": "select", "description": "Please select your current marital status from the options provided", "label": "Marital Status", "name": "marital_status", "options": [Array], "placeholder": "Select your marital status", "required": true}, {"action_type": "textarea", "description": "Feel free to provide any additional information or comments here", "label": "Additional Comments", "name": "additional_comments", "placeholder": "Enter any additional comments", "required": false}, {"action_type": "checkbox", "description": "Select the services you require", "label": "Select Services", "name": "services", "options": [Array], "required": true}, {"action_type": "radio", "description": "Select your preferred method of payment", "label": "Select Payment Method", "name": "payment_method", "options": [Array], "required": true}]} + + if (isLoading) { + return ...loading ; + } + + if (error) { + return error ; + } + + if (data === null) { + // Data is still being fetched, you can render a loading indicator or return null + return null; + } + + return ; +}; + +export default SubTaskScreen; diff --git a/client-new/src/screens/app/TaskScreen.tsx b/client-new/src/screens/app/TaskScreen.tsx new file mode 100644 index 0000000..1871d9e --- /dev/null +++ b/client-new/src/screens/app/TaskScreen.tsx @@ -0,0 +1,64 @@ +import { View, Text, ScrollView, Button, } from "native-base"; +import { useAuth } from "../../contexts/AuthContext"; +import LegacyWordmark from "../../components/reusable/LegacyWordmark"; +import HomeScreenTaskCard from "../../components/homescreen components/HomeScreenTaskCard"; + + +export default function TaskScreen() { + const { user, logout } = useAuth(); + const tagData = ['Emotional', 'Financial', 'Value Based', 'Holistic']; + const subtaskData = [ + { + title: 'Research Resources', + description: 'Research resources on overcoming death' + }, { + title: 'Connect with Local Support Group', + description: 'View marketplace for places to find individuals facing similar fears' + }, { + title: 'Explore Mindfulness & Meditation Practices', + description: 'View guides to access partnership with Calm to help manage anxiety related end-of-life topics' + }]; + + return ( + <> + + + + + + + + All Tasks + + + {tagData.map((item) => ( + + ))} + + + + {subtaskData.map((item, index) => ( + + + + ))} + + + + + + + + + ); +} \ No newline at end of file diff --git a/client-new/src/screens/auth/AccessScreen.tsx b/client-new/src/screens/auth/AccessScreen.tsx index 79df79d..1dd7c3f 100644 --- a/client-new/src/screens/auth/AccessScreen.tsx +++ b/client-new/src/screens/auth/AccessScreen.tsx @@ -1,11 +1,12 @@ import { SafeAreaView } from "react-native-safe-area-context"; -import QuestionaireBox from "../../components/reusable/QuestionaireBox"; +import QuestionaireBox from "@/components/reusable/QuestionaireBox"; import { KeyboardAvoidingView, View, Text } from "native-base"; import { widthPercentageToDP as w, heightPercentageToDP as h, } from "react-native-responsive-screen"; -import ScreenWideButton from "../../components/reusable/ScreenWideButton"; +import ScreenWideButton from "@/components/reusable/ScreenWideButton"; +import React from "react"; export default function AccessScreen({ route, navigation }) { const toSignUp = () => { diff --git a/client-new/src/screens/auth/LandingScreen.tsx b/client-new/src/screens/auth/LandingScreen.tsx index a05d715..a41f092 100644 --- a/client-new/src/screens/auth/LandingScreen.tsx +++ b/client-new/src/screens/auth/LandingScreen.tsx @@ -4,6 +4,7 @@ import { widthPercentageToDP as w, heightPercentageToDP as h, } from "react-native-responsive-screen"; +import React from "react"; export default function LandingScreen({ route, navigation }) { return ( diff --git a/client-new/src/screens/auth/LoginScreen.tsx b/client-new/src/screens/auth/LoginScreen.tsx index fafbe36..27996b1 100644 --- a/client-new/src/screens/auth/LoginScreen.tsx +++ b/client-new/src/screens/auth/LoginScreen.tsx @@ -1,18 +1,19 @@ import { KeyboardAvoidingView, View } from "native-base"; import { Alert, StyleSheet } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; -import { useAuth } from "../../contexts/AuthContext"; +import { useAuth } from "@/contexts/AuthContext"; import { useState } from "react"; -import ScreenWideInput from "../../components/reusable/ScreenWideInput"; -import ScreenWideButton from "../../components/reusable/HalfScreenWideButton"; -import SquareButton from "../../components/reusable/SquareButton"; -import CompaniesFooter from "../../components/reusable/CompaniesFooter"; +import ScreenWideInput from "@/components/reusable/ScreenWideInput"; +import ScreenWideButton from "@/components/reusable/HalfScreenWideButton"; +import SquareButton from "@/components/reusable/SquareButton"; +import CompaniesFooter from "@/components/reusable/CompaniesFooter"; import { widthPercentageToDP as w, heightPercentageToDP as h, } from "react-native-responsive-screen"; -import LegacyWordmark from "../../components/reusable/LegacyWordmark"; -import LetsGo from "../../components/reusable/LetsGo"; +import LegacyWordmark from "@/components/reusable/LegacyWordmark"; +import LetsGo from "@/components/reusable/LetsGo"; +import React from "react"; export default function LoginScreen({ route, navigation }) { const { user, login, logout } = useAuth(); @@ -20,10 +21,12 @@ export default function LoginScreen({ route, navigation }) { const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); - const signIn = () => { + const logIn = () => { login(email, password); - navigation.navigate(""); + console.log("HIT"); + navigation.navigate("Access Screen"); + // // login(email, password).then((response) => { // if (response === true) { // // ONCE WE FIGURE OUT HOW TO GO TO HOME SCREEN, PUT HERE @@ -94,7 +97,7 @@ export default function LoginScreen({ route, navigation }) { textColor="#FFFFFF" backgroundColor="#8F8F8F" borderColor="#8F8F8F" - onClick={signIn} + onClick={logIn} /> diff --git a/client-new/src/screens/auth/PersonaScreen.tsx b/client-new/src/screens/auth/PersonaScreen.tsx index 7adb0d9..7f96c6f 100644 --- a/client-new/src/screens/auth/PersonaScreen.tsx +++ b/client-new/src/screens/auth/PersonaScreen.tsx @@ -5,11 +5,12 @@ import { widthPercentageToDP as w, heightPercentageToDP as h, } from "react-native-responsive-screen"; -import ScreenWideButton from "../../components/reusable/ScreenWideButton"; -import { useOnboarding } from "../../contexts/OnboardingContext"; +import ScreenWideButton from "@/components/reusable/ScreenWideButton"; +import { useOnboarding } from "@/contexts/OnboardingContext"; import { useEffect, useState } from "react"; -import { sendOnboardingResponse, getPersona } from "../../services/authService"; -import { Persona } from "../../types/Persona"; +import { sendOnboardingResponse, getPersona } from "@/services/authService"; +import { IPersona } from "@/interfaces/IPersona"; +import React from "react"; export default function PersonaScreen({ route, navigation }) { const { @@ -21,7 +22,7 @@ export default function PersonaScreen({ route, navigation }) { handleChange, } = useOnboarding(); - const [persona, setPersona] = useState(null); + const [persona, setPersona] = useState(null); const next = async () => { const nextPage = onboardingFlow[page + 1]; diff --git a/client-new/src/screens/auth/QuestionaireScreen.tsx b/client-new/src/screens/auth/QuestionaireScreen.tsx index 7313d0e..b7c4bad 100644 --- a/client-new/src/screens/auth/QuestionaireScreen.tsx +++ b/client-new/src/screens/auth/QuestionaireScreen.tsx @@ -1,15 +1,16 @@ import { SafeAreaView } from "react-native-safe-area-context"; -import QuestionaireBox from "../../components/reusable/QuestionaireBox"; +import QuestionaireBox from "@/components/reusable/QuestionaireBox"; import { Button, Divider, KeyboardAvoidingView, View } from "native-base"; -import CircleProgressBar from "../../components/reusable/CircleProgressBar"; -import LegacyWordmark from "../../components/reusable/LegacyWordmark"; +import CircleProgressBar from "@/components/reusable/CircleProgressBar"; +import LegacyWordmark from "@/components/reusable/LegacyWordmark"; import Icon from "react-native-vector-icons/Ionicons"; import { widthPercentageToDP as w, heightPercentageToDP as h, } from "react-native-responsive-screen"; -import ScreenWideButton from "../../components/reusable/ScreenWideButton"; -import { useOnboarding } from "../../contexts/OnboardingContext"; +import ScreenWideButton from "@/components/reusable/ScreenWideButton"; +import { useOnboarding } from "@/contexts/OnboardingContext"; +import React from "react"; export default function QuestionaireScreen({ route, navigation }) { const {page, setPage, onboardingState, setOnboardingState, onboardingFlow, handleChange} = useOnboarding(); diff --git a/client-new/src/screens/auth/QuizSectionIntroScreen.tsx b/client-new/src/screens/auth/QuizSectionIntroScreen.tsx index 94d206a..abec287 100644 --- a/client-new/src/screens/auth/QuizSectionIntroScreen.tsx +++ b/client-new/src/screens/auth/QuizSectionIntroScreen.tsx @@ -1,13 +1,14 @@ import { KeyboardAvoidingView, View, Text, Divider, Button } from "native-base"; import { SafeAreaView } from "react-native-safe-area-context"; -import CircleProgressBar from "../../components/reusable/CircleProgressBar"; -import LegacyWordmark from "../../components/reusable/LegacyWordmark"; +import CircleProgressBar from "@/components/reusable/CircleProgressBar"; +import LegacyWordmark from "@/components/reusable/LegacyWordmark"; import { widthPercentageToDP as w, heightPercentageToDP as h, } from "react-native-responsive-screen"; import Icon from "react-native-vector-icons/MaterialCommunityIcons"; -import { useOnboarding } from "../../contexts/OnboardingContext"; +import { useOnboarding } from "@/contexts/OnboardingContext"; +import React from "react"; export default function QuizSectionIntroScreen({ route, navigation }) { const { diff --git a/client-new/src/screens/auth/SignUpScreen.tsx b/client-new/src/screens/auth/SignUpScreen.tsx index 32db14b..b4b93fb 100644 --- a/client-new/src/screens/auth/SignUpScreen.tsx +++ b/client-new/src/screens/auth/SignUpScreen.tsx @@ -1,28 +1,29 @@ import { KeyboardAvoidingView, View } from "native-base"; import { StyleSheet, Alert } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; -import { useAuth } from "../../contexts/AuthContext"; +import { useAuth } from "@/contexts/AuthContext"; import { useState } from "react"; -import ScreenWideInput from "../../components/reusable/ScreenWideInput"; -import ScreenWideButton from "../../components/reusable/HalfScreenWideButton"; -import SquareButton from "../../components/reusable/SquareButton"; -import CompaniesFooter from "../../components/reusable/CompaniesFooter"; +import ScreenWideInput from "@/components/reusable/ScreenWideInput"; +import ScreenWideButton from "@/components/reusable/HalfScreenWideButton"; +import SquareButton from "@/components/reusable/SquareButton"; +import CompaniesFooter from "@/components/reusable/CompaniesFooter"; import { widthPercentageToDP as w, heightPercentageToDP as h, } from "react-native-responsive-screen"; -import LegacyWordmark from "../../components/reusable/LegacyWordmark"; -import LetsGo from "../../components/reusable/LetsGo"; +import LegacyWordmark from "@/components/reusable/LegacyWordmark"; +import LetsGo from "@/components/reusable/LetsGo"; +import React from "react"; export default function SignUpScreen({ route, navigation }) { const { user, createAccount } = useAuth(); - const [fullName, setFullName] = useState(""); + const [username, setUsername] = useState(""); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const signUp = () => { - createAccount(fullName, email, password); + createAccount(username, email, password); navigation.setOptions(); navigation.navigate("Onboarding Stack"); // createAccount(fullName, email, password).then((response) => { @@ -81,8 +82,8 @@ export default function SignUpScreen({ route, navigation }) { placeholderText="Example" title="Full Name" iconName="user-o" - onChangeText={(value) => setFullName(value)} - value={fullName} + onChangeText={(value) => setUsername(value)} + value={username} /> => { return new Promise((resolve, reject) => { setTimeout(() => { axios - .get(`http://localhost:8080/api/guides/${guideName}`) + .get(`${ENDPOINT}/api/guides/${guideName}`) .then((res) => { resolve(res.data); }) diff --git a/client-new/src/services/SubTaskService.ts b/client-new/src/services/SubTaskService.ts new file mode 100644 index 0000000..13f94c2 --- /dev/null +++ b/client-new/src/services/SubTaskService.ts @@ -0,0 +1,14 @@ +import axios from 'axios'; +import { IAction, IActionList } from '@/interfaces/IAction'; +import { ENDPOINT } from './const'; + +export const getActions = async (subtask_id: number) => { + try { + const res = await axios.get( + `https://legacy.loca.lt/api/subtasks/${subtask_id}/actions` + ); + return JSON.parse(res.data); + } catch (error) { + throw new Error(error); + } +}; diff --git a/client-new/src/services/TaskService.ts b/client-new/src/services/TaskService.ts new file mode 100644 index 0000000..624add5 --- /dev/null +++ b/client-new/src/services/TaskService.ts @@ -0,0 +1,7 @@ +import axios from "axios"; + +export const getTasks = async (id: string) => { + const user = await axios.get(`http://localhost:8080/api/users/${id}/tasks`) + .then((res) => { return res.data; }).catch((err) => { console.log(err); }); + return user; +} \ No newline at end of file diff --git a/client-new/src/services/UserService.ts b/client-new/src/services/UserService.ts new file mode 100644 index 0000000..4794e19 --- /dev/null +++ b/client-new/src/services/UserService.ts @@ -0,0 +1,7 @@ +import axios from "axios"; + +export const getUser = async (id: string) => { + const user = await axios.get(`http://localhost:8080/api/users/${id}`) + .then((res) => { return res.data; }).catch((err) => { console.log(err); }); + return user; +} \ No newline at end of file diff --git a/client-new/src/services/authService.ts b/client-new/src/services/authService.ts index e6421e8..82bb323 100644 --- a/client-new/src/services/authService.ts +++ b/client-new/src/services/authService.ts @@ -1,87 +1,82 @@ import axios from 'axios'; import { IUser } from '../interfaces/IUser'; import { IOnboardingFlowState } from '../interfaces/IOnboardingFlowState'; -import { Persona } from '../types/Persona'; +import { IPersona } from '../interfaces/IPersona'; +import { ENDPOINT } from './const'; // SHOULD AXIOS BE BEING USED AND IF SO, AM I DOING IT PROPERLY +export const signIn = async (email: string, password: string, uid: string) => { + // CHECK ROUTE HERE + const response = await fetch(`${ENDPOINT}/api/users/firebase/${uid}`); -const signIn = async (email: string, password: string, uid: string) => { - // CHECK ROUTE HERE - const response = await fetch( - `http://localhost:8081/api/users/firebase/${uid}` - ); + response.json().then((data) => { + console.log('This is the USER returned by Login: ', data); + }); - response.json().then((data) => { - console.log(data); - }); - - const data = await response.json(); - console.log("test", data); + const data = await response.json(); + console.log('test', data); }; +export const signUp = async (userInput: IUser) => { + try { + const response = await fetch(`${ENDPOINT}/api/users`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + username: userInput.username, + password: userInput.password, + email: userInput.username, + persona_id: userInput.persona_id, + firebase_id: userInput.firebase_id + }) + }); - -const signUp = async (userInput: IUser) => { - try { - - const response = await fetch("http://localhost:8080/api/users", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - username: userInput.username, - password: userInput.password, - email: userInput.username, - persona_id: userInput.persona_id, - firebase_id: userInput.firebase_id - }), - }); - - if (!response.ok) { - throw new Error('Network response was not ok'); - } - - const data = await response.json(); - console.log('test', data); - - // this should probably be in the login function - const profileResponse = await fetch(`http://localhost:8080/api/profiles/${data.id}`, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - name: userInput.username.split('@')[0] - }), - }); - - const profileData = await profileResponse.json(); - console.log('test', profileData); - } catch (error) { - console.log('Error:', error.message); + if (!response.ok) { + console.log('api response', response); + throw new Error('Network response was not ok'); } -} -export const sendOnboardingResponse = async (id: number, onboardingState: IOnboardingFlowState) => { - const data = await axios.post(`http://localhost:8081/api/profiles/response/${id}`, { - onboardingResponse: onboardingState - }) + const data = await response.json(); + console.log('test', data); + + // this should probably be in the login function + const profileResponse = await fetch(`${ENDPOINT}/api/profiles/${data.id}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + name: userInput.username.split('@')[0] + }) + }); - return data.status; + const profileData = await profileResponse.json(); + console.log('test', profileData); + } catch (error) { + console.log('Error:', error.message); + } +}; -} +export const sendOnboardingResponse = async ( + id: number, + onboardingState: IOnboardingFlowState +) => { + const data = await axios.post(`${ENDPOINT}/api/profiles/response/${id}`, { + onboardingResponse: onboardingState + }); -export const getPersona = async (id: number) => { - const data = await axios.post(`http://localhost:8081/api/personas/${id}`) - .then((res) => { res.data }) as Persona - - return data -} + return data.status; +}; +export const getPersona = async (id: number) => { + const data = (await axios + .post(`${ENDPOINT}/api/personas/${id}`) + .then((res) => { + res.data; + })) as IPersona; -export const authService = { - signIn, - signUp -}; \ No newline at end of file + return data; +}; diff --git a/client-new/src/services/const.ts b/client-new/src/services/const.ts new file mode 100644 index 0000000..48474d2 --- /dev/null +++ b/client-new/src/services/const.ts @@ -0,0 +1 @@ +export const ENDPOINT = 'https://legacy.loca.lt'; diff --git a/client-new/src/utils/Actions.tsx b/client-new/src/utils/Actions.tsx new file mode 100644 index 0000000..93f51be --- /dev/null +++ b/client-new/src/utils/Actions.tsx @@ -0,0 +1,212 @@ +import React, { useState, useCallback } from 'react'; +import { + Input, + FormControl, + Select, + TextArea, + Checkbox, + Radio +} from 'native-base'; +import { IAction, IActionList } from '@/interfaces/IAction'; + +const FormComponent = ({ actions }: IActionList) => { + const [formState, setFormState] = useState({}); + const handleListChange = (e, name, index) => { + e.preventDefault(); + + // Check if the index is within the bounds of the existing list of items. + if (index >= formState[name].length) { + return; + } + + const { value } = e.target; + const newValues = [...(formState[name] || [])]; + newValues[index] = value; + setFormState((prevState) => ({ ...prevState, [name]: newValues })); + }; + + const handleRemoveListItem = (name, index) => { + const newValues = [...formState[name]]; + newValues.splice(index, 1); + setFormState((prevState) => ({ ...prevState, [name]: newValues })); + }; + + const handleAddListItem = (e, name) => { + const newValues = [...(formState[name] || []), '']; // Initialize as an array + setFormState((prevState) => ({ ...prevState, [name]: newValues })); + }; + + // TODO: Doesnt work correctly + const handleRadioChange = (name, value) => { + setFormState((prevState) => ({ + ...prevState, + [name]: value + })); + }; + + const handleInputChange = (name, value) => { + setFormState((prevState) => ({ ...prevState, [name]: value })); + }; + + const handleSelectChange = (name, value) => { + setFormState((prevState) => ({ ...prevState, [name]: value })); + }; + + const handleTextAreaChange = (name, value) => { + setFormState((prevState) => ({ ...prevState, [name]: value })); + }; + + const handleCheckboxChange = (values, name) => { + setFormState((prevState) => ({ + ...prevState, + [name]: values.reduce((obj, value) => { + obj[value] = true; + return obj; + }, {}) + })); + }; + + // const generatePDF = () => { + + // const doc = new jsPDF(); + // doc.text(20, 20, 'Form Data:'); + // let verticalPosition = 30; + // for (const [key, value] of Object.entries(formState)) { + // doc.text(20, verticalPosition, `${key}: ${value}`); + // verticalPosition += 10; + // } + // doc.save('form_data.pdf'); + // }; + + const handleSubmit = (e) => { + e.preventDefault(); + console.log('Form submitted:', { + metadata: { timestamp: new Date() }, + form: formState + }); + // generatePDF(); + }; + + const renderField = (action, index) => { + switch (action.action_type) { + case 'input': + return ( + <> + {action.label} + {/* Conditonally based on type */} + handleInputChange(action.name, value)} + margin="normal" + variant="outlined" + /> + {/* {action.description} */} + + ); + case 'select': + return ( + <> + {action.label} + + + {action.description} + + + ); + case 'textarea': + return ( + <> + {action.label} +