From 0d14051c30aee16c9ce179ea39803b1087a0e9a5 Mon Sep 17 00:00:00 2001 From: Rica2021 Date: Wed, 3 Jul 2024 14:11:26 -0400 Subject: [PATCH] Query graphql api using react query --- .env | 1 + api/{curl => exercises}/index.graphql | 0 api/index.graphql | 2 +- package-lock.json | 64 ++++++++++++++++++++++++--- package.json | 16 ++++--- src/app/[name].jsx | 39 +++++++++++++--- src/app/_layout.jsx | 17 ++++--- src/app/index.js | 49 ++++++++++++++++---- src/graphqlClient.js | 14 ++++++ 9 files changed, 170 insertions(+), 32 deletions(-) create mode 100644 .env rename api/{curl => exercises}/index.graphql (100%) create mode 100644 src/graphqlClient.js diff --git a/.env b/.env new file mode 100644 index 0000000..e4bc77a --- /dev/null +++ b/.env @@ -0,0 +1 @@ +EXPO_PUBLIC_GRAPQL_API_KEY = thataluna::local.net+1000::9e3d19bf6be3f41ed9e4208656794ca97d47a2c3eb6d75167918892ddc692607 \ No newline at end of file diff --git a/api/curl/index.graphql b/api/exercises/index.graphql similarity index 100% rename from api/curl/index.graphql rename to api/exercises/index.graphql diff --git a/api/index.graphql b/api/index.graphql index d1aab5f..1d20e09 100644 --- a/api/index.graphql +++ b/api/index.graphql @@ -1,3 +1,3 @@ -schema @sdl(files: ["curl/index.graphql"]) { +schema @sdl(files: ["exercises/index.graphql"]) { query: Query } diff --git a/package-lock.json b/package-lock.json index 3b5d5a1..6ae7a9d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,11 +8,15 @@ "name": "workoutapp", "version": "1.0.0", "dependencies": { + "@tanstack/react-query": "^5.49.2", "expo": "~51.0.17", "expo-constants": "~16.0.2", "expo-linking": "~6.3.1", "expo-router": "~3.5.17", "expo-status-bar": "~1.12.1", + "graphql": "^15.9.0", + "graphql-request": "^6.1.0", + "install": "^0.13.0", "react": "18.2.0", "react-dom": "18.2.0", "react-native": "0.74.2", @@ -2388,6 +2392,14 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, + "node_modules/@expo/cli/node_modules/graphql": { + "version": "15.8.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz", + "integrity": "sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/@expo/cli/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -6604,6 +6616,30 @@ "@sinonjs/commons": "^3.0.0" } }, + "node_modules/@tanstack/query-core": { + "version": "5.49.1", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.49.1.tgz", + "integrity": "sha512-JnC9ndmD1KKS01Rt/ovRUB1tmwO7zkyXAyIxN9mznuJrcNtOrkmOnQqdJF2ib9oHzc2VxHomnEG7xyfo54Npkw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.49.2", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.49.2.tgz", + "integrity": "sha512-6rfwXDK9BvmHISbNFuGd+wY3P44lyW7lWiA9vIFGT/T0P9aHD1VkjTvcM4SDAIbAQ9ygEZZoLt7dlU1o3NjMVA==", + "dependencies": { + "@tanstack/query-core": "5.49.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18.0.0" + } + }, "node_modules/@types/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", @@ -6697,7 +6733,6 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/@urql/exchange-retry/-/exchange-retry-0.3.0.tgz", "integrity": "sha512-hHqer2mcdVC0eYnVNbWyi28AlGOPb2vjH3lP3/Bc8Lc8BjhMsDwFMm7WhoP5C1+cfbr/QJ6Er3H/L08wznXxfg==", - "license": "MIT", "dependencies": { "@urql/core": ">=2.3.1", "wonka": "^4.0.14" @@ -9617,14 +9652,25 @@ "license": "ISC" }, "node_modules/graphql": { - "version": "15.8.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz", - "integrity": "sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==", - "license": "MIT", + "version": "15.9.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.9.0.tgz", + "integrity": "sha512-GCOQdvm7XxV1S4U4CGrsdlEN37245eC8P9zaYCMr6K1BG0IPGy5lUwmJsEOGyl1GD6HXjOtl2keCP9asRBwNvA==", "engines": { "node": ">= 10.x" } }, + "node_modules/graphql-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-6.1.0.tgz", + "integrity": "sha512-p+XPfS4q7aIpKVcgmnZKhMNqhltk20hfXtkaIkTfjjmiKMJ5xrt5c743cL03y/K7y1rg3WrIC49xGiEQ4mxdNw==", + "dependencies": { + "@graphql-typed-document-node/core": "^3.2.0", + "cross-fetch": "^3.1.5" + }, + "peerDependencies": { + "graphql": "14 - 16" + } + }, "node_modules/graphql-tag": { "version": "2.12.6", "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", @@ -9948,6 +9994,14 @@ "fast-loops": "^1.1.3" } }, + "node_modules/install": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/install/-/install-0.13.0.tgz", + "integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/internal-ip": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", diff --git a/package.json b/package.json index ace2cdb..1a7ddcb 100644 --- a/package.json +++ b/package.json @@ -9,17 +9,21 @@ "web": "expo start --web" }, "dependencies": { + "@tanstack/react-query": "^5.49.2", "expo": "~51.0.17", + "expo-constants": "~16.0.2", + "expo-linking": "~6.3.1", + "expo-router": "~3.5.17", "expo-status-bar": "~1.12.1", + "graphql": "^15.9.0", + "graphql-request": "^6.1.0", + "install": "^0.13.0", "react": "18.2.0", + "react-dom": "18.2.0", "react-native": "0.74.2", - "expo-router": "~3.5.17", - "react-native-screens": "3.31.1", - "expo-linking": "~6.3.1", - "expo-constants": "~16.0.2", "react-native-safe-area-context": "4.10.1", - "react-native-web": "~0.19.10", - "react-dom": "18.2.0" + "react-native-screens": "3.31.1", + "react-native-web": "~0.19.10" }, "devDependencies": { "@babel/core": "^7.20.0" diff --git a/src/app/[name].jsx b/src/app/[name].jsx index 99f6164..5cb3703 100644 --- a/src/app/[name].jsx +++ b/src/app/[name].jsx @@ -1,19 +1,48 @@ -import { View, Text, ScrollView } from "react-native"; +import { View, Text, ScrollView, ActivityIndicator } from "react-native"; import { useLocalSearchParams, Stack } from "expo-router"; import exercises from "../../assets/data/exercises.json"; import { StyleSheet } from "react-native"; import { useState } from "react"; +import { gql } from "graphql-request"; +import { useQuery } from "@tanstack/react-query"; +import client from "../graphqlClient"; + + +const exerciseQuery = gql` + query exercises($name: String) { + exercises(name: $name) { + equipment + instructions + name + muscle + } +} +`; + export default function ExerciseDetailsScreen() { - const params = useLocalSearchParams(); + + const { name } = useLocalSearchParams(); + + const {data, isLoading, error} = useQuery({ + queryKey: ['exercises',name], + queryFn: () => client.request(exerciseQuery, { name }), + }); + const [isExpandInstructions, setIsExpandInstructions] = useState(false); - const exercise = exercises.find((item) => item.name === params.name); - if (!exercise) { - return Exercise not found; + if (isLoading){ + return ; + } + + if (error) { + return Failed to fetch data. } + const exercise = data.exercises[0]; + + return ( diff --git a/src/app/_layout.jsx b/src/app/_layout.jsx index 2d24b64..c16141d 100644 --- a/src/app/_layout.jsx +++ b/src/app/_layout.jsx @@ -1,9 +1,14 @@ import { Stack, Slot } from "expo-router"; +import { QueryClientProvider, QueryClient } from "@tanstack/react-query"; + +const client = new QueryClient(); export default function RootLayout() { - return ( - - - - ); -} \ No newline at end of file + return ( + + + + + + ); +} diff --git a/src/app/index.js b/src/app/index.js index 9919842..a3a10ee 100644 --- a/src/app/index.js +++ b/src/app/index.js @@ -1,19 +1,52 @@ import { StatusBar } from "expo-status-bar"; -import { StyleSheet, Text, View, FlatList } from "react-native"; +import { + StyleSheet, + Text, + View, + FlatList, + ActivityIndicator, +} from "react-native"; import exercises from "../../assets/data/exercises.json"; import ExerciseListItem from "../components/ExerciseListItem"; +import { useQuery } from "@tanstack/react-query"; +import { gql } from "graphql-request"; +import client from "../graphqlClient"; +const exercisesQuery = gql` + query MyQuery($muscle: String, $name: String) { + exercises(name: $name, muscle: $muscle) { + muscle + name + equipment + } + } +`; -export default function App() { +export default function ExercisesScreen() { + + const { data, isLoading, error } = useQuery({ + queryKey: ["exercises"], + queryFn: () => client.request( exercisesQuery ), + }); + + if (isLoading) { + return ; + } + + if (error) { + console.log(error); + return Failed to fetch data.; + } + + console.log(data); return ( item.name + index} - renderItem={({ item }) => } - + data={data.exercises} + contentContainerStyle={{ gap: 5 }} + keyExtractor={(item, index) => item.name + index} + renderItem={({ item }) => } /> @@ -26,7 +59,5 @@ const styles = StyleSheet.create({ flex: 1, justifyContent: "center", padding: 10, - }, - }); diff --git a/src/graphqlClient.js b/src/graphqlClient.js new file mode 100644 index 0000000..27c2a0e --- /dev/null +++ b/src/graphqlClient.js @@ -0,0 +1,14 @@ +import { GraphQLClient } from "graphql-request"; + +const url = + "https://thataluna.us-east-a.ibm.stepzen.net/api/invisible-donkey/graphql"; + +const apiKey = process.env.EXPO_PUBLIC_GRAPQL_API_KEY; + +const client = new GraphQLClient(url, { + headers: { + Authorization: `apikey ${apiKey}`, + }, +}); + +export default client;