mirror of
https://github.com/seanmorley15/AdventureLog.git
synced 2025-08-02 19:55:18 +02:00
commit
a7be733b37
6 changed files with 176 additions and 53 deletions
|
@ -104,6 +104,20 @@
|
|||
></iconify-icon></button
|
||||
>
|
||||
{/if}
|
||||
{#if type == "trip"}
|
||||
<!-- <button class="btn btn-primary" on:click={moreInfo}
|
||||
><iconify-icon icon="mdi:launch" class="text-2xl"
|
||||
></iconify-icon></button
|
||||
> -->
|
||||
<button class="btn btn-primary" on:click={edit}
|
||||
><iconify-icon icon="mdi:file-document-edit" class="text-2xl"
|
||||
></iconify-icon></button
|
||||
>
|
||||
<button class="btn btn-secondary" on:click={remove}
|
||||
><iconify-icon icon="mdi:trash-can-outline" class="text-2xl"
|
||||
></iconify-icon></button
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -11,11 +11,11 @@ export const load: PageServerLoad = async (event) => {
|
|||
return {
|
||||
user: event.locals.user,
|
||||
};
|
||||
return redirect(302, "/login");
|
||||
return redirect(302, "/login");
|
||||
};
|
||||
|
||||
export const actions: Actions = {
|
||||
default: async (event: { request: { formData: () => any; }; }) => {
|
||||
default: async (event: { request: { formData: () => any } }) => {
|
||||
const formData = await event.request.formData();
|
||||
let userId = formData.get("user_id");
|
||||
let username = formData.get("username");
|
||||
|
@ -26,22 +26,22 @@ export const actions: Actions = {
|
|||
let password = formData.get("password");
|
||||
|
||||
if (!userId) {
|
||||
return {
|
||||
status: 400,
|
||||
body: {
|
||||
message: "User ID is required"
|
||||
}
|
||||
};
|
||||
return {
|
||||
status: 400,
|
||||
body: {
|
||||
message: "User ID is required",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (icon.length > 1) {
|
||||
return {
|
||||
status: 400,
|
||||
body: {
|
||||
message: "Icon must be a single character"
|
||||
}
|
||||
};
|
||||
}
|
||||
// if (icon.length > 1) {
|
||||
// return {
|
||||
// status: 400,
|
||||
// body: {
|
||||
// message: "Icon must be a single character",
|
||||
// },
|
||||
// };
|
||||
// }
|
||||
|
||||
const usernameTaken = await db
|
||||
.select()
|
||||
|
@ -50,40 +50,42 @@ export const actions: Actions = {
|
|||
.limit(1)
|
||||
.then((results) => results[0] as unknown as DatabaseUser | undefined);
|
||||
|
||||
if (usernameTaken) {
|
||||
return {
|
||||
status: 400,
|
||||
body: {
|
||||
message: "Username taken!"
|
||||
}
|
||||
};
|
||||
if (usernameTaken && usernameTaken.id !== userId) {
|
||||
return {
|
||||
status: 400,
|
||||
body: {
|
||||
message: "Username taken!",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (password) {
|
||||
let hashedPassword = await new Argon2id().hash(password);
|
||||
console.log(hashedPassword)
|
||||
await db.update(userTable)
|
||||
.set({
|
||||
hashed_password: hashedPassword
|
||||
})
|
||||
.where(eq(userTable.id, userId));
|
||||
}
|
||||
|
||||
await db.update(userTable)
|
||||
let hashedPassword = await new Argon2id().hash(password);
|
||||
console.log(hashedPassword);
|
||||
await db
|
||||
.update(userTable)
|
||||
.set({
|
||||
username: username,
|
||||
first_name: firstName,
|
||||
last_name: lastName,
|
||||
icon: icon
|
||||
hashed_password: hashedPassword,
|
||||
})
|
||||
.where(eq(userTable.id, userId));
|
||||
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
message: "User updated"
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
await db
|
||||
.update(userTable)
|
||||
.set({
|
||||
username: username,
|
||||
first_name: firstName,
|
||||
last_name: lastName,
|
||||
icon: icon,
|
||||
})
|
||||
.where(eq(userTable.id, userId));
|
||||
|
||||
// return a page refresh
|
||||
return {
|
||||
status: 303,
|
||||
headers: {
|
||||
location: "/settings",
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
let icon = data.user?.icon;
|
||||
let signup_date = data.user?.signup_date;
|
||||
let role = data.user?.role;
|
||||
|
||||
// the submit function shoud just reload the page
|
||||
</script>
|
||||
|
||||
<h1 class="text-center font-extrabold text-4xl mb-6">Settings Page</h1>
|
||||
|
|
|
@ -4,6 +4,7 @@ import { db } from "$lib/db/db.server";
|
|||
import {
|
||||
adventureTable,
|
||||
sessionTable,
|
||||
userPlannedTrips,
|
||||
userTable,
|
||||
userVisitedWorldTravel,
|
||||
} from "$lib/db/schema";
|
||||
|
@ -14,6 +15,9 @@ export const load: PageServerLoad = async (event) => {
|
|||
let users: DatabaseUser[] = [];
|
||||
let visitCount: number = NaN;
|
||||
let userCount: number = NaN;
|
||||
let planCount: number = NaN;
|
||||
let tripCount: number = NaN;
|
||||
let featuredCount: number = NaN;
|
||||
let regionCount: number = NaN;
|
||||
if (!event.locals.user) {
|
||||
return redirect(302, "/login");
|
||||
|
@ -36,12 +40,29 @@ export const load: PageServerLoad = async (event) => {
|
|||
.select({ count: count() })
|
||||
.from(userVisitedWorldTravel)
|
||||
.execute()) as unknown as number;
|
||||
planCount = (await db
|
||||
.select({ count: count() })
|
||||
.from(adventureTable)
|
||||
.where(eq(adventureTable.type, "planner"))
|
||||
.execute()) as unknown as number;
|
||||
tripCount = (await db
|
||||
.select({ count: count() })
|
||||
.from(userPlannedTrips)
|
||||
.execute()) as unknown as number;
|
||||
featuredCount = (await db
|
||||
.select({ count: count() })
|
||||
.from(adventureTable)
|
||||
.where(eq(adventureTable.type, "featured"))
|
||||
.execute()) as unknown as number;
|
||||
}
|
||||
return {
|
||||
users,
|
||||
visitCount,
|
||||
userCount,
|
||||
regionCount,
|
||||
planCount,
|
||||
tripCount,
|
||||
featuredCount,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -62,6 +62,9 @@
|
|||
let visitCount = $page.data.visitCount[0].count;
|
||||
let userCount = $page.data.userCount[0].count;
|
||||
let regionCount = $page.data.regionCount[0].count;
|
||||
let tripCount = $page.data.tripCount[0].count;
|
||||
let planCount = $page.data.planCount[0].count;
|
||||
let featuredCount = $page.data.featuredCount[0].count;
|
||||
</script>
|
||||
|
||||
<h1 class="text-center font-extrabold text-4xl">Admin Settings</h1>
|
||||
|
@ -153,17 +156,29 @@
|
|||
<div class="stats stats-vertical lg:stats-horizontal shadow">
|
||||
<div class="stat">
|
||||
<div class="stat-title">Total Visits</div>
|
||||
<div class="stat-value">{visitCount}</div>
|
||||
<div class="stat-value text-center">{visitCount}</div>
|
||||
</div>
|
||||
|
||||
<div class="stat">
|
||||
<div class="stat-title">Total Users</div>
|
||||
<div class="stat-value">{userCount}</div>
|
||||
<div class="stat-value text-center">{userCount}</div>
|
||||
</div>
|
||||
|
||||
<div class="stat">
|
||||
<div class="stat-title">Visited Regions</div>
|
||||
<div class="stat-value">{regionCount}</div>
|
||||
<div class="stat-value text-center">{regionCount}</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-title">Total Trips</div>
|
||||
<div class="stat-value text-center">{tripCount}</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-title">Total Plans</div>
|
||||
<div class="stat-value text-center">{planCount}</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-title">Featured Adventures</div>
|
||||
<div class="stat-value text-center">{featuredCount}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -4,8 +4,14 @@
|
|||
import type { PageData } from "./$types";
|
||||
import { goto } from "$app/navigation";
|
||||
import CreateNewAdventure from "$lib/components/CreateNewAdventure.svelte";
|
||||
import { addAdventure } from "../../../services/adventureService";
|
||||
import {
|
||||
addAdventure,
|
||||
removeAdventure,
|
||||
saveAdventure,
|
||||
} from "../../../services/adventureService";
|
||||
import AdventureCard from "$lib/components/AdventureCard.svelte";
|
||||
import EditModal from "$lib/components/EditModal.svelte";
|
||||
import SucessToast from "$lib/components/SucessToast.svelte";
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
|
@ -14,6 +20,7 @@
|
|||
let isCreateModalOpen: boolean = false;
|
||||
|
||||
let adventuresPlans: Adventure[] = [];
|
||||
let adventureToEdit: Adventure | undefined;
|
||||
|
||||
onMount(() => {
|
||||
if (data.trip.trip) {
|
||||
|
@ -25,6 +32,11 @@
|
|||
}
|
||||
});
|
||||
|
||||
function handleClose() {
|
||||
adventureToEdit = undefined;
|
||||
isCreateModalOpen = false;
|
||||
}
|
||||
|
||||
const newAdventure = async (event: { detail: Adventure }) => {
|
||||
isCreateModalOpen = false;
|
||||
let detailAdventure = event.detail;
|
||||
|
@ -32,13 +44,66 @@
|
|||
let newArray = await addAdventure(detailAdventure, adventuresPlans);
|
||||
if (newArray.length > 0) {
|
||||
adventuresPlans = newArray;
|
||||
// showToast("Adventure added successfully!");
|
||||
showToast("Adventure added successfully!");
|
||||
} else {
|
||||
// showToast("Failed to add adventure");
|
||||
showToast("Failed to add adventure");
|
||||
}
|
||||
};
|
||||
|
||||
let isShowingToast: boolean = false;
|
||||
let toastAction: string = "";
|
||||
|
||||
function showToast(action: string) {
|
||||
toastAction = action;
|
||||
isShowingToast = true;
|
||||
|
||||
setTimeout(() => {
|
||||
isShowingToast = false;
|
||||
toastAction = "";
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
async function remove(event: { detail: number }) {
|
||||
let initialLength: number = adventuresPlans.length;
|
||||
let theAdventure = adventuresPlans.find(
|
||||
(adventure) => adventure.id === event.detail
|
||||
);
|
||||
if (theAdventure) {
|
||||
let newArray = await removeAdventure(theAdventure, adventuresPlans);
|
||||
if (newArray.length === initialLength - 1) {
|
||||
adventuresPlans = newArray;
|
||||
showToast("Adventure removed successfully!");
|
||||
} else {
|
||||
showToast("Failed to remove adventure");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function savePlan(event: { detail: Adventure }) {
|
||||
let newArray = await saveAdventure(event.detail, adventuresPlans);
|
||||
if (newArray.length > 0) {
|
||||
adventuresPlans = newArray;
|
||||
showToast("Adventure updated successfully!");
|
||||
} else {
|
||||
showToast("Failed to update adventure");
|
||||
}
|
||||
adventureToEdit = undefined;
|
||||
}
|
||||
|
||||
function edit(event: { detail: number }) {
|
||||
const adventure = adventuresPlans.find(
|
||||
(adventure) => adventure.id === event.detail
|
||||
);
|
||||
if (adventure) {
|
||||
adventureToEdit = adventure;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if isShowingToast}
|
||||
<SucessToast action={toastAction} />
|
||||
{/if}
|
||||
|
||||
<main>
|
||||
{#if trip && trip.name}
|
||||
<h1 class="text-center font-extrabold text-4xl mb-2">{trip.name}</h1>
|
||||
|
@ -60,7 +125,7 @@
|
|||
class="grid xl:grid-cols-3 lg:grid-cols-3 md:grid-cols-2 sm:grid-cols-1 gap-4 mt-4 content-center auto-cols-auto ml-6 mr-6"
|
||||
>
|
||||
{#each adventuresPlans as adventure (adventure.id)}
|
||||
<AdventureCard {adventure} type="trip" />
|
||||
<AdventureCard {adventure} type="trip" on:edit={edit} on:remove={remove} />
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
|
@ -98,3 +163,7 @@
|
|||
on:create={newAdventure}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if adventureToEdit && adventureToEdit.id != undefined}
|
||||
<EditModal bind:adventureToEdit on:submit={savePlan} on:close={handleClose} />
|
||||
{/if}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue