Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
6a0bb623fc |
|||
|
30ec2ec0e8 |
8 changed files with 195 additions and 19 deletions
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
137
resources/css/admin-tokens.css
Normal file
137
resources/css/admin-tokens.css
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
@layer components {
|
||||
.token-list-wrapper {
|
||||
margin-block-start: 1em;
|
||||
border: 1px solid var(--clr-border);
|
||||
border-radius: 16px;
|
||||
overflow: auto hidden;
|
||||
background: light-dark(
|
||||
oklch(99% 0.02 var(--primary-hue)),
|
||||
oklch(22% 0.05 var(--primary-hue))
|
||||
);
|
||||
}
|
||||
|
||||
.token-list {
|
||||
width: 100%;
|
||||
min-width: 640px;
|
||||
table-layout: fixed;
|
||||
border-collapse: collapse;
|
||||
|
||||
th,
|
||||
td {
|
||||
text-align: left;
|
||||
padding: 0.9em 1.2em;
|
||||
border-bottom: 1px solid var(--clr-border);
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
th {
|
||||
font-size: 0.8em;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
tr.is-revoked {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
a {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
th:nth-child(1),
|
||||
td:nth-child(1) {
|
||||
width: 31%;
|
||||
}
|
||||
|
||||
th:nth-child(2),
|
||||
td:nth-child(2) {
|
||||
width: 24%;
|
||||
}
|
||||
|
||||
th:nth-child(3),
|
||||
td:nth-child(3) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
th:nth-child(4),
|
||||
td:nth-child(4) {
|
||||
width: 16%;
|
||||
}
|
||||
|
||||
th:nth-child(5),
|
||||
td:nth-child(5) {
|
||||
width: 14%;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
.scope-chips {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.4em;
|
||||
}
|
||||
|
||||
.scope-chip {
|
||||
display: inline-block;
|
||||
padding: 0.2em 0.7em;
|
||||
border-radius: 999px;
|
||||
background: light-dark(
|
||||
oklch(92% 0.05 var(--primary-hue)),
|
||||
oklch(35% 0.08 var(--primary-hue))
|
||||
);
|
||||
font-size: 0.85em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.badge,
|
||||
.token-list button.revoke {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.4em;
|
||||
padding: 0.3em 0.8em;
|
||||
border-radius: 999px;
|
||||
font-size: 0.85em;
|
||||
font-weight: 600;
|
||||
line-height: 1.5;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.badge {
|
||||
background: transparent;
|
||||
border: 1px solid currentcolor;
|
||||
}
|
||||
|
||||
.badge-active {
|
||||
color: light-dark(oklch(35% 0.16 145deg), oklch(75% 0.16 145deg));
|
||||
|
||||
.dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: currentcolor;
|
||||
}
|
||||
}
|
||||
|
||||
.badge-revoked {
|
||||
color: var(--clr-text);
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.token-list button.revoke {
|
||||
background: light-dark(oklch(92% 0.15 25deg), oklch(30% 0.12 25deg));
|
||||
color: light-dark(oklch(30% 0.15 25deg), oklch(92% 0.12 25deg));
|
||||
border: 1px solid transparent;
|
||||
cursor: pointer;
|
||||
transition: background-color 150ms ease;
|
||||
}
|
||||
|
||||
.token-list button.revoke:hover {
|
||||
background: light-dark(oklch(80% 0.2 25deg), oklch(45% 0.18 25deg));
|
||||
}
|
||||
}
|
||||
|
|
@ -8,3 +8,4 @@
|
|||
@import url('notes.css');
|
||||
@import url('pagination.css');
|
||||
@import url('theme-selector.css');
|
||||
@import url('admin-tokens.css');
|
||||
|
|
|
|||
|
|
@ -18,7 +18,17 @@
|
|||
}
|
||||
|
||||
> main {
|
||||
grid-column: 2/3;
|
||||
grid-column: 1/-1;
|
||||
display: grid;
|
||||
grid-template-columns: subgrid;
|
||||
|
||||
> * {
|
||||
grid-column: 2/3;
|
||||
}
|
||||
|
||||
> .full-bleed {
|
||||
grid-column: 1/-1;
|
||||
}
|
||||
}
|
||||
|
||||
> footer {
|
||||
|
|
|
|||
|
|
@ -7,21 +7,49 @@
|
|||
@if($tokens->isEmpty())
|
||||
<p>No tokens have been issued.</p>
|
||||
@else
|
||||
<ul>
|
||||
@foreach($tokens as $token)
|
||||
<li>
|
||||
{{ $token->client_id }} — scope: {{ $token->scope }} — issued {{ $token->created_at->diffForHumans() }}
|
||||
@if($token->isRevoked)
|
||||
— revoked {{ $token->revoked_at->diffForHumans() }}
|
||||
@else
|
||||
<form action="/admin/tokens/{{ $token->id }}/revoke" method="post">
|
||||
{{ csrf_field() }}
|
||||
{{ method_field('PUT') }}
|
||||
<button type="submit" name="revoke">Revoke</button>
|
||||
</form>
|
||||
@endif
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
<div class="full-bleed token-list-wrapper">
|
||||
<table class="token-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Client</th>
|
||||
<th scope="col">Scope</th>
|
||||
<th scope="col">Issued</th>
|
||||
<th scope="col">Status</th>
|
||||
<th scope="col">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($tokens as $token)
|
||||
<tr class="{{ $token->isRevoked ? 'is-revoked' : '' }}">
|
||||
<td><a href="{{ $token->client_id }}" rel="noopener">{{ $token->client_id }}</a></td>
|
||||
<td>
|
||||
<span class="scope-chips">
|
||||
@foreach(explode(' ', $token->scope) as $scope)
|
||||
<span class="scope-chip">{{ $scope }}</span>
|
||||
@endforeach
|
||||
</span>
|
||||
</td>
|
||||
<td><time datetime="{{ $token->created_at->toIso8601String() }}" title="{{ $token->created_at }}">{{ $token->created_at->diffForHumans() }}</time></td>
|
||||
<td>
|
||||
@if($token->isRevoked)
|
||||
<span class="badge badge-revoked">Revoked {{ $token->revoked_at->diffForHumans() }}</span>
|
||||
@else
|
||||
<span class="badge badge-active"><span class="dot"></span>Active</span>
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
@unless($token->isRevoked)
|
||||
<form action="/admin/tokens/{{ $token->id }}/revoke" method="post" onsubmit="return confirm('Revoke this token? This cannot be undone.')">
|
||||
{{ csrf_field() }}
|
||||
{{ method_field('PUT') }}
|
||||
<button type="submit" class="revoke" name="revoke">Revoke</button>
|
||||
</form>
|
||||
@endunless
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@endif
|
||||
@stop
|
||||
|
|
|
|||
Loading…
Reference in a new issue