Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# API接続先(開発時のプロキシ先)
VITE_API_TARGET="https://your-api-domain.com"
VITE_API_URL="https://your-api-domain.com"
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# AIE-DXプロジェクト1フロントエンド
# AIE-DXプロジェクト1フロントエンド

## 動かし方

Expand Down Expand Up @@ -33,7 +33,7 @@ cp .env.example .env
`.env`ファイルを編集して、バックエンドAPIのURLを指定してください。
```bash
# API接続先(開発時のプロキシ先)
VITE_API_TARGET="https://your-api-domain.com"
VITE_API_URL="https://your-api-domain.com"
```

### 5. 開発サーバーの起動
Expand Down
19 changes: 16 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { CourseDashboard } from './components/CourseDashboard';
import { DataUpload } from './components/DataUpload';
import { DataDelete } from './components/DataDelete';
import { Toaster } from './components/ui/sonner';
import { fetchCourses, ApiError } from './api/client';
import { fetchCourses, ApiError, logout } from './api/client';
import type { CourseItem } from './types/api';
import { Loader2, AlertCircle, RefreshCw } from 'lucide-react';
import { Button } from './components/ui/button';
Expand Down Expand Up @@ -77,13 +77,21 @@ export default function App() {
setViewMode('list');
};

const handleLogout = () => {
logout();
};

const showBackButton = viewMode === 'dashboard' || viewMode === 'upload' || viewMode === 'delete';

// ローディング表示
if (isLoading && viewMode === 'list') {
return (
<div className="min-h-screen bg-gray-50">
<Header showBackButton={false} onBackClick={handleBackToList} />
<Header
showBackButton={false}
onBackClick={handleBackToList}
onLogout={handleLogout}
/>
<div className="container mx-auto px-4 py-8">
<div className="flex flex-col items-center justify-center py-20">
<Loader2 className="h-12 w-12 animate-spin text-blue-600 mb-4" />
Expand All @@ -99,7 +107,11 @@ export default function App() {
if (error && viewMode === 'list') {
return (
<div className="min-h-screen bg-gray-50">
<Header showBackButton={false} onBackClick={handleBackToList} />
<Header
showBackButton={false}
onBackClick={handleBackToList}
onLogout={handleLogout}
/>
<div className="container mx-auto px-4 py-8">
<Card className="max-w-md mx-auto">
<CardContent className="py-8">
Expand All @@ -125,6 +137,7 @@ export default function App() {
<Header
showBackButton={showBackButton}
onBackClick={handleBackToList}
onLogout={handleLogout}
/>

{viewMode === 'dashboard' && selectedCourse ? (
Expand Down
14 changes: 12 additions & 2 deletions src/api/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ function redirectToLogin() {
if (isRedirectingToLogin) return;

// すでにログイン開始URLならループ防止
if (window.location.pathname === '/api/login') return;
if (window.location.pathname === `${BASE_URL}/login`) return;

isRedirectingToLogin = true;
window.location.href = '/api/login';
window.location.href = `${BASE_URL}/login`;
}

// 「認証切れ」と判断する条件
Expand Down Expand Up @@ -361,3 +361,13 @@ export async function fetchAttributes(): Promise<AttributesResponse> {
export async function fetchUserInfo(): Promise<UserInfoResponse> {
return fetchApi<UserInfoResponse>('/me');
}

// ===== 7. 認証API =====

/**
* ログアウト
* ログアウトエンドポイントへリダイレクト
*/
export function logout(): void {
window.location.href = `${BASE_URL}/logout`;
}
5 changes: 3 additions & 2 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import { Button } from './ui/button';
interface HeaderProps {
showBackButton?: boolean;
onBackClick?: () => void;
onLogout?: () => void;
}

export function Header({ showBackButton, onBackClick }: HeaderProps) {
export function Header({ showBackButton, onBackClick, onLogout }: HeaderProps) {
return (
<header className="border-b bg-white">
<div className="container mx-auto px-4 py-4 flex items-center justify-between">
Expand All @@ -26,7 +27,7 @@ export function Header({ showBackButton, onBackClick }: HeaderProps) {
<User className="h-5 w-5" />
<span>運営者</span>
</div>
<Button variant="ghost" size="sm">
<Button variant="ghost" size="sm" onClick={onLogout}>
<LogOut className="h-4 w-4 mr-2" />
ログアウト
</Button>
Expand Down
2 changes: 1 addition & 1 deletion vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import path from 'path';

export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), '');
const apiTarget = env.VITE_API_TARGET || 'http://localhost:8000';
const apiTarget = env.VITE_API_URL || 'http://localhost:8000';

return {
plugins: [react()],
Expand Down