more practice for interview

This commit is contained in:
David Katrinka 2025-08-14 18:34:58 +02:00
parent 12e5665a1c
commit 743de131d8
9 changed files with 116 additions and 7 deletions

27
package-lock.json generated
View File

@ -8,6 +8,7 @@
"name": "reac-moment",
"version": "0.0.0",
"dependencies": {
"@tanstack/react-query": "^5.85.0",
"axios": "^1.10.0",
"react": "^19.1.0",
"react-dom": "^19.1.0"
@ -1348,6 +1349,32 @@
"win32"
]
},
"node_modules/@tanstack/query-core": {
"version": "5.83.1",
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.83.1.tgz",
"integrity": "sha512-OG69LQgT7jSp+5pPuCfzltq/+7l2xoweggjme9vlbCPa/d7D7zaqv5vN/S82SzSYZ4EDLTxNO1PWrv49RAS64Q==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
}
},
"node_modules/@tanstack/react-query": {
"version": "5.85.0",
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.85.0.tgz",
"integrity": "sha512-t1HMfToVMGfwEJRya6GG7gbK0luZJd+9IySFNePL1BforU1F3LqQ3tBC2Rpvr88bOrlU6PXyMLgJD0Yzn4ztUw==",
"license": "MIT",
"dependencies": {
"@tanstack/query-core": "5.83.1"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
},
"peerDependencies": {
"react": "^18 || ^19"
}
},
"node_modules/@types/babel__core": {
"version": "7.20.5",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",

View File

@ -10,6 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
"@tanstack/react-query": "^5.85.0",
"axios": "^1.10.0",
"react": "^19.1.0",
"react-dom": "^19.1.0"

View File

@ -4,13 +4,17 @@ import Header from './components/Header'
import PostList from './components/PostList'
import type { Post } from './components/types'
import axios from 'axios'
import UserContext from './context/UserContext'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import UserList from './components/UserList'
function App() {
const [username, setUsername] = useState('david');
const [posts, setPosts] = useState<Post[]>([]);
const [searchTerm, setSearchTerm] = useState("");
const queryClient = new QueryClient;
const fetchPosts = async () => {
@ -49,7 +53,7 @@ function App() {
}
);
},[posts, searchTerm]);
}, [posts, searchTerm]);
@ -61,13 +65,16 @@ function App() {
return (
<>
<QueryClientProvider client={queryClient}>
<UserContext.Provider value={{ username }}>
<Header setRefresh={fetchPosts} searchTerm={searchTerm} setSearchTerm={setSearchTerm} />
<Header setRefresh={fetchPosts} searchTerm={searchTerm} setSearchTerm={setSearchTerm} />
<UserList/>
<PostList posts={filteredPosts} />
<PostList posts={filteredPosts} />
</UserContext.Provider>
</QueryClientProvider>
</>
)
}

6
src/api/types.ts Normal file
View File

@ -0,0 +1,6 @@
export interface User {
id: number,
name: string,
username: string,
email: string
}

14
src/api/users.ts Normal file
View File

@ -0,0 +1,14 @@
import axios from "axios";
import type { User } from "./types";
export const getUsersAPI = async () => {
const response = await axios.get<User[]>('https://jsonplaceholder.typicode.com/users');
return response.data;
}
export const getUser = async (id: number) => {
const response = await axios.get<User>('https://jsonplaceholder.typicode.com/users/' + id);
return response.data;
}

View File

@ -1,12 +1,15 @@
import Block from "./Block";
import type { HeaderProps } from "./types";
import styles from "./Header.module.css";
import { useContext } from "react";
import UserContext from "../context/UserContext";
function Header({setRefresh, searchTerm, setSearchTerm}:HeaderProps) {
const user = useContext(UserContext);
return (
<Block title="Header">
<span>{user.username}</span>
<hr></hr>
<div className={styles.refreshAndSearch}>
<button className={styles.refreshBtn} onClick={() => setRefresh()}>Refresh</button>

View File

@ -0,0 +1,23 @@
import { useUsers, useUser } from "../query/users";
import Block from "./Block";
function UserList(){
const {data, isLoading, isFetching} = useUsers();
const {data: user1data, isLoading: user1Loading} = useUser(1);
if(isLoading || user1Loading)
return <div>Loading...</div>
return(
<Block title="users">
<h2>User List</h2>
{data?.map(user => <p>{user.username}</p>)}
<h2>USer info</h2>
<p>{user1data?.email}</p>
</Block>
)
}
export default UserList;

View File

@ -0,0 +1,7 @@
import { createContext } from "react";
const UserContext = createContext({
username: "david"
})
export default UserContext;

21
src/query/users.ts Normal file
View File

@ -0,0 +1,21 @@
import { useQuery } from "@tanstack/react-query";
import { getUser, getUsersAPI } from "../api/users";
export const useUsers = () => {
const { data, isFetching, isLoading } = useQuery({
queryKey: ['users'],
queryFn: getUsersAPI
});
return {data, isFetching, isLoading};
}
export const useUser = (id: number) => {
const{data, isFetching, isLoading} = useQuery({
queryKey: ['user', id],
queryFn: () => getUser(id)
})
return {data, isLoading, isFetching};
}