diff --git a/App.tsx b/App.tsx index d71d9f7ead3418b3adeeed30bfafc4ce6c262b37..4ed5edfe521924c7ccc13078c2550bf9d660c8c3 100644 --- a/App.tsx +++ b/App.tsx @@ -1,15 +1,27 @@ import React from 'react'; -import { ScrollView, StyleSheet, Text, View } from 'react-native'; +import { SafeAreaView, SafeAreaViewBase, ScrollView, StyleSheet, Text, View } from 'react-native'; import PokemonsContainer from './containers/PokemonsContainer'; +import {ApolloClient, ApolloProvider, InMemoryCache} from "@apollo/client"; const App = () => { + const client = new ApolloClient({ + uri: 'http://it2810-14.idi.ntnu.no:4000/graphql', + cache: new InMemoryCache() +}); + return ( - <ScrollView> - <View style={styles.pokemonDiv}> - <PokemonsContainer /> - </View> - </ScrollView> + <ApolloProvider client={client}> + <SafeAreaView style={{flex:1 , backgroundColor: "#1E90FFFF"}}> + <ScrollView> + <View style={styles.pokemonDiv}> + <PokemonsContainer /> + </View> + </ScrollView> + </SafeAreaView> + + </ApolloProvider> + ); diff --git a/components/PokemonCard.tsx b/components/PokemonCard.tsx index 40fead9cf804185965cb356966f0da5ab30782b6..cb879a82963d8fc6841fe237e450a00da2aca9c7 100644 --- a/components/PokemonCard.tsx +++ b/components/PokemonCard.tsx @@ -1,29 +1,59 @@ -import React from 'react'; -import { StyleSheet, Image, Alert, Text, View, Button, Pressable } from 'react-native'; +import { useMutation } from '@apollo/react-hooks'; +import React, { useState } from 'react'; +import { StyleSheet, Image, Text, View, Pressable, TouchableWithoutFeedback } from 'react-native'; +import { MUTATE_POKEMON } from '../graphql/get-pokemons'; +import {Pokemon} from "../types/types"; -const PokemonCard = () => { - return ( + +const PokemonCard: React.FC<{ pokemon: Pokemon }> = ({pokemon}) => { + + const [clicked, setClicked] = useState(false); + const [capturedPokemons, setCapturedPokemons] = useState(pokemon.captured); + + const [updateDatabase] = useMutation(MUTATE_POKEMON, { + variables: { + pokemonId: { + id: pokemon.id + } + } + }) + + const handleClick = () => { + setClicked(!clicked) +}; + + const updateDatabaseFunction = () => { + setCapturedPokemons(!capturedPokemons) + updateDatabase() +} + + return ( //touchablewithoutfeedback for mer info knappen <View style={styles.pokemon}> <View style={styles.pokemon__name}> - <Text>Kristin Hestnes</Text> + <Text>{pokemon.name}</Text> </View> - <View style={styles.pokemon__meta}> - <Text style={styles.pokemon__meta_text}># 69</Text> - - </View> - <View style={styles.pokemon__image}> - <Image style={styles.pokemon__image_img} source={{uri: 'https://assets.pokemon.com/assets/cms2/img/pokedex/full/004.png'}} /> - </View> + {clicked && + <View style={styles.pokemon__meta}> + <Text style={styles.pokemon__meta_text}>#{pokemon.id}</Text> + </View> + } + <TouchableWithoutFeedback onPress={handleClick}> + <View style={styles.pokemon__image}> + <Image style={styles.pokemon__image_img} source={{uri: pokemon.imgUrl}} /> + </View> + </TouchableWithoutFeedback> + {clicked && <View style={styles.pokemon__type}> - <Text style={styles.pokemon__type_text}>Alcoholic</Text> - <Text style={styles.pokemon__type_text}>Attacker</Text> + {pokemon.pokemonTypes.map((t: string) => (<Text style={styles.pokemon__type_text} key={t}> {t}</Text>))} </View> - - <View> - <Pressable style={styles.button} onPress={() => Alert.alert("REJECTED, NOT HOT ENOUGH!")}> - <Text style={{fontSize: 30, color: 'white'}}>Hit on me?</Text> + } + + + <View > + <Pressable style={[capturedPokemons ? styles.buttonPressed: styles.buttonNotPressed]} onPress={updateDatabaseFunction}> + <Text style={{fontSize: 30, color: 'white'}}>{capturedPokemons ? "Captured!" : "Catch me!"}</Text> </Pressable> </View> @@ -111,7 +141,7 @@ const styles = StyleSheet.create({ textAlign: 'center', }, - button: { + buttonNotPressed: { backgroundColor: '#17c589', width: "100%", paddingTop: 0, @@ -120,6 +150,15 @@ const styles = StyleSheet.create({ justifyContent: 'center', }, + buttonPressed: { + backgroundColor: '#FF6347', + width: "100%", + paddingTop: 0, + paddingBottom: 5, + alignItems: 'center', + justifyContent: 'center', + + } }); diff --git a/containers/PokemonsContainer.tsx b/containers/PokemonsContainer.tsx index 5f85c6031c1c295f4f65d453c70fa2c1a3064a88..0bb903ff1a9920781f4e8f8419ea6a51dd837fe2 100644 --- a/containers/PokemonsContainer.tsx +++ b/containers/PokemonsContainer.tsx @@ -1,20 +1,49 @@ -import React from 'react'; +import React, { useState } from 'react'; import { ScrollView, StyleSheet, Text, View } from 'react-native'; import PokemonCard from '../components/PokemonCard'; +import {SEARCH_POKEMONS} from '../graphql/get-pokemons'; +import {useQuery} from '@apollo/react-hooks'; +import {Pokemon} from "../types/types"; const PokemonsContainer = () => { - return ( - - <View style={styles.container}> - <PokemonCard /> - <PokemonCard /> - <PokemonCard /> - <PokemonCard /> - <PokemonCard /> + + const searchText = "" + const typeText = "" + const capturedState = null + + const [limit, setLimit] = useState(15) + const [skip, setSkip] = useState(0) + + const {loading, error, data} = useQuery(SEARCH_POKEMONS, { + fetchPolicy: "no-cache", + variables: { + searchInput: { + searchText: searchText, + typeText: typeText, + limit: limit, + skip: skip, + captured: capturedState + } + } + }) + + if (loading){ + return ( + <Text>LOADING..</Text> + ) + } + else{ + return ( + <View style={styles.container}> + {data.searchPokemon && data.searchPokemon.map((pokemon: Pokemon) => + <PokemonCard key={pokemon.id} pokemon={pokemon}/>) + } </View> - - ) + ) + } + + } const styles = StyleSheet.create({ container: { diff --git a/graphql/get-pokemons.ts b/graphql/get-pokemons.ts new file mode 100644 index 0000000000000000000000000000000000000000..e373055f11749ff207c0fc49f6a91b344177c21a --- /dev/null +++ b/graphql/get-pokemons.ts @@ -0,0 +1,25 @@ +import gql from 'graphql-tag'; + +export const SEARCH_POKEMONS = gql ` + query Query($searchInput: SearchPokemon!) { + searchPokemon(searchInput: $searchInput) { + id + name + captured + imgUrl + pokemonTypes + } + } +` + +export const MUTATE_POKEMON = gql ` +mutation Mutation($pokemonId: SetCapturedPokemon!) { + setCaptured(pokemonId: $pokemonId) { + id + name + captured + imgUrl + pokemonTypes + } +} +` diff --git a/package-lock.json b/package-lock.json index 839f3de87ecec53631a99c4d4da7beb8453f19ce..8b912776ac3a5eb9fb46b18a8949ca08b87550e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,54 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@apollo/client": { + "version": "3.4.17", + "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.4.17.tgz", + "integrity": "sha512-MDt2rwMX1GqodiVEKJqmDmAz8xr0qJmq5PdWeIt0yDaT4GOkKYWZiWkyfhfv3raTk8PyJvbsNG9q2CqmUrlGfg==", + "requires": { + "@graphql-typed-document-node/core": "^3.0.0", + "@wry/context": "^0.6.0", + "@wry/equality": "^0.5.0", + "@wry/trie": "^0.3.0", + "graphql-tag": "^2.12.3", + "hoist-non-react-statics": "^3.3.2", + "optimism": "^0.16.1", + "prop-types": "^15.7.2", + "symbol-observable": "^4.0.0", + "ts-invariant": "^0.9.0", + "tslib": "^2.3.0", + "zen-observable-ts": "~1.1.0" + } + }, + "@apollo/react-hooks": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@apollo/react-hooks/-/react-hooks-4.0.0.tgz", + "integrity": "sha512-fCu0cbne3gbUl0QbA8X4L33iuuFVQbC5Jo2MIKRK8CyawR6PoxDpFdFA1kc6033ODZuZZ9Eo4RdeJFlFIIYcLA==", + "requires": { + "@apollo/client": "^3.4.17" + }, + "dependencies": { + "@apollo/client": { + "version": "3.4.17", + "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.4.17.tgz", + "integrity": "sha512-MDt2rwMX1GqodiVEKJqmDmAz8xr0qJmq5PdWeIt0yDaT4GOkKYWZiWkyfhfv3raTk8PyJvbsNG9q2CqmUrlGfg==", + "requires": { + "@graphql-typed-document-node/core": "^3.0.0", + "@wry/context": "^0.6.0", + "@wry/equality": "^0.5.0", + "@wry/trie": "^0.3.0", + "graphql-tag": "^2.12.3", + "hoist-non-react-statics": "^3.3.2", + "optimism": "^0.16.1", + "prop-types": "^15.7.2", + "symbol-observable": "^4.0.0", + "ts-invariant": "^0.9.0", + "tslib": "^2.3.0", + "zen-observable-ts": "~1.1.0" + } + } + } + }, "@babel/code-frame": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", @@ -1704,6 +1752,11 @@ "lodash.template": "^4.5.0" } }, + "@graphql-typed-document-node/core": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.1.1.tgz", + "integrity": "sha512-NQ17ii0rK1b34VZonlmT2QMJFI70m0TRwbknO/ihlbatXyaktDhN/98vBiUU6kNBPljqGqyIrl2T4nY2RpFANg==" + }, "@hapi/hoek": { "version": "9.2.1", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.1.tgz", @@ -2125,6 +2178,8 @@ }, "@types/react-native": { "version": "0.64.19", + "resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.64.19.tgz", + "integrity": "sha512-bT62QhaPvOKFGmlfURIC98ILjUDoIFrc2Bn5EzL3qciZrT91vHwkxFOkuEyQJy+DWaHCa2z3IrtIEJywkGu/Bg==", "dev": true, "requires": { "@types/react": "*" @@ -2156,6 +2211,35 @@ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==" }, + "@types/zen-observable": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.3.tgz", + "integrity": "sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw==" + }, + "@wry/context": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.6.1.tgz", + "integrity": "sha512-LOmVnY1iTU2D8tv4Xf6MVMZZ+juIJ87Kt/plMijjN20NMAXGmH4u8bS1t0uT74cZ5gwpocYueV58YwyI8y+GKw==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@wry/equality": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.5.2.tgz", + "integrity": "sha512-oVMxbUXL48EV/C0/M7gLVsoK6qRHPS85x8zECofEZOVvxGmIPLA9o5Z27cc2PoAyZz1S2VoM2A7FLAnpfGlneA==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@wry/trie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.3.1.tgz", + "integrity": "sha512-WwB53ikYudh9pIorgxrkHKrQZcCqNM/Q/bDzZBffEaGUKGuHrRb3zZUT9Sh2qw9yogC7SsdRmQ1ER0pqvd3bfw==", + "requires": { + "tslib": "^2.3.0" + } + }, "@xmldom/xmldom": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.5.tgz", @@ -3259,6 +3343,8 @@ }, "expo": { "version": "43.0.3", + "resolved": "https://registry.npmjs.org/expo/-/expo-43.0.3.tgz", + "integrity": "sha512-X4lLvoUuUbjj1n3DOjZ+w9TfNbEvNMRWvbOzYNYwS4FMB04Gt2RvQYYP8mXWbBZz0+b/s/Q+u67jj0+LMdxyfg==", "requires": { "@babel/runtime": "^7.14.0", "@expo/metro-config": "~0.1.84", @@ -3480,7 +3566,9 @@ } }, "expo-status-bar": { - "version": "1.1.0" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-1.1.0.tgz", + "integrity": "sha512-XgAbGfDV/Q6br2h4yzQwcZRYi37bZ/nvc06vvaJ7i7w9tRxb05OJmXBxl7ywkKlFCMcN6q3Miaf2wnzEgMwJoQ==" }, "extend-shallow": { "version": "3.0.2", @@ -3878,6 +3966,19 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" }, + "graphql": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.0.1.tgz", + "integrity": "sha512-oPvCuu6dlLdiz8gZupJ47o1clgb72r1u8NDBcQYjcV6G/iEdmE11B1bBlkhXRvV0LisP/SXRFP7tT6AgaTjpzg==" + }, + "graphql-tag": { + "version": "2.12.6", + "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", + "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", + "requires": { + "tslib": "^2.1.0" + } + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -5372,6 +5473,15 @@ "is-wsl": "^1.1.0" } }, + "optimism": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.16.1.tgz", + "integrity": "sha512-64i+Uw3otrndfq5kaoGNoY7pvOhSsjFEN4bdEFh80MWVk/dbgJfMv7VFDeCT8LxNAlEVhQmdVEbfE7X2nWNIIg==", + "requires": { + "@wry/context": "^0.6.0", + "@wry/trie": "^0.3.0" + } + }, "options": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", @@ -5729,6 +5839,8 @@ }, "react": { "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", + "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -5752,6 +5864,8 @@ }, "react-dom": { "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.1.tgz", + "integrity": "sha512-6eV150oJZ9U2t9svnsspTMrWNyHc6chX0KzDeAOXftRa8bNeOKTTfCJ7KorIwenkHd2xqVTBTCZd79yk/lx/Ug==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -5765,6 +5879,8 @@ }, "react-native": { "version": "0.64.3", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.64.3.tgz", + "integrity": "sha512-2OEU74U0Ek1/WeBzPbg6XDsCfjF/9fhrNX/5TFgEiBKd5mNc9LOZ/OlMmkb7iues/ZZ/oc51SbEfLRQdcW0fVw==", "requires": { "@jest/create-cache-key-function": "^26.5.0", "@react-native-community/cli": "^5.0.1-alpha.1", @@ -5905,6 +6021,8 @@ }, "react-native-web": { "version": "0.17.1", + "resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.17.1.tgz", + "integrity": "sha512-lUnn+2O8ynQ6/gJKylSxm7DLi2vHw6AujdDV1+LSa8Epe1bYFJNUcJTEhJf0jNYUFGOujzMtuG8Mkz3HdWTkag==", "requires": { "array-find-index": "^1.0.2", "create-react-class": "^15.7.0", @@ -6774,6 +6892,11 @@ "has-flag": "^4.0.0" } }, + "symbol-observable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", + "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==" + }, "temp": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", @@ -6882,6 +7005,14 @@ "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" }, + "ts-invariant": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.9.3.tgz", + "integrity": "sha512-HinBlTbFslQI0OHP07JLsSXPibSegec6r9ai5xxq/qHYCsIQbzpymLpDhAUsnXcSrDEcd0L62L8vsOEdzM0qlA==", + "requires": { + "tslib": "^2.1.0" + } + }, "tslib": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", @@ -6894,6 +7025,8 @@ }, "typescript": { "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", "dev": true }, "ua-parser-js": { @@ -7284,6 +7417,20 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" + }, + "zen-observable": { + "version": "0.8.15", + "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz", + "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==" + }, + "zen-observable-ts": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-1.1.0.tgz", + "integrity": "sha512-1h4zlLSqI2cRLPJUHJFL8bCWHhkpuXkF+dbGkRaWjgDIG26DmzyshUMrdV/rL3UnR+mhaX4fRq8LPouq0MYYIA==", + "requires": { + "@types/zen-observable": "0.8.3", + "zen-observable": "0.8.15" + } } } } diff --git a/package.json b/package.json index ec8a7b85c9f6fff4771100293340ce12e4964ee5..b05c6a18bb4ca89360f18f9efcf499d90f3ef1a6 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,14 @@ "eject": "expo eject" }, "dependencies": { + "@apollo/client": "^3.4.17", + "@apollo/react-hooks": "^4.0.0", "@emotion/react": "^11.6.0", "@emotion/styled": "^11.6.0", "@mui/material": "^5.1.1", "expo": "~43.0.2", "expo-status-bar": "~1.1.0", + "graphql": "^16.0.1", "react": "17.0.1", "react-dom": "17.0.1", "react-native": "0.64.3", diff --git a/types/types.ts b/types/types.ts new file mode 100644 index 0000000000000000000000000000000000000000..5c866ddf066d6b33e8c6dbe5da3056d157a1e847 --- /dev/null +++ b/types/types.ts @@ -0,0 +1,7 @@ +export interface Pokemon { + id: string | number; + name: string; + pokemonTypes: string[]; + imgUrl: string; + captured: boolean; +}