1
0
Fork 0
mirror of https://github.com/seanmorley15/AdventureLog.git synced 2025-07-19 21:09:37 +02:00

Merge branch 'development' into seanmorley15-patch-1

This commit is contained in:
Sean Morley 2024-04-02 18:16:02 -04:00 committed by GitHub
commit ad45447e88
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 6726 additions and 6493 deletions

View file

@ -1,4 +1,5 @@
# AdventureLog: Embark, Explore, Remember. 🌍 # AdventureLog: Embark, Explore, Remember. 🌍
_**⚠️ AdvenutreLog is in early development and is not at all deployable in the current form!**_ _**⚠️ AdvenutreLog is in early development and is not at all deployable in the current form!**_
### *"Never forget an adventure with AdventureLog - Your ultimate travel companion!"* ### *"Never forget an adventure with AdventureLog - Your ultimate travel companion!"*
----- -----
@ -9,3 +10,4 @@ _**⚠️ AdvenutreLog is in early development and is not at all deployable in t
2. Edit the `docker-compose.yml` file and change the database password 2. Edit the `docker-compose.yml` file and change the database password
3. Run `docker compose up -d` to build the image and start the container 3. Run `docker compose up -d` to build the image and start the container
4. Wait for the app to start up and migrate then visit the port and enjoy! 4. Wait for the app to start up and migrate then visit the port and enjoy!

View file

@ -1,15 +1,15 @@
import type { Config } from 'drizzle-kit'; import type { Config } from "drizzle-kit";
import * as dotenv from 'dotenv'; import * as dotenv from "dotenv";
dotenv.config(); dotenv.config();
const { DATABASE_URL } = process.env; const { DATABASE_URL } = process.env;
if (!DATABASE_URL) { if (!DATABASE_URL) {
throw new Error('No url'); throw new Error("No url");
} }
export default { export default {
schema: './src/lib/db/schema.ts', schema: "./src/lib/db/schema.ts",
out: './migrations', out: "./migrations",
driver: 'pg', driver: "pg",
dbCredentials: { dbCredentials: {
connectionString: DATABASE_URL connectionString: DATABASE_URL,
} },
} satisfies Config; } satisfies Config;

11882
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,42 +1,42 @@
{ {
"name": "adventurelog", "name": "adventurelog",
"version": "0.0.1", "version": "0.0.1",
"description": "Embark, Explore, Remember. 🌍", "description": "Embark, Explore, Remember. 🌍",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "vite dev", "dev": "vite dev",
"build": "vite build", "build": "vite build",
"preview": "vite preview", "preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"studio": "drizzle-kit studio --config drizzle.config.ts", "studio": "drizzle-kit studio --config drizzle.config.ts",
"generate": "drizzle-kit generate:pg --config drizzle.config.ts", "generate": "drizzle-kit generate:pg --config drizzle.config.ts",
"migrate": "drizzle-kit push:pg --config drizzle.config.ts", "migrate": "drizzle-kit push:pg --config drizzle.config.ts",
"seed": "node seed.js" "seed": "node seed.js"
}, },
"devDependencies": { "devDependencies": {
"@sveltejs/adapter-auto": "^3.0.0", "@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/adapter-node": "^5.0.1", "@sveltejs/adapter-node": "^5.0.1",
"@sveltejs/adapter-vercel": "^5.2.0", "@sveltejs/adapter-vercel": "^5.2.0",
"@sveltejs/kit": "^2.0.0", "@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0",
"@tailwindcss/typography": "^0.5.12", "@tailwindcss/typography": "^0.5.12",
"autoprefixer": "^10.4.19", "autoprefixer": "^10.4.19",
"daisyui": "^4.9.0", "daisyui": "^4.9.0",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"drizzle-kit": "^0.20.14", "drizzle-kit": "^0.20.14",
"pg": "^8.11.4", "pg": "^8.11.4",
"postcss": "^8.4.38", "postcss": "^8.4.38",
"svelte": "^4.2.7", "svelte": "^4.2.7",
"svelte-check": "^3.6.0", "svelte-check": "^3.6.0",
"tailwindcss": "^3.4.3", "tailwindcss": "^3.4.3",
"tslib": "^2.4.1", "tslib": "^2.4.1",
"typescript": "^5.0.0", "typescript": "^5.0.0",
"vite": "^5.0.3" "vite": "^5.0.3"
}, },
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"drizzle-orm": "^0.30.6", "drizzle-orm": "^0.30.6",
"postgres": "^3.4.4" "postgres": "^3.4.4"
} }
} }

View file

@ -3,4 +3,4 @@ export default {
tailwindcss: {}, tailwindcss: {},
autoprefixer: {}, autoprefixer: {},
}, },
} };

14
src/app.d.ts vendored
View file

@ -1,13 +1,13 @@
// See https://kit.svelte.dev/docs/types#app // See https://kit.svelte.dev/docs/types#app
// for information about these interfaces // for information about these interfaces
declare global { declare global {
namespace App { namespace App {
// interface Error {} // interface Error {}
// interface Locals {} // interface Locals {}
// interface PageData {} // interface PageData {}
// interface PageState {} // interface PageState {}
// interface Platform {} // interface Platform {}
} }
} }
export {}; export {};

View file

@ -1,13 +1,13 @@
<!doctype html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" /> <link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<title>AdventureLog</title> <title>AdventureLog</title>
%sveltekit.head% %sveltekit.head%
</head> </head>
<body data-sveltekit-preload-data="hover"> <body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div> <div style="display: contents">%sveltekit.body%</div>
</body> </body>
</html> </html>

View file

@ -1,31 +1,77 @@
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from "svelte";
import locationDot from "$lib/assets/locationDot.svg"; import locationDot from "$lib/assets/locationDot.svg";
import calendar from "$lib/assets/calendar.svg"; import calendar from "$lib/assets/calendar.svg";
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
export let name:String; export let type: String;
export let location:String;
export let created:string;
export let id:Number;
function remove() { export let name: String;
dispatch('remove', id); export let location: String;
} export let created: string;
function edit() { export let id: Number;
dispatch('edit', id)
} function remove() {
dispatch("remove", id);
}
function edit() {
dispatch("edit", id);
}
function add() {
dispatch("add", { name, location });
}
</script> </script>
<div class="card min-w-max lg:w-96 md:w-80 sm:w-60 xs:w-40 bg-neutral shadow-xl overflow-hidden"> {#if type === "mylog"}
<div
class="card min-w-max lg:w-96 md:w-80 sm:w-60 xs:w-40 bg-neutral shadow-xl overflow-hidden"
>
<div class="card-body"> <div class="card-body">
<h2 class="card-title overflow-ellipsis">{name}</h2> <h2 class="card-title overflow-ellipsis">{name}</h2>
<p><img src={locationDot} class="inline-block -mt-1 mr-1" alt="Logo" />{location}</p> {#if location !== ""}
<p><img src={calendar} class="inline-block -mt-1 mr-1" alt="Logo" />{created}</p> <p>
<img
src={locationDot}
class="inline-block -mt-1 mr-1"
alt="Logo"
/>{location}
</p>
{/if}
{#if created !== ""}
<p>
<img
src={calendar}
class="inline-block -mt-1 mr-1"
alt="Logo"
/>{created}
</p>
{/if}
<div class="card-actions justify-end"> <div class="card-actions justify-end">
<button class="btn btn-primary" on:click={edit}>Edit</button> <button class="btn btn-primary" on:click={edit}>Edit</button>
<button class="btn btn-secondary" on:click={remove}>Remove</button> <button class="btn btn-secondary" on:click={remove}>Remove</button>
</div> </div>
</div> </div>
</div> </div>
{/if}
{#if type === "featured"}
<div
class="card min-w-max lg:w-96 md:w-80 sm:w-60 xs:w-40 bg-neutral shadow-xl overflow-hidden"
>
<div class="card-body">
<h2 class="card-title overflow-ellipsis">{name}</h2>
{#if location != ""}
<p>
<img
src={locationDot}
class="inline-block -mt-1 mr-1"
alt="Logo"
/>{location}
</p>
{/if}
<div class="card-actions justify-end">
<button class="btn btn-primary" on:click={add}>Add</button>
</div>
</div>
</div>
{/if}

View file

@ -0,0 +1,68 @@
<script lang="ts">
import { createEventDispatcher } from "svelte";
import type { Adventure } from "$lib/utils/types";
const dispatch = createEventDispatcher();
import { onMount } from "svelte";
let modal: HTMLDialogElement;
onMount(() => {
modal = document.getElementById("my_modal_1") as HTMLDialogElement;
if (modal) {
modal.showModal();
}
});
function close() {
dispatch("close");
}
function handleKeydown(event: KeyboardEvent) {
if (event.key === "Escape") {
close();
}
}
</script>
<dialog id="my_modal_1" class="modal">
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
<div class="modal-box" role="dialog" on:keydown={handleKeydown} tabindex="0">
<h3 class="font-bold text-lg">Edit Adventure</h3>
<p class="py-4">Press ESC key or click the button below to close</p>
<div
class="modal-action items-center"
style="display: flex; flex-direction: column; align-items: center; width: 100%;"
>
<form method="dialog" style="width: 100%;">
<div>
<label for="name">Name</label>
<input
type="text"
id="name"
class="input input-bordered w-full max-w-xs"
/>
</div>
<div>
<label for="location">Location</label>
<input
type="text"
id="location"
class="input input-bordered w-full max-w-xs"
/>
</div>
<div>
<label for="created">Created</label>
<input
type="date"
id="created"
class="input input-bordered w-full max-w-xs"
/>
</div>
<!-- <button class="btn btn-primary mr-4 mt-4" on:click={submit}>Save</button
> -->
<!-- if there is a button in form, it will close the modal -->
<button class="btn mt-4" on:click={close}>Close</button>
</form>
</div>
</div>
</dialog>

View file

@ -1,60 +1,88 @@
<script lang="ts"> <script lang="ts">
export let editId:number = NaN; export let editId: number = NaN;
export let editName:string = ''; export let editName: string = "";
export let editLocation:string = ''; export let editLocation: string = "";
export let editCreated: string = ''; export let editCreated: string = "";
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from "svelte";
import type { Adventure } from '$lib/utils/types'; import type { Adventure } from "$lib/utils/types";
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
import { onMount } from 'svelte'; import { onMount } from "svelte";
let modal: HTMLDialogElement; let modal: HTMLDialogElement;
let originalName = editName; let originalName = editName;
onMount(() => { onMount(() => {
modal = document.getElementById("my_modal_1") as HTMLDialogElement; modal = document.getElementById("my_modal_1") as HTMLDialogElement;
if (modal) { if (modal) {
modal.showModal(); modal.showModal();
}
});
function submit() {
const adventureEdited: Adventure = { id: editId, name: editName, location: editLocation, created: editCreated };
dispatch('submit', adventureEdited);
console.log(adventureEdited)
} }
});
function close() { function submit() {
dispatch('close'); const adventureEdited: Adventure = {
} id: editId,
name: editName,
location: editLocation,
created: editCreated,
};
dispatch("submit", adventureEdited);
console.log(adventureEdited);
}
function handleKeydown(event: KeyboardEvent) { function close() {
if (event.key === 'Escape') { dispatch("close");
close(); }
}
function handleKeydown(event: KeyboardEvent) {
if (event.key === "Escape") {
close();
} }
}
</script> </script>
<dialog id="my_modal_1" class="modal" > <dialog id="my_modal_1" class="modal">
<!-- svelte-ignore a11y-no-noninteractive-element-interactions --> <!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<!-- svelte-ignore a11y-no-noninteractive-tabindex --> <!-- svelte-ignore a11y-no-noninteractive-tabindex -->
<div class="modal-box" role="dialog" on:keydown={handleKeydown} tabindex="0"> <div class="modal-box" role="dialog" on:keydown={handleKeydown} tabindex="0">
<h3 class="font-bold text-lg">Edit Adventure {originalName}</h3> <h3 class="font-bold text-lg">Edit Adventure {originalName}</h3>
<p class="py-4">Press ESC key or click the button below to close</p> <p class="py-4">Press ESC key or click the button below to close</p>
<div class="modal-action"> <div
<form method="dialog"> class="modal-action items-center"
<label for="name">Name</label> style="display: flex; flex-direction: column; align-items: center; width: 100%;"
<input type="text" id="name" bind:value={editName} class="input input-bordered w-full max-w-xs" /> >
<label for="location">Location</label> <form method="dialog" style="width: 100%;">
<input type="text" id="location" bind:value={editLocation} class="input input-bordered w-full max-w-xs" /> <div>
<label for="created">Created</label> <label for="name">Name</label>
<input type="date" id="created" bind:value={editCreated} class="input input-bordered w-full max-w-xs" /> <input
<button class="btn btn-primary" on:click={submit}>Save</button> type="text"
<!-- if there is a button in form, it will close the modal --> id="name"
<button class="btn" on:click={close}>Close</button> bind:value={editName}
</form> class="input input-bordered w-full max-w-xs"
/>
</div> </div>
<div>
<label for="location">Location</label>
<input
type="text"
id="location"
bind:value={editLocation}
class="input input-bordered w-full max-w-xs"
/>
</div>
<div>
<label for="created">Created</label>
<input
type="date"
id="created"
bind:value={editCreated}
class="input input-bordered w-full max-w-xs"
/>
</div>
<button class="btn btn-primary mr-4 mt-4" on:click={submit}>Save</button
>
<!-- if there is a button in form, it will close the modal -->
<button class="btn mt-4" on:click={close}>Close</button>
</form>
</div> </div>
</div>
</dialog> </dialog>

View file

@ -1,24 +0,0 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
import locationDot from "$lib/assets/locationDot.svg";
import calendar from "$lib/assets/calendar.svg";
const dispatch = createEventDispatcher();
export let name:String;
export let location:String;
function add() {
dispatch('add', {name, location});
}
</script>
<div class="card min-w-max lg:w-96 md:w-80 sm:w-60 xs:w-40 bg-neutral shadow-xl overflow-hidden">
<div class="card-body">
<h2 class="card-title overflow-ellipsis">{name}</h2>
<p><img src={locationDot} class="inline-block -mt-1 mr-1" alt="Logo" />{location}</p>
<div class="card-actions justify-end">
<button class="btn btn-primary" on:click={add}>Add</button>
</div>
</div>
</div>

View file

@ -1,19 +1,53 @@
<script> <script>
import pinLogo from "$lib/assets/pinLogo.svg"; import pinLogo from "$lib/assets/pinLogo.svg";
</script> </script>
<footer class="footer items-center p-4 bg-neutral text-neutral-content fixed bottom-0 left-0 w-full"> <footer
<aside class="items-center grid-flow-col"> class="footer items-center p-4 bg-neutral text-neutral-content fixed bottom-0 left-0 w-full"
<img src={pinLogo} class="inline-block -mt-1 mr-1" alt="Logo" /> >
<p>Copyright © 2024 Sean Morley - All rights reserved</p> <aside class="items-center grid-flow-col">
</aside> <img src={pinLogo} class="inline-block -mt-1 mr-1" alt="Logo" />
<nav class="grid-flow-col gap-4 md:place-self-center md:justify-self-end"> <p>Copyright © 2024 Sean Morley - All rights reserved</p>
<!-- svelte-ignore a11y-missing-attribute --> </aside>
<a><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="fill-current"><path d="M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z"></path></svg> <nav class="grid-flow-col gap-4 md:place-self-center md:justify-self-end">
</a> <!-- svelte-ignore a11y-missing-attribute -->
<!-- svelte-ignore a11y-missing-attribute --> <a
<a><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="fill-current"><path d="M19.615 3.184c-3.604-.246-11.631-.245-15.23 0-3.897.266-4.356 2.62-4.385 8.816.029 6.185.484 8.549 4.385 8.816 3.6.245 11.626.246 15.23 0 3.897-.266 4.356-2.62 4.385-8.816-.029-6.185-.484-8.549-4.385-8.816zm-10.615 12.816v-8l8 3.993-8 4.007z"></path></svg></a> ><svg
<!-- svelte-ignore a11y-missing-attribute --> xmlns="http://www.w3.org/2000/svg"
<a><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="fill-current"><path d="M9 8h-3v4h3v12h5v-12h3.642l.358-4h-4v-1.667c0-.955.192-1.333 1.115-1.333h2.885v-5h-3.808c-3.596 0-5.192 1.583-5.192 4.615v3.385z"></path></svg></a> width="24"
</nav> height="24"
viewBox="0 0 24 24"
class="fill-current"
><path
d="M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z"
></path></svg
>
</a>
<!-- svelte-ignore a11y-missing-attribute -->
<a
><svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
class="fill-current"
><path
d="M19.615 3.184c-3.604-.246-11.631-.245-15.23 0-3.897.266-4.356 2.62-4.385 8.816.029 6.185.484 8.549 4.385 8.816 3.6.245 11.626.246 15.23 0 3.897-.266 4.356-2.62 4.385-8.816-.029-6.185-.484-8.549-4.385-8.816zm-10.615 12.816v-8l8 3.993-8 4.007z"
></path></svg
></a
>
<!-- svelte-ignore a11y-missing-attribute -->
<a
><svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
class="fill-current"
><path
d="M9 8h-3v4h3v12h5v-12h3.642l.358-4h-4v-1.667c0-.955.192-1.333 1.115-1.333h2.885v-5h-3.808c-3.596 0-5.192 1.583-5.192 4.615v3.385z"
></path></svg
></a
>
</nav>
</footer> </footer>

View file

@ -1,44 +1,51 @@
<script lang="ts"> <script lang="ts">
import { visitCount } from '$lib/utils/stores/visitCountStore'; import { visitCount } from "$lib/utils/stores/visitCountStore";
import { goto } from '$app/navigation'; import { goto } from "$app/navigation";
async function goHome() { async function goHome() {
goto('/'); goto("/");
}
async function goToLog() {
goto("/log");
}
async function goToFeatured() {
goto("/featured");
}
let count = 0;
visitCount.subscribe((value) => {
count = value;
});
// Set the visit count to the number of adventures stored in local storage
const isBrowser = typeof window !== "undefined";
if (isBrowser) {
const storedAdventures = localStorage.getItem("adventures");
if (storedAdventures) {
let parsed = JSON.parse(storedAdventures);
visitCount.set(parsed.length);
} }
async function goToLog() { }
goto('/log');
}
async function goToFeatured() {
goto('/featured');
}
let count = 0;
visitCount.subscribe((value) => {
count = value;
});
// Set the visit count to the number of adventures stored in local storage
const isBrowser = typeof window !== 'undefined';
if (isBrowser) {
const storedAdventures = localStorage.getItem('adventures');
if (storedAdventures) {
let parsed = JSON.parse(storedAdventures);
visitCount.set (parsed.length);
}
}
</script> </script>
<div class="navbar bg-base-100 flex flex-col md:flex-row"> <div class="navbar bg-base-100 flex flex-col md:flex-row">
<div class="navbar-start flex justify-around md:justify-start"> <div class="navbar-start flex justify-around md:justify-start">
<button class="btn btn-primary my-2 md:my-0 md:mr-4 md:ml-2" on:click={goHome}>Home</button> <button
<button class="btn btn-primary my-2 md:my-0 md:mr-4 md:ml-2" on:click={goToLog}>My Log</button> class="btn btn-primary my-2 md:my-0 md:mr-4 md:ml-2"
<button class="btn btn-primary my-2 md:my-0" on:click={goToFeatured}>Featured</button> on:click={goHome}>Home</button
</div> >
<div class="navbar-center flex justify-center md:justify-center"> <button
<a class="btn btn-ghost text-xl" href="/">AdventureLog 🗺️</a> class="btn btn-primary my-2 md:my-0 md:mr-4 md:ml-2"
</div> on:click={goToLog}>My Log</button
<div class="navbar-end flex justify-around md:justify-end mr-4"> >
<p>Adventures: {count} </p> <button class="btn btn-primary my-2 md:my-0" on:click={goToFeatured}
</div> >Featured</button
>
</div>
<div class="navbar-center flex justify-center md:justify-center">
<a class="btn btn-ghost text-xl" href="/">AdventureLog 🗺️</a>
</div>
<div class="navbar-end flex justify-around md:justify-end mr-4">
<p>Adventures: {count}</p>
</div>
</div> </div>

View file

@ -1,9 +1,9 @@
<script lang="ts"> <script lang="ts">
export let action:string; export let action: string;
</script> </script>
<div class="toast toast-top toast-end z-50"> <div class="toast toast-top toast-end z-50">
<div class="alert alert-info"> <div class="alert alert-info">
<span>Adventure {action} successfully!</span> <span>Adventure {action} successfully!</span>
</div>
</div> </div>
</div>

View file

@ -1,8 +1,8 @@
import { drizzle } from 'drizzle-orm/postgres-js'; import { drizzle } from "drizzle-orm/postgres-js";
import postgres from 'postgres'; import postgres from "postgres";
import dotenv from 'dotenv'; import dotenv from "dotenv";
dotenv.config(); dotenv.config();
const { DATABASE_URL } = process.env; const { DATABASE_URL } = process.env;
const client = postgres(DATABASE_URL) const client = postgres(DATABASE_URL);
export const db = drizzle(client, {}); export const db = drizzle(client, {});

View file

@ -1,12 +1,12 @@
import { pgTable,json,text,serial } from "drizzle-orm/pg-core"; import { pgTable, json, text, serial } from "drizzle-orm/pg-core";
export const featuredAdventures = pgTable("featuredAdventures",{ export const featuredAdventures = pgTable("featuredAdventures", {
id:serial("id").primaryKey(), id: serial("id").primaryKey(),
name:text("name").notNull(), name: text("name").notNull(),
location:text("location"), location: text("location"),
}) });
export const sharedAdventures = pgTable("sharedAdventures",{ export const sharedAdventures = pgTable("sharedAdventures", {
id:text("id").primaryKey(), id: text("id").primaryKey(),
data:json("data").notNull(), data: json("data").notNull(),
}) });

View file

@ -1,11 +1,12 @@
// place files you want to import through the `$lib` alias in this folder. // place files you want to import through the `$lib` alias in this folder.
export function generateRandomString() { export function generateRandomString() {
let randomString = ''; let randomString = "";
const digits = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; const digits =
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (let i = 0; i < 10; i++) { for (let i = 0; i < 10; i++) {
const randomIndex = Math.floor(Math.random() * digits.length); const randomIndex = Math.floor(Math.random() * digits.length);
randomString += digits[randomIndex]; randomString += digits[randomIndex];
} }
return randomString; return randomString;
} }

View file

@ -1,4 +1,3 @@
import { onMount } from "svelte";
import { writable } from "svelte/store"; import { writable } from "svelte/store";
export const visitCount = writable(0); export const visitCount = writable(0);

View file

@ -1,6 +1,6 @@
export interface Adventure { export interface Adventure {
id: number id: number;
name: string; name: string;
location: string; location: string;
created:string created: string;
} }

View file

@ -1,19 +1,18 @@
<script> <script>
import Footer from "$lib/components/Footer.svelte"; import Footer from "$lib/components/Footer.svelte";
import Navbar from "$lib/components/Navbar.svelte"; import Navbar from "$lib/components/Navbar.svelte";
import "../app.css"; import "../app.css";
// only show footer if scrolled to the bottom
// only show footer if scrolled to the bottom
</script> </script>
<Navbar /> <Navbar />
<section> <section>
<slot></slot> <slot />
</section> </section>
<!-- <Footer /> --> <!-- <Footer /> -->
<!-- <style> <!-- <style>
section { section {
margin-top: 2rem; margin-top: 2rem;
margin-bottom: 5rem; margin-bottom: 5rem;

View file

@ -1,13 +1,25 @@
<script lang="ts"> <script lang="ts">
import { goto } from '$app/navigation'; import { goto } from "$app/navigation";
import campingDrawing from "$lib/assets/camping.svg"; import campingDrawing from "$lib/assets/camping.svg";
async function navToLog() { import { visitCount } from "$lib/utils/stores/visitCountStore";
goto('/log');
} async function navToLog() {
goto("/log");
}
</script> </script>
<div class="flex flex-col items-center justify-center"> <div class="flex flex-col items-center justify-center">
<article class="prose"><h1 class="mb-4">Welcome. Let's get Exploring!</h1></article> <article class="prose">
<img src={campingDrawing} class="w-1/4 mb-4" alt="Logo" /> <h1 class="mb-4">Welcome. Let's get Exploring!</h1>
<button on:click={navToLog} class="btn btn-primary">Open Log</button> </article>
<img src={campingDrawing} class="w-1/4 mb-4" alt="Logo" />
<button on:click={navToLog} class="btn btn-primary">Open Log</button>
<div class="stats shadow">
<div class="stat">
<div class="stat-title">Logged Adventures</div>
<div class="stat-value text-center">{$visitCount}</div>
<!-- <div class="stat-desc">21% more than last month</div> -->
</div>
</div>
</div> </div>

View file

@ -3,9 +3,12 @@ import { sharedAdventures } from "$lib/db/schema";
import type { Adventure } from "$lib/utils/types"; import type { Adventure } from "$lib/utils/types";
export async function POST({ request }: { request: Request }) { export async function POST({ request }: { request: Request }) {
const { key , data } = await request.json(); const { key, data } = await request.json();
let adventure = data as Adventure; let adventure = data as Adventure;
console.log(adventure); console.log(adventure);
await db.insert(sharedAdventures).values({ id:key,data:adventure }).execute(); await db
return new Response(JSON.stringify({key:key})); .insert(sharedAdventures)
.values({ id: key, data: adventure })
.execute();
return new Response(JSON.stringify({ key: key }));
} }

View file

@ -1,11 +1,13 @@
import { db } from '$lib/db/db.server'; import { db } from "$lib/db/db.server";
import { featuredAdventures } from '$lib/db/schema'; import { featuredAdventures } from "$lib/db/schema";
import type { Adventure } from '$lib/utils/types'; import type { Adventure } from "$lib/utils/types";
export const load = async () => {
export const load = (async () => { const result = await db
const result = await db.select().from(featuredAdventures).orderBy(featuredAdventures.id); .select()
return { .from(featuredAdventures)
result : result as Adventure[] .orderBy(featuredAdventures.id);
}; return {
}) result: result as Adventure[],
};
};

View file

@ -1,31 +1,39 @@
<script lang="ts"> <script lang="ts">
export let data export let data;
console.log(data.result); console.log(data.result);
import FeaturedAdventureCard from '$lib/components/FeaturedAdventureCard.svelte'; import AdventureCard from "$lib/components/AdventureCard.svelte";
import type { Adventure } from '$lib/utils/types.js'; import type { Adventure } from "$lib/utils/types.js";
import { addAdventure, getNextId } from '../../services/adventureService.js'; import { addAdventure, getNextId } from "../../services/adventureService.js";
function add(event: CustomEvent<{name: string, location: string}>) { function add(event: CustomEvent<{ name: string; location: string }>) {
console.log(event.detail); console.log(event.detail);
let newAdventure:Adventure = { let newAdventure: Adventure = {
id: getNextId(), id: getNextId(),
name: event.detail.name, name: event.detail.name,
location: event.detail.location, location: event.detail.location,
created: "" created: "",
} };
addAdventure(newAdventure); addAdventure(newAdventure);
}
}
</script> </script>
<div class="flex justify-center items-center w-full mt-4 mb-4"> <div class="flex justify-center items-center w-full mt-4 mb-4">
<article class="prose"> <article class="prose">
<h1 class="text-center">Featured Adventure Locations</h1> <h1 class="text-center">Featured Adventure Locations</h1>
</article> </article>
</div> </div>
<div 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"> <div
{#each data.result as adventure (adventure.id)} 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"
<FeaturedAdventureCard on:add={add} name={adventure.name} location={adventure.location} /> >
{/each} {#each data.result as adventure (adventure.id)}
<AdventureCard
type="featured"
on:add={add}
name={adventure.name}
location={adventure.location}
created=""
id={NaN}
/>
{/each}
</div> </div>

View file

@ -1,174 +1,224 @@
<script lang="ts"> <script lang="ts">
import AdventureCard from "$lib/components/AdventureCard.svelte"; import AdventureCard from "$lib/components/AdventureCard.svelte";
import type { Adventure } from '$lib/utils/types'; import type { Adventure } from "$lib/utils/types";
import { addAdventure, clearAdventures, getAdventures, getNextId, removeAdventure ,saveEdit } from "../../services/adventureService"; import {
import { onMount } from 'svelte'; addAdventure,
import { exportData } from "../../services/export"; clearAdventures,
import { importData } from "../../services/import"; getAdventures,
import exportFile from "$lib/assets/exportFile.svg"; getNextId,
import deleteIcon from "$lib/assets/deleteIcon.svg"; removeAdventure,
import SucessToast from "$lib/components/SucessToast.svelte"; saveEdit,
import mapDrawing from "$lib/assets/adventure_map.svg" } from "../../services/adventureService";
import EditModal from "$lib/components/EditModal.svelte"; import { onMount } from "svelte";
import { generateRandomString } from "$lib"; import { exportData } from "../../services/export";
import { importData } from "../../services/import";
import exportFile from "$lib/assets/exportFile.svg";
import deleteIcon from "$lib/assets/deleteIcon.svg";
import SucessToast from "$lib/components/SucessToast.svelte";
import mapDrawing from "$lib/assets/adventure_map.svg";
import EditModal from "$lib/components/EditModal.svelte";
import { generateRandomString } from "$lib";
let newName = ''; let newName = "";
let newLocation = ''; let newLocation = "";
let editId:number = NaN; let editId: number = NaN;
let editName:string = ''; let editName: string = "";
let editLocation:string = ''; let editLocation: string = "";
let editCreated: string = ''; let editCreated: string = "";
let adventures: Adventure[] = []; let adventures: Adventure[] = [];
let isShowingToast:boolean = false; let isShowingToast: boolean = false;
let toastAction:string = ''; let toastAction: string = "";
function showToast(action:string) { function showToast(action: string) {
toastAction = action; toastAction = action;
isShowingToast = true; isShowingToast = true;
console.log('showing toast'); console.log("showing toast");
setTimeout(() => { setTimeout(() => {
isShowingToast = false; isShowingToast = false;
toastAction = ''; toastAction = "";
console.log('hiding toast'); console.log("hiding toast");
}, 3000); }, 3000);
} }
const createNewAdventure = () => { const createNewAdventure = () => {
let currentDate = new Date(); let currentDate = new Date();
let dateString = currentDate.toISOString().slice(0,10); // Get date in "yyyy-mm-dd" format let dateString = currentDate.toISOString().slice(0, 10); // Get date in "yyyy-mm-dd" format
const newAdventure: Adventure = { id:getNextId(), name: newName, location: newLocation, created: dateString}; const newAdventure: Adventure = {
addAdventure(newAdventure); id: getNextId(),
newName = ''; // Reset newName and newLocation after adding adventure name: newName,
newLocation = ''; location: newLocation,
adventures = getAdventures(); // add to local array created: dateString,
showToast('added');
}; };
addAdventure(newAdventure);
newName = ""; // Reset newName and newLocation after adding adventure
newLocation = "";
adventures = getAdventures(); // add to local array
showToast("added");
};
onMount(async () => { onMount(async () => {
adventures = getAdventures() adventures = getAdventures();
}); });
function triggerRemoveAdventure(event: { detail: number; }) { function triggerRemoveAdventure(event: { detail: number }) {
removeAdventure(event) removeAdventure(event);
showToast('removed'); showToast("removed");
adventures = getAdventures() adventures = getAdventures();
}
function saveAdventure(event: { detail: Adventure }) {
console.log("Event" + event.detail);
saveEdit(event.detail);
editId = NaN;
editName = "";
editLocation = "";
editCreated = "";
adventures = getAdventures();
showToast("edited");
}
function editAdventure(event: { detail: number }) {
const adventure = adventures.find(
(adventure) => adventure.id === event.detail
);
if (adventure) {
editId = adventure.id;
editName = adventure.name;
editLocation = adventure.location;
editCreated = adventure.created;
} }
}
function saveAdventure(event: { detail: Adventure; }) { function shareLink() {
console.log("Event" + event.detail) let key = generateRandomString();
saveEdit(event.detail) let data = JSON.stringify(adventures);
editId = NaN; fetch("/api/share", {
editName = ''; method: "POST",
editLocation = ''; headers: {
editCreated = ''; "Content-Type": "application/json",
adventures = getAdventures() },
showToast('edited'); body: JSON.stringify({ key, data }),
})
.then((response) => response.json())
.then((data) => {
console.log("Success:", data);
let url = window.location.origin + "/shared/" + key;
navigator.clipboard.writeText(url);
})
.catch((error) => {
console.error("Error:", error);
});
}
} function handleClose() {
editId = NaN;
function editAdventure(event: { detail: number; }) { editName = "";
const adventure = adventures.find(adventure => adventure.id === event.detail); editLocation = "";
if (adventure) { editCreated = "";
editId = adventure.id; }
editName = adventure.name;
editLocation = adventure.location;
editCreated = adventure.created;
}
}
function shareLink() {
let key = generateRandomString()
let data = JSON.stringify(adventures)
fetch('/api/share', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ key, data }),
})
.then(response => response.json())
.then(data => {
console.log('Success:', data);
let url = window.location.origin + '/shared/' + key
navigator.clipboard.writeText(url)
})
.catch((error) => {
console.error('Error:', error);
});
}
function handleClose() {
editId = NaN;
editName = '';
editLocation = '';
editCreated = '';
}
function deleteData() {
clearAdventures();
adventures = getAdventures();
showToast('deleted');
}
function deleteData() {
clearAdventures();
adventures = getAdventures();
showToast("deleted");
}
</script> </script>
<div class="flex justify-center items-center w-full mt-4 mb-4"> <div class="flex justify-center items-center w-full mt-4 mb-4">
<article class="prose"> <article class="prose">
<h2 class="text-center">Add new Location</h2> <h2 class="text-center">Add new Location</h2>
</article> </article>
</div> </div>
<div class="flex flex-row items-center justify-center gap-4"> <div class="flex flex-row items-center justify-center gap-4">
<form on:submit={createNewAdventure} class="flex gap-2"> <form on:submit={createNewAdventure} class="flex gap-2">
<input type="text" bind:value={newName} placeholder="Adventure Name" class="input input-bordered w-full max-w-xs" /> <input
<input type="text" bind:value={newLocation} placeholder="Adventure Location" class="input input-bordered w-full max-w-xs" /> type="text"
<input class="btn btn-primary" type="submit" value="Add Adventure"> bind:value={newName}
</form> placeholder="Adventure Name"
class="input input-bordered w-full max-w-xs"
/>
<input
type="text"
bind:value={newLocation}
placeholder="Adventure Location"
class="input input-bordered w-full max-w-xs"
/>
<input class="btn btn-primary" type="submit" value="Add Adventure" />
</form>
</div> </div>
{#if adventures.length != 0} {#if adventures.length != 0}
<div class="flex justify-center items-center w-full mt-4 mb-4"> <div class="flex justify-center items-center w-full mt-4 mb-4">
<article class="prose"> <article class="prose">
<h1 class="text-center">My Visited Adventure Locations</h1> <h1 class="text-center">My Visited Adventure Locations</h1>
</article> </article>
</div> </div>
{/if} {/if}
{#if isShowingToast} {#if isShowingToast}
<SucessToast action={toastAction} /> <SucessToast action={toastAction} />
{/if} {/if}
{#if !Number.isNaN(editId)} {#if !Number.isNaN(editId)}
<EditModal bind:editId={editId} bind:editName={editName} bind:editLocation={editLocation} bind:editCreated={editCreated} on:submit={saveAdventure} on:close={handleClose} /> <EditModal
bind:editId
bind:editName
bind:editLocation
bind:editCreated
on:submit={saveAdventure}
on:close={handleClose}
/>
{/if} {/if}
<div 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"> <div
{#each adventures as adventure (adventure.id)} 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"
<AdventureCard id={adventure.id} name={adventure.name} location={adventure.location} created={adventure.created} on:remove={triggerRemoveAdventure} on:edit={editAdventure} /> >
{/each} {#each adventures as adventure (adventure.id)}
<AdventureCard
type="mylog"
id={adventure.id}
name={adventure.name}
location={adventure.location}
created={adventure.created}
on:remove={triggerRemoveAdventure}
on:edit={editAdventure}
/>
{/each}
</div> </div>
{#if adventures.length == 0} {#if adventures.length == 0}
<div class="flex flex-col items-center justify-center mt-16"> <div class="flex flex-col items-center justify-center mt-16">
<article class="prose mb-4"><h2>Add some adventures!</h2></article> <article class="prose mb-4"><h2>Add some adventures!</h2></article>
<img src={mapDrawing} width="25%" alt="Logo" /> <img src={mapDrawing} width="25%" alt="Logo" />
</div> </div>
{/if} {/if}
{#if adventures.length != 0} {#if adventures.length != 0}
<div class="flex flex-row items-center justify-center mt-16 gap-4 mb-4"> <div class="flex justify-center items-center w-full mt-4">
<button class="btn btn-neutral" on:click={async () => { window.location.href = exportData(); }}> <article class="prose">
<img src={exportFile} class="inline-block -mt-1" alt="Logo" /> Save as File <h2 class="text-center">Actions</h2>
</article>
</div>
<div
class="flex flex-row items-center justify-center mt-2 gap-4 mb-4 flex-wrap"
>
<button
class="btn btn-neutral"
on:click={async () => {
window.location.href = exportData();
}}
>
<img src={exportFile} class="inline-block -mt-1" alt="Logo" /> Save as File
</button> </button>
<button class="btn btn-neutral" on:click={deleteData}> <button class="btn btn-neutral" on:click={deleteData}>
<img src={deleteIcon} class="inline-block -mt-1" alt="Logo" /> Delete Data <img src={deleteIcon} class="inline-block -mt-1" alt="Logo" /> Delete Data
</button> </button>
<button class="btn btn-neutral" on:click={shareLink}> <button class="btn btn-neutral" on:click={shareLink}>
<img src={deleteIcon} class="inline-block -mt-1" alt="Logo" /> Share as Link <img src={deleteIcon} class="inline-block -mt-1" alt="Logo" /> Share as Link
</button> </button>
</div> </div>
{/if} {/if}

View file

@ -4,11 +4,15 @@ import { eq } from "drizzle-orm";
import type { Adventure } from "$lib/utils/types"; import type { Adventure } from "$lib/utils/types";
export async function load({ params }) { export async function load({ params }) {
let key = params.key; let key = params.key;
let result = await db.select().from(sharedAdventures).where(eq(sharedAdventures.id, key)).execute(); let result = await db
let adventure = result[0].data as Adventure; .select()
console.log(adventure); .from(sharedAdventures)
return { .where(eq(sharedAdventures.id, key))
result: adventure .execute();
}; let adventure = result[0].data as Adventure;
}; console.log(adventure);
return {
result: adventure,
};
}

View file

@ -1,8 +1,7 @@
<script lang="ts"> <script lang="ts">
import type { Adventure } from '$lib/utils/types' import type { Adventure } from "$lib/utils/types";
export let data; export let data;
let result = data.result; let result = data.result;
</script> </script>
<p>{result}</p> <p>{result}</p>

View file

@ -1,80 +1,76 @@
import type { Adventure } from '$lib/utils/types'; import type { Adventure } from "$lib/utils/types";
let adventures: Adventure[] = []; let adventures: Adventure[] = [];
import { visitCount } from '$lib/utils/stores/visitCountStore'; import { visitCount } from "$lib/utils/stores/visitCountStore";
// Check if localStorage is available (browser environment) // Check if localStorage is available (browser environment)
const isBrowser = typeof window !== 'undefined'; const isBrowser = typeof window !== "undefined";
// Load adventures from localStorage on startup (only in the browser) // Load adventures from localStorage on startup (only in the browser)
if (isBrowser) { if (isBrowser) {
const storedAdventures = localStorage.getItem('adventures'); const storedAdventures = localStorage.getItem("adventures");
if (storedAdventures) { if (storedAdventures) {
adventures = JSON.parse(storedAdventures); adventures = JSON.parse(storedAdventures);
} }
} }
export function getNextId() { export function getNextId() {
let nextId = Math.max(0, ...adventures.map(adventure => adventure.id)) + 1; let nextId = Math.max(0, ...adventures.map((adventure) => adventure.id)) + 1;
return nextId; return nextId;
} }
export function setAdventures(importArray: Adventure[]) { export function setAdventures(importArray: Adventure[]) {
adventures = importArray adventures = importArray;
} }
export function addAdventure(adventure: Adventure) { export function addAdventure(adventure: Adventure) {
adventures = [...adventures, adventure]; adventures = [...adventures, adventure];
if (isBrowser) { if (isBrowser) {
localStorage.setItem('adventures', JSON.stringify(adventures)); localStorage.setItem("adventures", JSON.stringify(adventures));
visitCount.update((n) => n + 1); visitCount.update((n) => n + 1);
} }
console.log(adventures); console.log(adventures);
} }
export function getAdventures(): Adventure[] { export function getAdventures(): Adventure[] {
return adventures; return adventures;
} }
export function removeAdventure(event: { detail: number; }) { export function removeAdventure(event: { detail: number }) {
adventures = adventures.filter(adventure => adventure.id !== event.detail); adventures = adventures.filter((adventure) => adventure.id !== event.detail);
if (isBrowser) { if (isBrowser) {
localStorage.setItem('adventures', JSON.stringify(adventures)); localStorage.setItem("adventures", JSON.stringify(adventures));
visitCount.update((n) => n - 1); visitCount.update((n) => n - 1);
} }
} }
export function saveEdit(adventure:Adventure) { export function saveEdit(adventure: Adventure) {
let editId = adventure.id; let editId = adventure.id;
console.log("saving edit") console.log("saving edit");
let editName = adventure.name; let editName = adventure.name;
let editLocation = adventure.location; let editLocation = adventure.location;
let editCreated = adventure.created; let editCreated = adventure.created;
let oldAdventure: Adventure | undefined = adventures.find(adventure => adventure.id === editId); let oldAdventure: Adventure | undefined = adventures.find(
console.log("old" + oldAdventure) (adventure) => adventure.id === editId
if (oldAdventure) { );
oldAdventure.name = editName; console.log("old" + oldAdventure);
oldAdventure.location = editLocation; if (oldAdventure) {
oldAdventure.created = editCreated; oldAdventure.name = editName;
} oldAdventure.location = editLocation;
editId = NaN; oldAdventure.created = editCreated;
console.log("done") }
if (isBrowser) { editId = NaN;
localStorage.setItem('adventures', JSON.stringify(adventures)); console.log("done");
} if (isBrowser) {
localStorage.setItem("adventures", JSON.stringify(adventures));
}
} }
export function clearAdventures() { export function clearAdventures() {
adventures = []; adventures = [];
if (isBrowser) { if (isBrowser) {
localStorage.setItem('adventures', JSON.stringify(adventures)); localStorage.setItem("adventures", JSON.stringify(adventures));
visitCount.set(0); visitCount.set(0);
} }
} }

View file

@ -1,11 +1,11 @@
import type { Adventure } from '$lib/utils/types'; import type { Adventure } from "$lib/utils/types";
import { getAdventures } from './adventureService'; import { getAdventures } from "./adventureService";
export function exportData() { export function exportData() {
let adventures: Adventure[] = getAdventures() let adventures: Adventure[] = getAdventures();
let jsonArray = JSON.stringify(adventures) let jsonArray = JSON.stringify(adventures);
console.log(jsonArray) console.log(jsonArray);
let blob = new Blob([jsonArray], {type: "application/json"}); let blob = new Blob([jsonArray], { type: "application/json" });
let url = URL.createObjectURL(blob); let url = URL.createObjectURL(blob);
return url return url;
} }

View file

@ -1,12 +1,11 @@
import type { Adventure } from '$lib/utils/types'; import type { Adventure } from "$lib/utils/types";
import { setAdventures } from './adventureService'; import { setAdventures } from "./adventureService";
export function importData(file:File) {
let reader = new FileReader();
reader.onload = function() {
let importArray: Adventure[] = JSON.parse(reader.result as string);
setAdventures(importArray);
}
reader.readAsText(file);
export function importData(file: File) {
let reader = new FileReader();
reader.onload = function () {
let importArray: Adventure[] = JSON.parse(reader.result as string);
setAdventures(importArray);
};
reader.readAsText(file);
} }

View file

@ -1,20 +1,20 @@
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; import { vitePreprocess } from "@sveltejs/vite-plugin-svelte";
import adapterNode from '@sveltejs/adapter-node'; import adapterNode from "@sveltejs/adapter-node";
import adapterVercel from '@sveltejs/adapter-vercel'; import adapterVercel from "@sveltejs/adapter-vercel";
let adapter; let adapter;
if (process.env.USING_VERCEL === 'true') { if (process.env.USING_VERCEL === "true") {
adapter = adapterVercel; adapter = adapterVercel;
} else { } else {
adapter = adapterNode; adapter = adapterNode;
} }
/** @type {import('@sveltejs/kit').Config} */ /** @type {import('@sveltejs/kit').Config} */
const config = { const config = {
preprocess: vitePreprocess(), preprocess: vitePreprocess(),
kit: { kit: {
adapter: adapter() adapter: adapter(),
} },
}; };
export default config; export default config;

View file

@ -1,8 +1,8 @@
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
export default { export default {
content: ['./src/**/*.{html,js,svelte,ts}'], content: ["./src/**/*.{html,js,svelte,ts}"],
theme: { theme: {
extend: {} extend: {},
}, },
plugins: [require("@tailwindcss/typography"), require("daisyui")], plugins: [require("@tailwindcss/typography"), require("daisyui")],
daisyui: { daisyui: {

View file

@ -1,19 +1,19 @@
{ {
"extends": "./.svelte-kit/tsconfig.json", "extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": { "compilerOptions": {
"allowJs": true, "allowJs": true,
"checkJs": true, "checkJs": true,
"esModuleInterop": true, "esModuleInterop": true,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"resolveJsonModule": true, "resolveJsonModule": true,
"skipLibCheck": true, "skipLibCheck": true,
"sourceMap": true, "sourceMap": true,
"strict": true, "strict": true,
"moduleResolution": "bundler" "moduleResolution": "bundler"
} }
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
// except $lib which is handled by https://kit.svelte.dev/docs/configuration#files // except $lib which is handled by https://kit.svelte.dev/docs/configuration#files
// //
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
// from the referenced tsconfig.json - TypeScript does not merge them in // from the referenced tsconfig.json - TypeScript does not merge them in
} }

View file

@ -1,6 +1,6 @@
import { sveltekit } from '@sveltejs/kit/vite'; import { sveltekit } from "@sveltejs/kit/vite";
import { defineConfig } from 'vite'; import { defineConfig } from "vite";
export default defineConfig({ export default defineConfig({
plugins: [sveltekit()] plugins: [sveltekit()],
}); });