Ten skrypt w React tworzy komponent, który automatycznie pobiera listę użytkowników z serwera, a następnie wyświetla ją w formie tabeli. Komponent obsługuje różne stany, takie jak ładowanie danych, wyświetlanie błędów oraz wyświetlanie danych po ich załadowaniu.
Szczegółowy opis działania skryptu:
- Inicjalizacja stanu komponentu:
users
: Przechowuje listę użytkowników. Początkowo jest to pusta tablica.loading
: Wskazuje, czy dane są w trakcie ładowania. Początkowo ustawione natrue
.error
: Przechowuje ewentualne błędy, które mogą wystąpić podczas pobierania danych. Początkowo jestnull
.
- Pobieranie danych z serwera:
useEffect
: Po pierwszym załadowaniu komponentu wywołuje asynchroniczną funkcjęfetchUsers
, która pobiera dane użytkowników z podanego adresu API.- Żądanie HTTP: Wysyłane jest zapytanie GET do serwera w celu pobrania listy użytkowników. Zapytanie zawiera nagłówki, takie jak
Authorization
z tokenem uwierzytelniającym orazContent-Type
jakoapplication/json
. - Obsługa odpowiedzi: Jeśli serwer zwróci poprawną odpowiedź, dane użytkowników są zapisywane w stanie
users
, aloading
jest ustawione nafalse
. Jeśli wystąpi błąd, jest on przechwytywany, a jego szczegóły są zapisane w stanieerror
.
- Renderowanie komponentu:
- Ładowanie: Jeśli dane są w trakcie pobierania, wyświetlany jest komunikat "Loading...".
- Błąd: Jeśli wystąpił błąd podczas pobierania danych, wyświetlany jest komunikat o błędzie.
- Tabela z użytkownikami: Jeśli dane zostały poprawnie załadowane, komponent renderuje tabelę, w której wyświetla listę użytkowników. Każdy wiersz tabeli zawiera informacje o ID użytkownika, nazwie użytkownika, adresie e-mail, tokenie oraz dacie wygaśnięcia tokena.
import { useState, useEffect } from "react";
function UserList() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
// Funkcja do pobierania użytkowników
const fetchUsers = async () => {
try {
const response = await fetch("https://localhost:7106/api/admin/users", {
method: "GET",
headers: {
Authorization: "FBEE68BE-C5FD-465A-89B8-AB04A81C5C78", // Podaj swój rzeczywisty token bez "Bearer"
"Content-Type": "application/json",
},
});
if (!response.ok) {
throw new Error("Network response was not ok");
}
const data = await response.json();
setUsers(data);
setLoading(false);
} catch (error) {
setError(error);
setLoading(false);
}
};
fetchUsers();
}, []);
if (loading) {
return <div className="text-center mt-5">Loading...</div>;
}
if (error) {
return (
<div className="text-center mt-5 text-danger">Error: {error.message}</div>
);
}
return (
<div className="container mt-5">
<h2>User List</h2>
<table
className="table table-striped table-bordered"
style={{ border: "1px solid black" }}
>
<thead>
<tr>
<th>ID</th>
<th>Username</th>
<th>Email</th>
<th>Token</th>
<th>Expiration Date</th>
</tr>
</thead>
<tbody>
{users.map((user) => (
<tr key={user.id}>
<td style={{ border: "1px solid black" }}>{user.id}</td>
<td style={{ border: "1px solid black" }}>{user.userName}</td>
<td style={{ border: "1px solid black" }}>{user.email}</td>
<td style={{ border: "1px solid black" }}>{user.token}</td>
<td style={{ border: "1px solid black" }}>
{user.expirationDate}
</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
export default UserList;
Ten skrypt tworzy formularz logowania w React, który umożliwia użytkownikowi zalogowanie się poprzez podanie adresu e-mail i hasła.
Co robi skrypt:
- Przechowywanie danych logowania: Skrypt zarządza stanami dla adresu e-mail, hasła, tokena JWT, informacji o błędzie oraz statusu ładowania.
- Obsługa logowania: Gdy użytkownik wypełni formularz i go wyśle, skrypt wysyła zapytanie HTTP POST do określonego API z danymi logowania. Skrypt oczekuje na odpowiedź serwera.
- Przechwytywanie tokena JWT: Po udanym logowaniu serwer zwraca token JWT. Skrypt zapisuje ten token w
localStorage
oraz w stanie komponentu. - Dekodowanie tokena: Skrypt dekoduje token JWT, aby wyciągnąć z niego specyficzne informacje, takie jak
UserToken
, i zapisuje je w stanie komponentu. - Wyświetlanie komunikatów:
- Jeśli logowanie jest w toku, wyświetlany jest komunikat o ładowaniu.
- Jeśli logowanie się nie powiedzie, wyświetlany jest komunikat o błędzie.
- Po udanym logowaniu wyświetlany jest token JWT oraz wyciągnięta z niego informacja
UserToken
.
- Interfejs użytkownika: Formularz jest zbudowany z użyciem Bootstrap, co zapewnia responsywny i estetyczny wygląd. Po wprowadzeniu danych użytkownik klika przycisk "Zaloguj się", który jest dezaktywowany podczas ładowania.
import { useState } from "react";
import axios from "axios";
import { jwtDecode } from "jwt-decode"; // Poprawiony import
const Login = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [token, setToken] = useState("");
const [userToken, setUserToken] = useState(""); // Przechowywanie wartości UserToken
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const handleLogin = async (e) => {
e.preventDefault();
setError("");
setLoading(true);
setToken("");
setUserToken("");
try {
const response = await axios.post(
"https://localhost:7106/api/Users/login",
{
email,
password,
}
);
const { token } = response.data;
localStorage.setItem("token", token); // Zapisz token w localStorage
setToken(token); // Ustaw token w stanie komponentu
const decoded = jwtDecode(token);
console.log(decoded);
// Dekodowanie JWT i wyciągnięcie UserToken
const decodedToken = jwtDecode(token);
setUserToken(decodedToken.UserToken); // Ustawienie UserToken w stanie komponentu
setLoading(false);
} catch {
setLoading(false);
setError("Nieprawidłowy email lub hasło.");
}
};
return (
<div className="container mt-5">
<div className="row justify-content-center">
<div className="col-md-6">
<div className="card">
<div className="card-body">
<h4 className="card-title text-center">Logowanie</h4>
{error && <div className="alert alert-danger">{error}</div>}
{token && (
<div className="alert alert-success">Token: {token}</div>
)}
{userToken && (
<div className="alert alert-info">UserToken: {userToken}</div>
)}
<form onSubmit={handleLogin}>
<div className="mb-3">
<label htmlFor="email" className="form-label">
Email
</label>
<input
type="email"
className="form-control"
id="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
</div>
<div className="mb-3">
<label htmlFor="password" className="form-label">
Hasło
</label>
<input
type="password"
className="form-control"
id="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
/>
</div>
<button
type="submit"
className="btn btn-primary w-100"
disabled={loading}
>
{loading ? "Logowanie..." : "Zaloguj się"}
</button>
</form>
</div>
</div>
</div>
</div>
</div>
);
};
export default Login;
Ten skrypt definiuje komponent React o nazwie
Register
, który tworzy formularz rejestracji użytkownika. Formularz pozwala użytkownikowi na wprowadzenie nazwy użytkownika, adresu e-mail oraz hasła, a następnie przesyła te dane do serwera w celu rejestracji.Szczegółowe działanie skryptu:
- Inicjalizacja stanu komponentu:
userName
: Przechowuje nazwę użytkownika wprowadzoną w formularzu.password
: Przechowuje hasło wprowadzone przez użytkownika.email
: Przechowuje adres e-mail wprowadzony przez użytkownika.message
: Przechowuje komunikat zwrotny po udanej rejestracji, np. "User registered successfully".error
: Przechowuje komunikat o błędzie, jeśli rejestracja się nie powiedzie.loading
: Wskazuje, czy proces rejestracji jest w toku.
- Obsługa zdarzenia rejestracji:
handleRegister
: Funkcja, która jest wywoływana po przesłaniu formularza.- Najpierw resetuje komunikaty (
message
,error
) i ustawia stanloading
natrue
, co wskazuje na rozpoczęcie procesu rejestracji. - Wysyła zapytanie POST do API pod adresem
https://localhost:7106/api/Users/register
z danymi użytkownika (userName
,password
,email
). - Jeśli rejestracja się powiedzie, ustawia komunikat sukcesu w stanie
message
i wyłączaloading
. - Jeśli wystąpi błąd (np. serwer zwróci błąd lub zapytanie nie powiedzie się), zapisuje komunikat o błędzie w stanie
error
i wyłączaloading
.
- Najpierw resetuje komunikaty (
- Renderowanie formularza:
- Formularz jest wyświetlany z trzema polami do wprowadzenia danych: nazwa użytkownika, adres e-mail i hasło.
- Pod formularzem znajduje się przycisk „Zarejestruj się”, który jest dezaktywowany w trakcie procesu rejestracji (
loading
). - Jeśli proces rejestracji się powiedzie, wyświetlany jest komunikat o sukcesie. Jeśli wystąpi błąd, wyświetlany jest odpowiedni komunikat o błędzie.
- Stylizacja:
- Komponent jest stylizowany przy użyciu Bootstrap. Formularz jest wyśrodkowany, a komunikaty sukcesu i błędu są wyświetlane w odpowiednich alertach (zielony dla sukcesu, czerwony dla błędu).
import { useState } from 'react';
import axios from 'axios';
const Register = () => {
const [userName, setUserName] = useState('');
const [password, setPassword] = useState('');
const [email, setEmail] = useState('');
const [message, setMessage] = useState('');
const [error, setError] = useState('');
const [loading, setLoading] = useState(false);
const handleRegister = async (e) => {
e.preventDefault();
setMessage('');
setError('');
setLoading(true);
try {
const response = await axios.post('https://localhost:7106/api/Users/register', {
userName,
password,
email
});
// Oczekiwany format odpowiedzi: { "message": "User registered successfully" }
setMessage(response.data.message);
setLoading(false);
} catch (err) {
setLoading(false);
setError(err.response?.data?.message || 'Rejestracja nie powiodła się.');
}
};
return (
<div className="container mt-5">
<div className="row justify-content-center">
<div className="col-md-6">
<div className="card">
<div className="card-body">
<h4 className="card-title text-center">Rejestracja</h4>
{message && <div className="alert alert-success">{message}</div>}
{error && <div className="alert alert-danger">{error}</div>}
<form onSubmit={handleRegister}>
<div className="mb-3">
<label htmlFor="userName" className="form-label">Nazwa użytkownika</label>
<input
type="text"
className="form-control"
id="userName"
value={userName}
onChange={(e) => setUserName(e.target.value)}
required
/>
</div>
<div className="mb-3">
<label htmlFor="email" className="form-label">Email</label>
<input
type="email"
className="form-control"
id="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
</div>
<div className="mb-3">
<label htmlFor="password" className="form-label">Hasło</label>
<input
type="password"
className="form-control"
id="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
/>
</div>
<button type="submit" className="btn btn-primary w-100" disabled={loading}>
{loading ? 'Rejestracja...' : 'Zarejestruj się'}
</button>
</form>
</div>
</div>
</div>
</div>
</div>
);
};
export default Register;