Skip to content

Commit 91a30c2

Browse files
ANUPAM KHOSLAANUPAM KHOSLA
authored andcommitted
REBASED local fix/width-apollo; SWAPI API endpoint fixed, graphql schema updated, expo 54, apollo 4
1 parent 0b1f848 commit 91a30c2

File tree

4 files changed

+110
-62
lines changed

4 files changed

+110
-62
lines changed

with-apollo/App.js

Lines changed: 89 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,50 @@
1-
import { ApolloProvider, gql, useQuery } from "@apollo/client";
1+
import { gql } from "@apollo/client";
2+
import { ApolloProvider, useQuery } from "@apollo/client/react";
23
import { Picker } from "@react-native-picker/picker";
3-
import { useState } from "react";
4+
import { useState, useEffect } from "react";
45
import { ActivityIndicator, StyleSheet, Text, View } from "react-native";
5-
66
import { apolloClient } from "./apollo";
77

8-
// Imperial I-class Star Destroyer
9-
const defaultStarshipId = "c3RhcnNoaXBzOjM=";
8+
// Imperial I-class Star Destroyer (numeric ID string, not Relay)
9+
const defaultStarshipId = "3";
1010

11-
const LIST_STARSHIPTS = gql`
11+
// List all starships (your wrapper returns results array)
12+
const LIST_STARSHIPS = gql`
1213
query listStarships {
1314
allStarships {
14-
starships {
15-
id
16-
name
15+
edges {
16+
node {
17+
id
18+
name
19+
}
1720
}
1821
}
1922
}
2023
`;
2124

25+
// Fetch single starship by numeric id (snake_case + films = [String])
2226
const GET_STARSHIP = gql`
2327
query getStarship($id: ID!) {
24-
starship(id: $id) {
28+
starshipById(id: $id) {
2529
id
2630
name
2731
model
28-
starshipClass
29-
manufacturers
30-
length
32+
starship_class
3133
crew
32-
costInCredits
34+
length
35+
cost_in_credits
3336
consumables
34-
filmConnection {
35-
films {
36-
id
37-
title
38-
}
37+
manufacturers
38+
film_names {
39+
title
40+
episode_id
41+
release_date
3942
}
4043
}
4144
}
4245
`;
4346

47+
4448
function RootComponent() {
4549
const [starshipId, setStarshipId] = useState(defaultStarshipId);
4650
const { data, error, loading } = useQuery(GET_STARSHIP, {
@@ -51,6 +55,8 @@ function RootComponent() {
5155
console.log("Error fetching starship", error);
5256
}
5357

58+
const starship = data?.starshipById;
59+
5460
return (
5561
<View style={styles.container}>
5662
<View style={styles.section}>
@@ -59,24 +65,33 @@ function RootComponent() {
5965
onStarshipChange={setStarshipId}
6066
/>
6167
</View>
62-
{loading ? (
63-
<ActivityIndicator color="#333" />
64-
) : (
65-
<StarshipDetails starship={data.starship} />
66-
)}
68+
<View style={styles.detailsContainer}>
69+
{loading ? (
70+
<ActivityIndicator color="#333" />
71+
) : starship ? (
72+
<StarshipDetails starship={starship} />
73+
) : (
74+
<Text style={{ color: "red" }}>No starship found</Text>
75+
)}
76+
</View>
6777
</View>
6878
);
6979
}
7080

7181
function StarshipPicker(props) {
72-
const { data, error, loading } = useQuery(LIST_STARSHIPTS);
82+
const { data, error, loading } = useQuery(LIST_STARSHIPS);
7383

7484
if (error) {
7585
console.log("Error listing starships", error);
86+
return <Text style={{ color: "red" }}>Failed to load starships</Text>;
7687
}
77-
if (loading) return null;
7888

79-
const { starships } = data.allStarships;
89+
if (loading) {
90+
return null;
91+
}
92+
93+
// Flatten edges → nodes
94+
const starships = data.allStarships.edges.map(edge => edge.node);
8095

8196
return (
8297
<Picker
@@ -94,7 +109,11 @@ function StarshipPicker(props) {
94109
);
95110
}
96111

112+
97113
function StarshipDetails({ starship }) {
114+
const [films, setFilms] = useState([]);
115+
const [loadingFilms, setLoadingFilms] = useState(false);
116+
98117
return (
99118
<>
100119
<View style={styles.section}>
@@ -104,29 +123,48 @@ function StarshipDetails({ starship }) {
104123

105124
<View style={styles.section}>
106125
<Text style={styles.label}>Operational abilities</Text>
107-
<Text>- {starship.crew} crew members</Text>
108-
<Text>- {starship.consumables} without restocking</Text>
126+
<Text>- {starship.crew ?? "N/A"} crew members</Text>
127+
<Text>- {starship.consumables ?? "N/A"} without restocking</Text>
109128
</View>
110129

111-
<View>
130+
<View style={styles.section}>
112131
<Text style={styles.label}>Ship attributes</Text>
113-
<Text>- {starship.length}m long</Text>
114-
<Text>- {starship.costInCredits} credits</Text>
132+
<Text>- {starship.length ?? "N/A"}m long</Text>
133+
<Text>- {starship.cost_in_credits ?? "N/A"} credits</Text>
115134
</View>
116135

117-
<View style={styles.section}>
118-
<Text style={styles.label}>Manufacturers</Text>
119-
{starship.manufacturers.map((manufacturer) => (
120-
<Text key={manufacturer}>- {manufacturer}</Text>
121-
))}
122-
</View>
136+
{starship.manufacturers?.length > 0 && (
137+
<View style={styles.section}>
138+
<Text style={styles.label}>Manufacturers</Text>
139+
{starship.manufacturers.map((m, idx) => (
140+
<Text key={idx}>- {m}</Text>
141+
))}
142+
</View>
143+
)}
123144

124-
<View style={styles.section}>
125-
<Text style={styles.label}>Appeared in</Text>
126-
{starship.filmConnection.films.map((film) => (
127-
<Text key={film.id}>- {film.title}</Text>
128-
))}
129-
</View>
145+
{starship.film_names?.length > 0 && (
146+
<View style={styles.section}>
147+
<Text style={styles.label}>Appeared in</Text>
148+
{starship.film_names.map((film, idx) => (
149+
<Text key={idx}>
150+
- {film.title} (Episode {film.episode_id}, {film.release_date})
151+
</Text>
152+
))}
153+
</View>
154+
)}
155+
156+
{loadingFilms ? (
157+
<ActivityIndicator color="#333" />
158+
) : films.length > 0 ? (
159+
<View style={styles.section}>
160+
<Text style={styles.label}>Appeared in</Text>
161+
{films.map((film, idx) => (
162+
<Text key={idx}>
163+
- {film.title} (Episode {film.episode_id})
164+
</Text>
165+
))}
166+
</View>
167+
) : null}
130168
</>
131169
);
132170
}
@@ -136,11 +174,18 @@ const styles = StyleSheet.create({
136174
flex: 1,
137175
justifyContent: "center",
138176
alignItems: "center",
177+
},
178+
detailsContainer: {
179+
flexGrow: 1,
180+
justifyContent: "flex-start", // keeps it pinned to the top
181+
minHeight: 200, // avoids collapse
182+
paddingTop: 20,
139183
},
140184
container: {
141185
flex: 1,
142186
justifyContent: "center",
143187
paddingHorizontal: 50,
188+
paddingTop: 100,
144189
},
145190
label: {
146191
marginBottom: 2,

with-apollo/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@
2222

2323
- The Apollo configuration lies in the `apollo.js` file.
2424
- The file also contains an option (with commented code) to pass an authorization token to the API.
25-
- [Apollo Client Docs](https://www.apollographql.com/docs/react/v3.0-beta/)
25+
- [Apollo Client Docs](https://www.apollographql.com/docs/react/get-started/)

with-apollo/apollo.js

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { ApolloClient, HttpLink, InMemoryCache } from '@apollo/client';
2-
// import { setContext } from '@apollo/link-context';
2+
// import { ApolloProvider, ApolloLink } from '@apollo/client';
3+
34

45
// see: https://github.com/graphql/swapi-graphql
5-
const GRAPHQL_API_URL = 'https://swapi-graphql.netlify.app/.netlify/functions/index';
6+
const GRAPHQL_API_URL = 'https://swapi-gql-wrapper.vercel.app/api/graphql';
67

78
/*
89
uncomment the code below in case you are using a GraphQL API that requires some form of
@@ -11,12 +12,15 @@ you provide while making the request.
1112
1213
1314
const TOKEN = '';
14-
const asyncAuthLink = setContext(async () => {
15-
return {
15+
16+
const authLink = new ApolloLink((operation, forward) => {
17+
operation.setContext(({ headers = {} }) => ({
1618
headers: {
17-
Authorization: TOKEN,
19+
...headers,
20+
Authorization: TOKEN ? `Bearer ${TOKEN}` : '',
1821
},
19-
};
22+
}));
23+
return forward(operation);
2024
});
2125
2226
*/
@@ -28,5 +32,5 @@ const httpLink = new HttpLink({
2832
export const apolloClient = new ApolloClient({
2933
cache: new InMemoryCache(),
3034
link: httpLink,
31-
// link: asyncAuthLink.concat(httpLink),
32-
});
35+
// link: authLink.concat(httpLink),
36+
});

with-apollo/package.json

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
{
22
"dependencies": {
3-
"@apollo/client": "^3.4.16",
4-
"@apollo/link-context": "^2.0.0-beta.3",
5-
"@react-native-picker/picker": "2.11.1",
6-
"expo": "^54.0.1",
7-
"graphql": "^15.0.0",
8-
"react": "19.1.0",
9-
"react-dom": "19.1.0",
10-
"react-native": "0.81.4",
11-
"react-native-web": "^0.21.0"
3+
"@apollo/client": "^4.0.4",
4+
"@react-native-picker/picker": "latest",
5+
"expo": "^54.0.1",
6+
"graphql": "^16.11.0",
7+
"react": "19.1.0",
8+
"react-dom": "19.1.0",
9+
"react-native": "0.81.4",
10+
"react-native-web": "latest"
1211
}
1312
}

0 commit comments

Comments
 (0)