133 lines
6.3 KiB
HTML
133 lines
6.3 KiB
HTML
{{template "base" .}}
|
||
|
||
{{define "content"}}
|
||
<h1 class="mb-4"><i class="bi bi-key me-2" aria-hidden="true"></i>APIキー管理</h1>
|
||
|
||
{{if .error}}<div class="alert alert-danger" role="alert">{{.error}}</div>{{end}}
|
||
|
||
{{if .newKey}}
|
||
<div class="alert alert-success" role="status">
|
||
<h5 class="alert-heading"><i class="bi bi-check-circle me-2" aria-hidden="true"></i>APIキーが作成されました</h5>
|
||
<p class="mb-2">キー名: <strong>{{.newKeyName}}</strong></p>
|
||
<p class="mb-0">以下のキーを安全な場所に保存してください。このキーは二度と表示されません。</p>
|
||
<hr>
|
||
<div class="d-flex align-items-center">
|
||
<code class="flex-grow-1 bg-dark text-light p-2 rounded me-2" id="newApiKey" aria-label="APIキー">{{.newKey}}</code>
|
||
<button class="btn btn-outline-secondary" id="copyKeyBtn" aria-label="APIキーをコピー">
|
||
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
{{end}}
|
||
|
||
<div class="card mb-4">
|
||
<div class="card-header">
|
||
<i class="bi bi-plus-circle me-2" aria-hidden="true"></i>新規APIキー作成
|
||
</div>
|
||
<div class="card-body">
|
||
<form action="/admin/api-keys" method="POST" class="row g-3">
|
||
{{.csrfField}}
|
||
<div class="col-md-8">
|
||
<label for="keyName" class="visually-hidden">キー名</label>
|
||
<input type="text" class="form-control" id="keyName" name="name" placeholder="キー名(例: 外部連携用)" required>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<button type="submit" class="btn btn-primary w-100"><i class="bi bi-plus me-1" aria-hidden="true"></i>作成</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
{{if .apiKeys}}
|
||
<div class="table-responsive">
|
||
<table class="table table-hover" aria-label="APIキー一覧">
|
||
<thead class="table-light">
|
||
<tr>
|
||
<th scope="col">ID</th>
|
||
<th scope="col">キー名</th>
|
||
<th scope="col">作成者</th>
|
||
<th scope="col">最終使用</th>
|
||
<th scope="col">作成日</th>
|
||
<th scope="col" style="width: 100px">操作</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{{range .apiKeys}}
|
||
<tr>
|
||
<td>{{.ID}}</td>
|
||
<td><i class="bi bi-key me-1" aria-hidden="true"></i>{{.Name}}</td>
|
||
<td>{{if .User}}{{.User.Name}}{{else}}-{{end}}</td>
|
||
<td>{{if .LastUsed}}{{formatDateTime .LastUsed}}{{else}}<span class="text-muted">未使用</span>{{end}}</td>
|
||
<td>{{formatDate .CreatedAt}}</td>
|
||
<td>
|
||
<form action="/admin/api-keys/{{.ID}}/delete" method="POST" class="d-inline"
|
||
data-confirm="このAPIキーを削除しますか?">
|
||
<input type="hidden" name="_csrf" value="{{$.csrfToken}}">
|
||
<button type="submit" class="btn btn-sm btn-outline-danger" aria-label="{{.Name}}を削除">
|
||
<i class="bi bi-trash" aria-hidden="true"></i>
|
||
</button>
|
||
</form>
|
||
</td>
|
||
</tr>
|
||
{{end}}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
{{else}}
|
||
<div class="text-center py-5">
|
||
<i class="bi bi-key display-1 text-muted" aria-hidden="true"></i>
|
||
<h3 class="mt-3">APIキーがありません</h3>
|
||
<p class="text-muted">上のフォームから新しいAPIキーを作成してください。</p>
|
||
</div>
|
||
{{end}}
|
||
|
||
<div class="card mt-4">
|
||
<div class="card-header">
|
||
<i class="bi bi-info-circle me-2" aria-hidden="true"></i>API使用方法
|
||
</div>
|
||
<div class="card-body">
|
||
<p class="mb-2">APIにアクセスするには、<code>Authorization</code>ヘッダーにAPIキーを設定してください:</p>
|
||
<pre class="bg-dark text-light p-3 rounded"><code>curl -H "Authorization: Bearer YOUR_API_KEY" http://localhost:8080/api/v1/assignments</code></pre>
|
||
<h6 class="mt-3">利用可能なエンドポイント:</h6>
|
||
<ul class="mb-0">
|
||
<li><code>GET /api/v1/assignments</code> - 課題一覧取得</li>
|
||
<li><code>GET /api/v1/assignments/pending</code> - 未完了の課題一覧</li>
|
||
<li><code>GET /api/v1/assignments/completed</code> - 完了済みの課題一覧</li>
|
||
<li><code>GET /api/v1/assignments/overdue</code> - 期限切れの課題一覧</li>
|
||
<li><code>GET /api/v1/assignments/due-today</code> - 今日が期限の課題一覧</li>
|
||
<li><code>GET /api/v1/assignments/due-this-week</code> - 今週中が期限の課題一覧</li>
|
||
<li><code>GET /api/v1/assignments/:id</code> - 課題詳細取得</li>
|
||
<li><code>POST /api/v1/assignments</code> - 課題作成</li>
|
||
<li><code>PUT /api/v1/assignments/:id</code> - 課題更新</li>
|
||
<li><code>DELETE /api/v1/assignments/:id</code> - 課題削除</li>
|
||
<li><code>PATCH /api/v1/assignments/:id/toggle</code> - 完了状態切替</li>
|
||
<li><code>GET /api/v1/statistics</code> - 統計情報取得</li>
|
||
<li><code>GET /api/v1/recurring</code> - 繰り返し設定一覧取得</li>
|
||
<li><code>GET /api/v1/recurring/:id</code> - 繰り返し設定詳細取得</li>
|
||
<li><code>PUT /api/v1/recurring/:id</code> - 繰り返し設定更新</li>
|
||
<li><code>DELETE /api/v1/recurring/:id</code> - 繰り返し設定削除</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
{{end}}
|
||
|
||
{{define "scripts"}}
|
||
<script>
|
||
var copyKeyBtn = document.getElementById('copyKeyBtn');
|
||
if (copyKeyBtn) {
|
||
copyKeyBtn.addEventListener('click', function() {
|
||
var key = document.getElementById('newApiKey').textContent.trim();
|
||
if (!navigator.clipboard) {
|
||
showCopyFeedback('クリップボードがサポートされていません。手動でコピーしてください。');
|
||
return;
|
||
}
|
||
navigator.clipboard.writeText(key).then(function() {
|
||
showCopyFeedback('APIキーをコピーしました');
|
||
}).catch(function(err) {
|
||
showCopyFeedback('コピーに失敗しました: ' + (err.message || '不明なエラー'));
|
||
});
|
||
});
|
||
}
|
||
</script>
|
||
{{end}}
|