Feature #99 + BugFixes
This commit is contained in:
156
bizmatch/src/app/pages/admin/user-list/user-list.component.html
Normal file
156
bizmatch/src/app/pages/admin/user-list/user-list.component.html
Normal file
@@ -0,0 +1,156 @@
|
||||
<!-- src/app/components/user-list/user-list.component.html -->
|
||||
<div class="container mx-auto p-4">
|
||||
<h1 class="text-2xl font-bold mb-4">Benutzerverwaltung</h1>
|
||||
|
||||
<!-- Ladeanzeige -->
|
||||
<div *ngIf="isLoading" class="flex justify-center">
|
||||
<div class="animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-blue-500"></div>
|
||||
</div>
|
||||
|
||||
<!-- Fehlermeldung -->
|
||||
<div *ngIf="error" class="text-red-500 mb-4">
|
||||
{{ error }}
|
||||
</div>
|
||||
|
||||
<!-- Benutzer-Tabelle -->
|
||||
<table *ngIf="!isLoading && !error" class="min-w-full bg-white border">
|
||||
<thead>
|
||||
<tr>
|
||||
<!-- <th class="py-2 px-4 border-b">ID</th> -->
|
||||
<th class="py-2 px-4 border-b">Vorname</th>
|
||||
<th class="py-2 px-4 border-b">Nachname</th>
|
||||
<th class="py-2 px-4 border-b">E-Mail</th>
|
||||
<th class="py-2 px-4 border-b">DB</th>
|
||||
<th class="py-2 px-4 border-b">Keycloak</th>
|
||||
<th class="py-2 px-4 border-b">Stripe</th>
|
||||
<th class="py-2 px-4 border-b">Sub</th>
|
||||
<th class="py-2 px-4 border-b">Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let user of combinedUsers; let i = index" class="text-center">
|
||||
<td class="py-2 px-4 border-b">
|
||||
{{ user.appUser?.firstname || user.keycloakUser?.firstName || user.stripeUser?.name || '—' }}
|
||||
</td>
|
||||
<td class="py-2 px-4 border-b">
|
||||
{{ user.appUser?.lastname || user.keycloakUser?.lastName || '—' }}
|
||||
</td>
|
||||
<td class="py-2 px-4 border-b">
|
||||
{{ user.appUser?.email || user.keycloakUser?.email || user.stripeUser?.email }}
|
||||
</td>
|
||||
<td class="py-2 px-4 border-b">
|
||||
<input type="checkbox" [checked]="!!user.appUser" disabled />
|
||||
</td>
|
||||
<td class="py-2 px-4 border-b">
|
||||
<input type="checkbox" [checked]="!!user.keycloakUser" disabled />
|
||||
</td>
|
||||
<td class="py-2 px-4 border-b">
|
||||
<input type="checkbox" [checked]="!!user.stripeUser" disabled />
|
||||
</td>
|
||||
<td class="py-2 px-4 border-b">
|
||||
@if(!!user.stripeSubscription){
|
||||
<input type="checkbox" [checked]="!!user.stripeSubscription" disabled attr.data-tooltip-target="tooltip-{{ i }}" />
|
||||
}@else {
|
||||
<input type="checkbox" [checked]="!!user.stripeSubscription" disabled />
|
||||
} @if(!!user.stripeSubscription){
|
||||
<app-tooltip id="tooltip-{{ i }}" [text]="getSubscriptionInfo(user.stripeSubscription)"></app-tooltip>
|
||||
}
|
||||
</td>
|
||||
<td class="py-2 px-4 border-b space-x-2">
|
||||
<button class="share share-delete text-white font-bold text-xs py-1 px-2 inline-flex items-center" attr.data-dropdown-toggle="dropdown_{{ user.appUser?.id }}">
|
||||
Delete<svg class="w-2.5 h-2.5 ms-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6">
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 4 4 4-4" />
|
||||
</svg>
|
||||
</button>
|
||||
<!-- Dropdown menu -->
|
||||
<div id="dropdown_{{ user.appUser?.id }}" class="z-10 hidden bg-white divide-y divide-gray-100 rounded-lg shadow w-44">
|
||||
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200" aria-labelledby="dropdownDefaultButton">
|
||||
<li>
|
||||
<a class="block px-4 py-2 hover:bg-gray-100" (click)="delete(user)">Complete</a>
|
||||
</li>
|
||||
@if(user.stripeSubscription){
|
||||
<li>
|
||||
<a class="block px-4 py-2 hover:bg-gray-100" (click)="deleteFromStripe(user)">From Stripe</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
<button class="share share-cc text-white font-bold text-xs py-1 px-2 inline-flex items-center" (click)="showCreditCardInfo(user)" [disabled]="!user.stripeSubscription">
|
||||
<i class="fa-solid fa-credit-card"></i> CC Info
|
||||
</button>
|
||||
<button class="share share-msg text-white font-bold text-xs py-1 px-2 inline-flex items-center" (click)="showMessages(user)"><i class="fa-solid fa-message"></i> Messages</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- Flowbite Modal für Kreditkarteninformationen -->
|
||||
<div *ngIf="showModal" class="fixed top-0 left-0 right-0 z-50 flex items-center justify-center w-full p-4 overflow-x-hidden overflow-y-auto md:inset-0 h-modal md:h-full" aria-modal="true" role="dialog">
|
||||
<div class="relative w-full max-w-2xl max-h-full">
|
||||
<!-- Modal-Content -->
|
||||
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
|
||||
<!-- Modal-Kopf -->
|
||||
<div class="flex items-start justify-between p-4 border-b rounded-t dark:border-gray-600">
|
||||
<h3 class="text-xl font-semibold text-gray-900 dark:text-white">Kreditkarteninformationen</h3>
|
||||
<button
|
||||
type="button"
|
||||
class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm p-1.5 ml-auto inline-flex items-center dark:hover:bg-gray-600 dark:hover:text-white"
|
||||
(click)="closeModal()"
|
||||
>
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
|
||||
clip-rule="evenodd"
|
||||
></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Modal-Körper -->
|
||||
<div class="p-6 space-y-6">
|
||||
<div *ngIf="ccInfoLoading" class="flex justify-center">
|
||||
<div class="animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-blue-500"></div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="ccInfoError" class="text-red-500">
|
||||
{{ ccInfoError }}
|
||||
</div>
|
||||
|
||||
<div *ngIf="!ccInfoLoading && !ccInfoError">
|
||||
<ng-container *ngIf="creditCardInfo.length > 0; else noCCInfo">
|
||||
<table class="min-w-full bg-white border">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="py-2 px-4 border-b">Kartenmarke</th>
|
||||
<th class="py-2 px-4 border-b">Letzte 4</th>
|
||||
<th class="py-2 px-4 border-b">Ablaufdatum</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let method of creditCardInfo" class="text-center">
|
||||
<td class="py-2 px-4 border-b">{{ method.card?.brand || '—' }}</td>
|
||||
<td class="py-2 px-4 border-b">{{ method.card?.last4 || '—' }}</td>
|
||||
<td class="py-2 px-4 border-b">{{ method.card?.exp_month }}/{{ method.card?.exp_year }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</ng-container>
|
||||
<ng-template #noCCInfo>
|
||||
<p>Keine Kreditkarteninformationen verfügbar.</p>
|
||||
</ng-template>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Modal-Fuß -->
|
||||
<div class="flex items-center p-6 space-x-2 border-t border-gray-200 rounded-b dark:border-gray-600">
|
||||
<button
|
||||
type="button"
|
||||
class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
|
||||
(click)="closeModal()"
|
||||
>
|
||||
Schließen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user