Compare commits
4 Commits
4a539638f8
...
d5a8b16e43
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5a8b16e43 | ||
|
|
48e21736ea | ||
|
|
ab168311a9 | ||
|
|
54faee731d |
@@ -76,7 +76,7 @@ export function processUserFormData(rawData) {
|
|||||||
email: String(rawData.object.email),
|
email: String(rawData.object.email),
|
||||||
phone: String(rawData.object.phone || ''),
|
phone: String(rawData.object.phone || ''),
|
||||||
company: String(rawData.object.company || ''),
|
company: String(rawData.object.company || ''),
|
||||||
dateofbirth: toRFC3339(String(rawData.object.dateofbirth)),
|
dateofbirth: toRFC3339(String(rawData.object.dateofbirth || '')),
|
||||||
address: String(rawData.object.address || ''),
|
address: String(rawData.object.address || ''),
|
||||||
zip_code: String(rawData.object.zip_code || ''),
|
zip_code: String(rawData.object.zip_code || ''),
|
||||||
city: String(rawData.object.city || ''),
|
city: String(rawData.object.city || ''),
|
||||||
@@ -86,8 +86,8 @@ export function processUserFormData(rawData) {
|
|||||||
membership: {
|
membership: {
|
||||||
id: Number(rawData.object.membership?.id) || 0,
|
id: Number(rawData.object.membership?.id) || 0,
|
||||||
status: Number(rawData.object.membership?.status),
|
status: Number(rawData.object.membership?.status),
|
||||||
start_date: toRFC3339(String(rawData.object.membership?.start_date)),
|
start_date: toRFC3339(String(rawData.object.membership?.start_date || '')),
|
||||||
end_date: toRFC3339(String(rawData.object.membership?.end_date)),
|
end_date: toRFC3339(String(rawData.object.membership?.end_date || '')),
|
||||||
parent_member_id: Number(rawData.object.membership?.parent_member_id) || 0,
|
parent_member_id: Number(rawData.object.membership?.parent_member_id) || 0,
|
||||||
subscription_model: {
|
subscription_model: {
|
||||||
id: Number(rawData.object.membership?.subscription_model?.id) || 0,
|
id: Number(rawData.object.membership?.subscription_model?.id) || 0,
|
||||||
@@ -107,8 +107,8 @@ export function processUserFormData(rawData) {
|
|||||||
id: Number(rawData.object.licence?.id) || 0,
|
id: Number(rawData.object.licence?.id) || 0,
|
||||||
status: Number(rawData.object.licence?.status),
|
status: Number(rawData.object.licence?.status),
|
||||||
number: String(rawData.object.licence?.number || ''),
|
number: String(rawData.object.licence?.number || ''),
|
||||||
issued_date: toRFC3339(String(rawData.object.licence?.issued_date)),
|
issued_date: toRFC3339(String(rawData.object.licence?.issued_date || '')),
|
||||||
expiration_date: toRFC3339(String(rawData.object.licence?.expiration_date)),
|
expiration_date: toRFC3339(String(rawData.object.licence?.expiration_date || '')),
|
||||||
country: String(rawData.object.licence?.country || ''),
|
country: String(rawData.object.licence?.country || ''),
|
||||||
categories: rawData.object.licence?.categories || []
|
categories: rawData.object.licence?.categories || []
|
||||||
},
|
},
|
||||||
@@ -120,7 +120,9 @@ export function processUserFormData(rawData) {
|
|||||||
iban: String(rawData.object.bank_account?.iban || ''),
|
iban: String(rawData.object.bank_account?.iban || ''),
|
||||||
bic: String(rawData.object.bank_account?.bic || ''),
|
bic: String(rawData.object.bank_account?.bic || ''),
|
||||||
mandate_reference: String(rawData.object.bank_account?.mandate_reference || ''),
|
mandate_reference: String(rawData.object.bank_account?.mandate_reference || ''),
|
||||||
mandate_date_signed: toRFC3339(String(rawData.object.bank_account?.mandate_date_signed))
|
mandate_date_signed: toRFC3339(
|
||||||
|
String(rawData.object.bank_account?.mandate_date_signed || '')
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
import { BASE_API_URI } from "$lib/utils/constants";
|
|
||||||
import { refreshCookie } from "$lib/utils/helpers";
|
|
||||||
import { redirect } from "@sveltejs/kit";
|
|
||||||
/** @type {import('./$types').LayoutServerLoad} */
|
/** @type {import('./$types').LayoutServerLoad} */
|
||||||
export async function load({ locals, cookies }) {
|
export async function load({ locals }) {
|
||||||
return {
|
return {
|
||||||
user: locals.user,
|
user: locals.user,
|
||||||
licence_categories: locals.licence_categories,
|
licence_categories: locals.licence_categories,
|
||||||
subscriptions: locals.subscriptions,
|
subscriptions: locals.subscriptions
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export const actions = {
|
|||||||
console.log('Is creating: ', isCreating);
|
console.log('Is creating: ', isCreating);
|
||||||
// console.dir(formData);
|
// console.dir(formData);
|
||||||
console.dir(processedData.user.membership);
|
console.dir(processedData.user.membership);
|
||||||
const apiURL = `${BASE_API_URI}/backend/users/upsert/`;
|
const apiURL = `${BASE_API_URI}/backend/users/`;
|
||||||
|
|
||||||
/** @type {RequestInit} */
|
/** @type {RequestInit} */
|
||||||
const requestUpdateOptions = {
|
const requestUpdateOptions = {
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { userDatesFromRFC3339, refreshCookie } from '$lib/utils/helpers';
|
|||||||
export async function load({ cookies, fetch, locals }) {
|
export async function load({ cookies, fetch, locals }) {
|
||||||
const jwt = cookies.get('jwt');
|
const jwt = cookies.get('jwt');
|
||||||
try {
|
try {
|
||||||
// Fetch user data, subscriptions, and licence categories in parallel
|
|
||||||
const response = await fetch(`${BASE_API_URI}/backend/users/all`, {
|
const response = await fetch(`${BASE_API_URI}/backend/users/all`, {
|
||||||
credentials: 'include',
|
credentials: 'include',
|
||||||
headers: {
|
headers: {
|
||||||
@@ -16,7 +15,7 @@ export async function load({ cookies, fetch, locals }) {
|
|||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
// Clear the invalid JWT cookie
|
// Clear the invalid JWT cookie
|
||||||
cookies.delete('jwt', { path: '/' });
|
cookies.delete('jwt', { path: '/' });
|
||||||
throw redirect(302, '/auth/login?next=/');
|
throw redirect(302, '/auth/login?next=admin/users/');
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
@@ -43,6 +42,6 @@ export async function load({ cookies, fetch, locals }) {
|
|||||||
// In case of any error, clear the JWT cookie
|
// In case of any error, clear the JWT cookie
|
||||||
cookies.delete('jwt', { path: '/' });
|
cookies.delete('jwt', { path: '/' });
|
||||||
|
|
||||||
throw redirect(302, '/auth/login?next=/');
|
throw redirect(302, '/auth/login?next=admin/users/');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
export async function load({ locals }) {
|
export async function load({ locals }) {
|
||||||
// redirect user if not logged in
|
// redirect user if not logged in
|
||||||
if (!locals.user) {
|
if (!locals.user) {
|
||||||
throw redirect(302, `/auth/login?next=/auth/users`);
|
throw redirect(302, `/auth/login?next=/auth/admin/users`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ export const actions = {
|
|||||||
console.dir(processedData.user.membership);
|
console.dir(processedData.user.membership);
|
||||||
const isCreating = !processedData.user.id || processedData.user.id === 0;
|
const isCreating = !processedData.user.id || processedData.user.id === 0;
|
||||||
console.log('Is creating: ', isCreating);
|
console.log('Is creating: ', isCreating);
|
||||||
const apiURL = `${BASE_API_URI}/backend/users/upsert`;
|
const apiURL = `${BASE_API_URI}/backend/users`;
|
||||||
|
|
||||||
/** @type {RequestInit} */
|
/** @type {RequestInit} */
|
||||||
const requestOptions = {
|
const requestOptions = {
|
||||||
@@ -122,7 +122,7 @@ export const actions = {
|
|||||||
const rawData = formDataToObject(formData);
|
const rawData = formDataToObject(formData);
|
||||||
const processedData = processUserFormData(rawData);
|
const processedData = processUserFormData(rawData);
|
||||||
|
|
||||||
const apiURL = `${BASE_API_URI}/backend/users/delete`;
|
const apiURL = `${BASE_API_URI}/backend/users`;
|
||||||
|
|
||||||
/** @type {RequestInit} */
|
/** @type {RequestInit} */
|
||||||
const requestOptions = {
|
const requestOptions = {
|
||||||
|
|||||||
@@ -179,7 +179,6 @@
|
|||||||
backgroundColor="--base"
|
backgroundColor="--base"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<!-- <input type="text" bind:value={searchTerm} placeholder={$t('placeholder.search')} /> -->
|
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
class="btn primary"
|
class="btn primary"
|
||||||
@@ -201,7 +200,7 @@
|
|||||||
<details class="accordion-item">
|
<details class="accordion-item">
|
||||||
<summary class="accordion-header">
|
<summary class="accordion-header">
|
||||||
{user.first_name}
|
{user.first_name}
|
||||||
{user.last_name} - {user.email}
|
{user.last_name}
|
||||||
</summary>
|
</summary>
|
||||||
<div class="accordion-content">
|
<div class="accordion-content">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
@@ -218,6 +217,10 @@
|
|||||||
<th>{$t('user.email')}</th>
|
<th>{$t('user.email')}</th>
|
||||||
<td>{user.email}</td>
|
<td>{user.email}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>{$t('subscription.subscription')}</th>
|
||||||
|
<td>{user.membership?.subscription_model?.name}</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{$t('status')}</th>
|
<th>{$t('status')}</th>
|
||||||
<td>{$t('userStatus.' + user.status)}</td>
|
<td>{$t('userStatus.' + user.status)}</td>
|
||||||
@@ -281,6 +284,12 @@
|
|||||||
<details class="accordion-item">
|
<details class="accordion-item">
|
||||||
<summary class="accordion-header">
|
<summary class="accordion-header">
|
||||||
{subscription.name}
|
{subscription.name}
|
||||||
|
<span class="nav-badge"
|
||||||
|
>{users.filter(
|
||||||
|
(/** @type{App.Locals['user']}*/ user) =>
|
||||||
|
user.membership?.subscription_model?.name === subscription.name
|
||||||
|
).length}</span
|
||||||
|
>
|
||||||
</summary>
|
</summary>
|
||||||
<div class="accordion-content">
|
<div class="accordion-content">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
@@ -507,6 +516,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.accordion-header {
|
.accordion-header {
|
||||||
|
display: flex;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-family: 'Roboto Mono', monospace;
|
font-family: 'Roboto Mono', monospace;
|
||||||
@@ -586,7 +596,6 @@
|
|||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Style for the nav badge */
|
|
||||||
.nav-badge {
|
.nav-badge {
|
||||||
background: var(--surface2);
|
background: var(--surface2);
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
@@ -596,7 +605,6 @@
|
|||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Improved focus states */
|
|
||||||
.nav-link:focus,
|
.nav-link:focus,
|
||||||
.accordion-header:focus {
|
.accordion-header:focus {
|
||||||
outline: 2px solid var(--mauve);
|
outline: 2px solid var(--mauve);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { BASE_API_URI } from "$lib/utils/constants";
|
import { BASE_API_URI } from '$lib/utils/constants';
|
||||||
import { fail, redirect } from "@sveltejs/kit";
|
import { fail, redirect } from '@sveltejs/kit';
|
||||||
|
|
||||||
/** @type {import('./$types').PageServerLoad} */
|
/** @type {import('./$types').PageServerLoad} */
|
||||||
export async function load({ locals }) {
|
export async function load({ locals }) {
|
||||||
@@ -14,18 +14,15 @@ export const actions = {
|
|||||||
default: async ({ fetch, cookies }) => {
|
default: async ({ fetch, cookies }) => {
|
||||||
/** @type {RequestInit} */
|
/** @type {RequestInit} */
|
||||||
const requestInitOptions = {
|
const requestInitOptions = {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
credentials: "include",
|
credentials: 'include',
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
'Content-Type': 'application/json',
|
||||||
Cookie: `jwt=${cookies.get("jwt")}`,
|
Cookie: `jwt=${cookies.get('jwt')}`
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const res = await fetch(
|
const res = await fetch(`${BASE_API_URI}/backend/logout/`, requestInitOptions);
|
||||||
`${BASE_API_URI}/backend/users/logout/`,
|
|
||||||
requestInitOptions
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
const response = await res.json();
|
const response = await res.json();
|
||||||
@@ -35,23 +32,23 @@ export const actions = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// eat the cookie
|
// eat the cookie
|
||||||
cookies.delete("jwt", { path: "/" });
|
cookies.delete('jwt', { path: '/' });
|
||||||
|
|
||||||
// The server should clear the cookie, so we don't need to handle it here
|
// The server should clear the cookie, so we don't need to handle it here
|
||||||
// Just check if the cookie is cleared in the response
|
// Just check if the cookie is cleared in the response
|
||||||
const setCookieHeader = res.headers.get("set-cookie");
|
const setCookieHeader = res.headers.get('set-cookie');
|
||||||
if (!setCookieHeader || !setCookieHeader.includes("jwt=;")) {
|
if (!setCookieHeader || !setCookieHeader.includes('jwt=;')) {
|
||||||
console.error("JWT cookie not cleared in response");
|
console.error('JWT cookie not cleared in response');
|
||||||
return fail(500, {
|
return fail(500, {
|
||||||
errors: [
|
errors: [
|
||||||
{
|
{
|
||||||
error: "Server error: Failed to clear authentication token",
|
error: 'Server error: Failed to clear authentication token',
|
||||||
id: Date.now(),
|
id: Date.now()
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// redirect the user
|
// redirect the user
|
||||||
throw redirect(302, "/auth/login");
|
throw redirect(302, '/auth/login');
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,15 +21,15 @@ func RegisterRoutes(router *gin.Engine, userController *controllers.UserControll
|
|||||||
// apiRouter.POST("/v1/subscription", membershipcontroller.RegisterSubscription)
|
// apiRouter.POST("/v1/subscription", membershipcontroller.RegisterSubscription)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
userRouter := router.Group("/backend/users")
|
userRouter := router.Group("/backend")
|
||||||
userRouter.Use(middlewares.AuthMiddleware())
|
userRouter.Use(middlewares.AuthMiddleware())
|
||||||
{
|
{
|
||||||
userRouter.GET("/current", userController.CurrentUserHandler)
|
userRouter.GET("/users/current", userController.CurrentUserHandler)
|
||||||
userRouter.POST("/logout", userController.LogoutHandler)
|
userRouter.POST("/logout", userController.LogoutHandler)
|
||||||
userRouter.PATCH("/upsert", userController.UpdateHandler)
|
userRouter.PATCH("/users", userController.UpdateHandler)
|
||||||
userRouter.POST("/upsert", userController.RegisterUser)
|
userRouter.POST("/users", userController.RegisterUser)
|
||||||
userRouter.GET("/all", userController.GetAllUsers)
|
userRouter.GET("/users/all", userController.GetAllUsers)
|
||||||
userRouter.DELETE("/delete", userController.DeleteUser)
|
userRouter.DELETE("/users", userController.DeleteUser)
|
||||||
}
|
}
|
||||||
|
|
||||||
membershipRouter := router.Group("/backend/membership")
|
membershipRouter := router.Group("/backend/membership")
|
||||||
|
|||||||
Reference in New Issue
Block a user