mirror of
https://github.com/farcasclaudiu/learn-build-apps-copilot-agent.git
synced 2026-06-22 05:01:34 +03:00
feat: refactor API base URL handling and update frontend components for improved data structure
This commit is contained in:
@@ -3,10 +3,10 @@
|
||||
# Copy this file to .env.local and fill in your values.
|
||||
# .env.local is gitignored and never committed.
|
||||
#
|
||||
# VITE_CODESPACE_NAME is required when running inside a GitHub Codespace.
|
||||
# It is used to build the backend API base URL:
|
||||
# https://${VITE_CODESPACE_NAME}-8000.app.github.dev/api
|
||||
# VITE_CODESPACE_NAME can be used to explicitly point at the backend API.
|
||||
# When running inside a GitHub Codespace, the frontend will also auto-detect
|
||||
# the backend host from the current app.github.dev URL.
|
||||
#
|
||||
# If unset, the frontend falls back to http://localhost:8000/api.
|
||||
# If unset outside Codespaces, the frontend falls back to http://localhost:8000/api.
|
||||
|
||||
VITE_CODESPACE_NAME=your-codespace-name-here
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
const codespaceName = import.meta.env.VITE_CODESPACE_NAME
|
||||
const API_BASE = codespaceName
|
||||
? `https://${codespaceName}-8000.app.github.dev/api`
|
||||
: 'http://localhost:8000/api'
|
||||
import { API_BASE } from '../lib/apiBase'
|
||||
|
||||
function Activities() {
|
||||
const [activities, setActivities] = useState([])
|
||||
@@ -17,7 +13,7 @@ function Activities() {
|
||||
return res.json()
|
||||
})
|
||||
.then((data) => {
|
||||
setActivities(Array.isArray(data) ? data : (data.results ?? []))
|
||||
setActivities(Array.isArray(data) ? data : (data.items ?? data.results ?? []))
|
||||
setLoading(false)
|
||||
})
|
||||
.catch((err) => {
|
||||
@@ -36,18 +32,22 @@ function Activities() {
|
||||
<thead>
|
||||
<tr>
|
||||
<th>User</th>
|
||||
<th>Team</th>
|
||||
<th>Type</th>
|
||||
<th>Duration (min)</th>
|
||||
<th>Date</th>
|
||||
<th>Calories</th>
|
||||
<th>Completed</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{activities.map((activity) => (
|
||||
<tr key={activity._id ?? activity.id}>
|
||||
<td>{activity.user}</td>
|
||||
<td>{activity.activity_type}</td>
|
||||
<td>{activity.duration}</td>
|
||||
<td>{activity.date}</td>
|
||||
<td>{activity.user?.username ?? activity.user}</td>
|
||||
<td>{activity.team?.name ?? activity.team}</td>
|
||||
<td>{activity.type}</td>
|
||||
<td>{activity.durationMinutes}</td>
|
||||
<td>{activity.caloriesBurned}</td>
|
||||
<td>{activity.completedAt ? new Date(activity.completedAt).toLocaleString() : ''}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
const codespaceName = import.meta.env.VITE_CODESPACE_NAME
|
||||
const API_BASE = codespaceName
|
||||
? `https://${codespaceName}-8000.app.github.dev/api`
|
||||
: 'http://localhost:8000/api'
|
||||
import { API_BASE } from '../lib/apiBase'
|
||||
|
||||
function Leaderboard() {
|
||||
const [entries, setEntries] = useState([])
|
||||
const [leaderboards, setLeaderboards] = useState([])
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [error, setError] = useState(null)
|
||||
|
||||
@@ -17,7 +13,7 @@ function Leaderboard() {
|
||||
return res.json()
|
||||
})
|
||||
.then((data) => {
|
||||
setEntries(Array.isArray(data) ? data : (data.results ?? []))
|
||||
setLeaderboards(Array.isArray(data) ? data : (data.items ?? data.results ?? []))
|
||||
setLoading(false)
|
||||
})
|
||||
.catch((err) => {
|
||||
@@ -35,22 +31,26 @@ function Leaderboard() {
|
||||
<table className="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Period</th>
|
||||
<th>Rank</th>
|
||||
<th>User</th>
|
||||
<th>Score</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{entries.map((entry, index) => (
|
||||
<tr key={entry._id ?? entry.id}>
|
||||
<td>{index + 1}</td>
|
||||
<td>{entry.user}</td>
|
||||
<td>{entry.score}</td>
|
||||
</tr>
|
||||
))}
|
||||
{leaderboards.flatMap((leaderboard) =>
|
||||
leaderboard.entries.map((entry) => (
|
||||
<tr key={`${leaderboard._id ?? leaderboard.id}-${entry.rank}-${entry.user?._id ?? entry.user?.id ?? entry.user}`}>
|
||||
<td>{leaderboard.period}</td>
|
||||
<td>{entry.rank}</td>
|
||||
<td>{entry.user?.username ?? entry.user}</td>
|
||||
<td>{entry.points}</td>
|
||||
</tr>
|
||||
)),
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
{entries.length === 0 && <p>No leaderboard entries found.</p>}
|
||||
{leaderboards.length === 0 && <p>No leaderboard entries found.</p>}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
const codespaceName = import.meta.env.VITE_CODESPACE_NAME
|
||||
const API_BASE = codespaceName
|
||||
? `https://${codespaceName}-8000.app.github.dev/api`
|
||||
: 'http://localhost:8000/api'
|
||||
import { API_BASE } from '../lib/apiBase'
|
||||
|
||||
function Teams() {
|
||||
const [teams, setTeams] = useState([])
|
||||
@@ -17,7 +13,7 @@ function Teams() {
|
||||
return res.json()
|
||||
})
|
||||
.then((data) => {
|
||||
setTeams(Array.isArray(data) ? data : (data.results ?? []))
|
||||
setTeams(Array.isArray(data) ? data : (data.items ?? data.results ?? []))
|
||||
setLoading(false)
|
||||
})
|
||||
.catch((err) => {
|
||||
@@ -36,6 +32,7 @@ function Teams() {
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Captain</th>
|
||||
<th>Members</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -43,7 +40,12 @@ function Teams() {
|
||||
{teams.map((team) => (
|
||||
<tr key={team._id ?? team.id}>
|
||||
<td>{team.name}</td>
|
||||
<td>{Array.isArray(team.members) ? team.members.join(', ') : team.members}</td>
|
||||
<td>{team.captain?.username ?? team.captain}</td>
|
||||
<td>
|
||||
{Array.isArray(team.members)
|
||||
? team.members.map((member) => member?.username ?? member).join(', ')
|
||||
: team.members}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
const codespaceName = import.meta.env.VITE_CODESPACE_NAME
|
||||
const API_BASE = codespaceName
|
||||
? `https://${codespaceName}-8000.app.github.dev/api`
|
||||
: 'http://localhost:8000/api'
|
||||
import { API_BASE } from '../lib/apiBase'
|
||||
|
||||
function Users() {
|
||||
const [users, setUsers] = useState([])
|
||||
@@ -17,7 +13,7 @@ function Users() {
|
||||
return res.json()
|
||||
})
|
||||
.then((data) => {
|
||||
setUsers(Array.isArray(data) ? data : (data.results ?? []))
|
||||
setUsers(Array.isArray(data) ? data : (data.items ?? data.results ?? []))
|
||||
setLoading(false)
|
||||
})
|
||||
.catch((err) => {
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
const codespaceName = import.meta.env.VITE_CODESPACE_NAME
|
||||
const API_BASE = codespaceName
|
||||
? `https://${codespaceName}-8000.app.github.dev/api`
|
||||
: 'http://localhost:8000/api'
|
||||
import { API_BASE } from '../lib/apiBase'
|
||||
|
||||
function Workouts() {
|
||||
const [workouts, setWorkouts] = useState([])
|
||||
@@ -17,7 +13,7 @@ function Workouts() {
|
||||
return res.json()
|
||||
})
|
||||
.then((data) => {
|
||||
setWorkouts(Array.isArray(data) ? data : (data.results ?? []))
|
||||
setWorkouts(Array.isArray(data) ? data : (data.items ?? data.results ?? []))
|
||||
setLoading(false)
|
||||
})
|
||||
.catch((err) => {
|
||||
@@ -35,15 +31,19 @@ function Workouts() {
|
||||
<table className="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
<th>Title</th>
|
||||
<th>Category</th>
|
||||
<th>Difficulty</th>
|
||||
<th>Duration (min)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{workouts.map((workout) => (
|
||||
<tr key={workout._id ?? workout.id}>
|
||||
<td>{workout.name}</td>
|
||||
<td>{workout.description}</td>
|
||||
<td>{workout.title}</td>
|
||||
<td>{workout.category}</td>
|
||||
<td>{workout.difficulty}</td>
|
||||
<td>{workout.durationMinutes}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
const codespaceName = import.meta.env.VITE_CODESPACE_NAME
|
||||
const browserHost = typeof window !== 'undefined' ? window.location.hostname : ''
|
||||
const isDevelopment = import.meta.env.DEV
|
||||
|
||||
const derivedCodespaceHost = browserHost.endsWith('.app.github.dev')
|
||||
? browserHost.replace(/-\d+\.app\.github\.dev$/, '-8000.app.github.dev')
|
||||
: ''
|
||||
|
||||
export const API_BASE = isDevelopment
|
||||
? '/api'
|
||||
: codespaceName
|
||||
? `https://${codespaceName}-8000.app.github.dev/api`
|
||||
: derivedCodespaceHost
|
||||
? `https://${derivedCodespaceHost}/api`
|
||||
: 'http://localhost:8000/api'
|
||||
@@ -5,6 +5,12 @@ import react from '@vitejs/plugin-react'
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
server: {
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://127.0.0.1:8000',
|
||||
changeOrigin: true,
|
||||
},
|
||||
},
|
||||
port: 5173,
|
||||
strictPort: true,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user