From 7f13cc406e7e7119245c2e8d180a927746df59f7 Mon Sep 17 00:00:00 2001 From: zvoverman Date: Sat, 18 May 2024 19:32:13 -0600 Subject: [PATCH 1/2] will work with deployment? --- src/components/App.tsx | 130 ++++++++++++++++++++-------------- src/components/PersonCard.tsx | 56 +++++++++++++-- 2 files changed, 130 insertions(+), 56 deletions(-) diff --git a/src/components/App.tsx b/src/components/App.tsx index e67ac33..532c91e 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -1,5 +1,5 @@ -import React, { useState } from 'react'; -import { QueryClient, QueryClientProvider } from 'react-query'; +import React, { useState, useEffect } from 'react'; +import { useQueryClient, QueryClient, QueryClientProvider, useQuery } from 'react-query'; import './App.css'; import PersonCard from './PersonCard'; import ToggleButton from 'react-bootstrap/ToggleButton'; @@ -8,10 +8,39 @@ import ToggleButtonGroup from 'react-bootstrap/ToggleButtonGroup'; const queryClient = new QueryClient(); function App() { + return ( + + + + ) +} + +function GetPeople() { const [length, setLength] = useState(12); const [favoriteCards, setFavoriteCards] = useState([]); const [showFavorites, setShowFavorites] = useState(false); + const queryClient = useQueryClient() + + const { isLoading, error, data } = useQuery('people', () => + fetch('https://w5c9dy2dg4.execute-api.us-east-2.amazonaws.com/people', { + headers: { + 'Content-Type': 'application/json', + "Access-Control-Allow-Origin": "*", + }, + }).then(res => + res.json() + ) + ); + + useEffect(() => { + if (data) { + //setFavoriteCards(data.map(person => person.id)); + } + }, [data]); + + console.log(data); + const handleInputChange = (event: React.ChangeEvent) => { const value = parseInt(event.target.value); if (!isNaN(value)) { @@ -21,7 +50,6 @@ function App() { } }; - // Call AWS lambda to update DynamoDB here!! const handleFavoriteToggle = (cardIndex: number) => { setFavoriteCards(prevFavorites => prevFavorites.includes(cardIndex) @@ -40,58 +68,56 @@ function App() { : Array.from({ length }, (_, index) => index); return ( - -
-
-

SWAPI React + Typescript Test!

- - Star Wars API - -
-
- - -
- - +
+

SWAPI React + Typescript Test!

+ - - All-Items - - - Favorites - - + Star Wars API + +
+
+ + +
+ + + + All-Items + + + Favorites + + -
- {displayedCards.map(index => ( - - ))} -
+
+ {displayedCards.map(index => ( + + ))}
- +
); } diff --git a/src/components/PersonCard.tsx b/src/components/PersonCard.tsx index affd13b..ba3baac 100644 --- a/src/components/PersonCard.tsx +++ b/src/components/PersonCard.tsx @@ -1,4 +1,5 @@ -import { useQuery } from 'react-query'; +import React from 'react'; +import { useQuery, useMutation, useQueryClient } from 'react-query'; import Card from 'react-bootstrap/Card'; import ToggleButton from 'react-bootstrap/ToggleButton'; @@ -9,6 +10,7 @@ interface PersonCardProps { } interface CharacterData { + id: string; name: string; height: string; mass: string; @@ -17,17 +19,57 @@ interface CharacterData { skin_color: string; } -function PersonCard({ index, isFavorite, onFavoriteToggle }: PersonCardProps): JSX.Element { +const addPerson = async (id: number, data: CharacterData): Promise => { + const response = await fetch(`https://w5c9dy2dg4.execute-api.us-east-2.amazonaws.com/people`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + "Access-Control-Allow-Origin": "*", + }, + body: JSON.stringify(data), + }); + if (!response.ok) { + throw new Error('Network response was not ok'); + } + return response.json(); +} +const deletePerson = async (id: number): Promise => { + const response = await fetch(`https://w5c9dy2dg4.execute-api.us-east-2.amazonaws.com/people/${id}`, { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json', + "Access-Control-Allow-Origin": "*", + }, + }); + if (!response.ok) { + throw new Error('Network response was not ok'); + } +} + +function PersonCard({ index, isFavorite, onFavoriteToggle }: PersonCardProps): JSX.Element { + const queryClient = useQueryClient(); // api starts at 1 not 0 - const person = index+1; + const person = index + 1; const { isLoading, error, data } = useQuery('getPerson_' + person, () => - fetch('https://swapi.dev/api/people/' + person).then(res => + fetch('https://swapi.dev/api/people/' + person).then(res => res.json() ) ); + const addMutation = useMutation((newData: CharacterData) => addPerson(person, newData), { + onSuccess: () => { + queryClient.invalidateQueries('getPerson_' + person); + }, + }); + + const deleteMutation = useMutation(() => deletePerson(person), { + onSuccess: () => { + queryClient.invalidateQueries('getPerson_' + person); + }, + }); + if (isLoading) return (

Loading...

); if (error) return (

Error fetching data.

); @@ -43,6 +85,11 @@ function PersonCard({ index, isFavorite, onFavoriteToggle }: PersonCardProps): J } const handleFavoriteClick = () => { + if (isFavorite) { + deleteMutation.mutate(); + } else { + addMutation.mutate(data); + } onFavoriteToggle(index); }; @@ -54,6 +101,7 @@ function PersonCard({ index, isFavorite, onFavoriteToggle }: PersonCardProps): J variant={isFavorite ? 'primary' : 'outline-primary'} value={1} onClick={handleFavoriteClick} + disabled={addMutation.isLoading || deleteMutation.isLoading} > {isFavorite ? 'Unfavorite' : 'Favorite'} From 0b2fc885db8bb0837810942d5dd62e02c241caf8 Mon Sep 17 00:00:00 2001 From: zvoverman Date: Sat, 18 May 2024 23:01:57 -0600 Subject: [PATCH 2/2] DynamoDB CRUD and AWS Lambda integration --- src/components/App.tsx | 14 ++++++++++++-- src/components/PersonCard.tsx | 5 +++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/components/App.tsx b/src/components/App.tsx index 532c91e..e83bc08 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -7,6 +7,16 @@ import ToggleButtonGroup from 'react-bootstrap/ToggleButtonGroup'; const queryClient = new QueryClient(); +interface CharacterData { + id: string; + name: string; + height: string; + mass: string; + eye_color: string; + hair_color: string; + skin_color: string; +} + function App() { return ( @@ -35,11 +45,11 @@ function GetPeople() { useEffect(() => { if (data) { - //setFavoriteCards(data.map(person => person.id)); + setFavoriteCards(data.map(person => parseInt(person.id))); } }, [data]); - console.log(data); + console.log(favoriteCards); const handleInputChange = (event: React.ChangeEvent) => { const value = parseInt(event.target.value); diff --git a/src/components/PersonCard.tsx b/src/components/PersonCard.tsx index ba3baac..a9e57b7 100644 --- a/src/components/PersonCard.tsx +++ b/src/components/PersonCard.tsx @@ -20,6 +20,7 @@ interface CharacterData { } const addPerson = async (id: number, data: CharacterData): Promise => { + data.id = id.toString(); const response = await fetch(`https://w5c9dy2dg4.execute-api.us-east-2.amazonaws.com/people`, { method: 'PUT', headers: { @@ -58,13 +59,13 @@ function PersonCard({ index, isFavorite, onFavoriteToggle }: PersonCardProps): J ) ); - const addMutation = useMutation((newData: CharacterData) => addPerson(person, newData), { + const addMutation = useMutation((newData: CharacterData) => addPerson(index, newData), { onSuccess: () => { queryClient.invalidateQueries('getPerson_' + person); }, }); - const deleteMutation = useMutation(() => deletePerson(person), { + const deleteMutation = useMutation(() => deletePerson(index), { onSuccess: () => { queryClient.invalidateQueries('getPerson_' + person); },