Added pocket base.
This commit is contained in:
parent
4dd4c22db6
commit
402c65fc90
11
package-lock.json
generated
11
package-lock.json
generated
@ -14,6 +14,7 @@
|
||||
"bulmaswatch": "^0.8.1",
|
||||
"material-dynamic-colors": "^0.0.10",
|
||||
"normalize.css": "^8.0.1",
|
||||
"pocketbase": "^0.7.3",
|
||||
"svelte-spa-router": "^3.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -885,6 +886,11 @@
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/pocketbase": {
|
||||
"version": "0.7.3",
|
||||
"resolved": "https://registry.npmjs.org/pocketbase/-/pocketbase-0.7.3.tgz",
|
||||
"integrity": "sha512-sMbj6uw0f/u9xALsow9b2xlA/6vCB+R0DVswldTxxSBY+HQNz2EyLW2jQu8sMYwo7W0OF2VPyV2Aa+RlhyPoLQ=="
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.17",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.17.tgz",
|
||||
@ -1668,6 +1674,11 @@
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
|
||||
},
|
||||
"pocketbase": {
|
||||
"version": "0.7.3",
|
||||
"resolved": "https://registry.npmjs.org/pocketbase/-/pocketbase-0.7.3.tgz",
|
||||
"integrity": "sha512-sMbj6uw0f/u9xALsow9b2xlA/6vCB+R0DVswldTxxSBY+HQNz2EyLW2jQu8sMYwo7W0OF2VPyV2Aa+RlhyPoLQ=="
|
||||
},
|
||||
"postcss": {
|
||||
"version": "8.4.17",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.17.tgz",
|
||||
|
@ -20,6 +20,7 @@
|
||||
"bulmaswatch": "^0.8.1",
|
||||
"material-dynamic-colors": "^0.0.10",
|
||||
"normalize.css": "^8.0.1",
|
||||
"pocketbase": "^0.7.3",
|
||||
"svelte-spa-router": "^3.3.0"
|
||||
}
|
||||
}
|
||||
|
@ -1,36 +1,60 @@
|
||||
<script>
|
||||
import Router from 'svelte-spa-router';
|
||||
import { replace } from 'svelte-spa-router';
|
||||
import Router from "svelte-spa-router";
|
||||
import { replace, location } from "svelte-spa-router";
|
||||
|
||||
import { isAuthed } from './store';
|
||||
|
||||
import Home from './routes/Home.svelte';
|
||||
import NotFound from './routes/NotFound.svelte';
|
||||
import Budgets from './routes/Budgets.svelte';
|
||||
import Settings from './routes/Settings.svelte';
|
||||
import Timeline from './routes/Timeline.svelte'
|
||||
import Login from './routes/Login.svelte';
|
||||
import Logout from './routes/Logout.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import { pbClient, activeNav } from "./store";
|
||||
|
||||
import Home from "./routes/Home.svelte";
|
||||
import NotFound from "./routes/NotFound.svelte";
|
||||
import Budgets from "./routes/Budgets.svelte";
|
||||
import Settings from "./routes/Settings.svelte";
|
||||
import Timeline from "./routes/Timeline.svelte";
|
||||
import Login from "./routes/Login.svelte";
|
||||
import Logout from "./routes/Logout.svelte";
|
||||
import { onMount } from "svelte";
|
||||
import { authUserID } from "./store";
|
||||
|
||||
const routes = {
|
||||
'/': Home,
|
||||
'/timeline': Timeline,
|
||||
"/budgets": Budgets,
|
||||
'/settings': Settings,
|
||||
'/login': Login,
|
||||
'/logout': Logout,
|
||||
'*': NotFound,
|
||||
}
|
||||
|
||||
onMount(()=> {
|
||||
console.log($isAuthed)
|
||||
if(!$isAuthed){
|
||||
replace('/login')
|
||||
}
|
||||
})
|
||||
"/": Home,
|
||||
"/timeline": Timeline,
|
||||
"/budgets": Budgets,
|
||||
"/settings": Settings,
|
||||
"/login": Login,
|
||||
"/logout": Logout,
|
||||
"*": NotFound,
|
||||
};
|
||||
|
||||
location.subscribe((value) => {
|
||||
switch (value) {
|
||||
case "/":
|
||||
activeNav.set(0);
|
||||
break;
|
||||
case "/budgets":
|
||||
activeNav.set(1);
|
||||
break;
|
||||
case "/timeline":
|
||||
activeNav.set(2);
|
||||
break;
|
||||
case "/settings":
|
||||
activeNav.set(3);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
if (
|
||||
!pbClient.authStore.isValid ||
|
||||
localStorage.getItem("pocketbase_auth") == null
|
||||
) {
|
||||
replace("/login");
|
||||
}
|
||||
|
||||
authUserID.set(
|
||||
JSON.parse(localStorage.getItem("pocketbase_auth")).model.id
|
||||
);
|
||||
});
|
||||
</script>
|
||||
|
||||
<Router {routes}/>
|
||||
|
||||
<Router {routes} />
|
||||
|
@ -6,6 +6,7 @@ export const FAKE_BUDGET_ITEMS = [
|
||||
"isEnabled": true,
|
||||
"entries":[
|
||||
{
|
||||
"budget_item_id": "",
|
||||
"name": "Test Entry",
|
||||
"amount": 20,
|
||||
"description": "Extra info if wanted",
|
||||
|
@ -1,46 +1,29 @@
|
||||
<script>
|
||||
import {link} from 'svelte-spa-router'
|
||||
import { activeNav } from '../store';
|
||||
|
||||
let activeitem = $activeNav;
|
||||
|
||||
function updateActiveItem(num){
|
||||
activeNav.set(num)
|
||||
}
|
||||
import { link } from "svelte-spa-router";
|
||||
import { activeNav } from "../store";
|
||||
|
||||
let activeitem = $activeNav;
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@media only screen and (max-width: 600px){
|
||||
.m:not(.s), .l:not(.s), .m.l:not(.s) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<nav class="m l left">
|
||||
|
||||
<img class="circle" src="/vite.svg" alt="Favicon">
|
||||
<a href="/" class:active="{activeitem === 0}" on:click={()=>updateActiveItem(0)} use:link>
|
||||
<img class="circle" src="/vite.svg" alt="Favicon" />
|
||||
<a href="/" class:active={activeitem === 0} use:link>
|
||||
<i>home</i>
|
||||
<span>Home</span>
|
||||
</a>
|
||||
<a href="/budgets" class:active="{activeitem === 1}" on:click={()=>updateActiveItem(1)} use:link>
|
||||
<a href="/budgets" class:active={activeitem === 1} use:link>
|
||||
<i>payments</i>
|
||||
<span>Budgets</span>
|
||||
</a>
|
||||
<a href="/timeline" class:active="{activeitem === 2}" on:click={()=>updateActiveItem(2)} use:link>
|
||||
<a href="/timeline" class:active={activeitem === 2} use:link>
|
||||
<i>timeline</i>
|
||||
<span>Spending</span>
|
||||
</a>
|
||||
<a href="/settings" class:active="{activeitem === 3}" on:click={()=>updateActiveItem(3)} use:link>
|
||||
<a href="/settings" class:active={activeitem === 3} use:link>
|
||||
<i>settings</i>
|
||||
<span>Settings</span>
|
||||
</a>
|
||||
<div class="max">
|
||||
|
||||
</div>
|
||||
<div class="max" />
|
||||
<a href="/logout" use:link>
|
||||
<i>logout</i>
|
||||
<span>Logout</span>
|
||||
@ -48,20 +31,19 @@
|
||||
</nav>
|
||||
|
||||
<nav class="s bottom">
|
||||
|
||||
<a href="/" class:active="{activeitem === 0}" on:click={()=>updateActiveItem(0)} use:link>
|
||||
<a href="/" class:active={activeitem === 0} use:link>
|
||||
<i>home</i>
|
||||
<span>Home</span>
|
||||
</a>
|
||||
<a href="/budgets" class:active="{activeitem === 1}" on:click={()=>updateActiveItem(1)} use:link>
|
||||
<a href="/budgets" class:active={activeitem === 1} use:link>
|
||||
<i>payments</i>
|
||||
<span>Budgets</span>
|
||||
</a>
|
||||
<a href="/timeline" class:active="{activeitem === 2}" on:click={()=>updateActiveItem(2)} use:link>
|
||||
<a href="/timeline" class:active={activeitem === 2} use:link>
|
||||
<i>timeline</i>
|
||||
<span>Spending</span>
|
||||
</a>
|
||||
<a href="/settings" class:active="{activeitem === 3}" on:click={()=>updateActiveItem(3)} use:link>
|
||||
<a href="/settings" class:active={activeitem === 3} use:link>
|
||||
<i>settings</i>
|
||||
<span>Settings</span>
|
||||
</a>
|
||||
@ -70,3 +52,13 @@
|
||||
<span>Logout</span>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
<style>
|
||||
@media only screen and (max-width: 600px) {
|
||||
.m:not(.s),
|
||||
.l:not(.s),
|
||||
.m.l:not(.s) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,6 +1,33 @@
|
||||
<script>
|
||||
import BaseLayout from "../layouts/BaseLayout.svelte";
|
||||
import { FAKE_BUDGET_ITEMS } from "../fakeData";
|
||||
import { onMount } from "svelte";
|
||||
|
||||
import { pbClient, authUserID } from "../store";
|
||||
|
||||
let budgetItems = [];
|
||||
|
||||
async function disableBudgetItem(recordID) {
|
||||
await pbClient.records.update("eo2i6pm5ldu4tsm_budget_items", recordID, {
|
||||
isEnabled: false,
|
||||
});
|
||||
fetchData();
|
||||
}
|
||||
|
||||
async function enableBudgetItem(recordID) {
|
||||
await pbClient.records.update("eo2i6pm5ldu4tsm_budget_items", recordID, {
|
||||
isEnabled: true,
|
||||
});
|
||||
fetchData();
|
||||
}
|
||||
|
||||
async function fetchData() {
|
||||
const items = await pbClient.records.getList($authUserID + "_budget_items");
|
||||
budgetItems = items.items;
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
fetchData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<BaseLayout>
|
||||
@ -9,38 +36,66 @@
|
||||
</nav>
|
||||
<div class="space" />
|
||||
<hr />
|
||||
<article class="responsive">
|
||||
<table class="border medium-space">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Amount</th>
|
||||
<th />
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each FAKE_BUDGET_ITEMS as ITEM}
|
||||
{#if budgetItems.length == 0}
|
||||
<div class="padding absolute center middle">
|
||||
<!-- svelte-ignore a11y-missing-attribute -->
|
||||
<!-- svelte-ignore a11y-missing-content -->
|
||||
<a class="loader" />
|
||||
</div>
|
||||
{:else}
|
||||
<article class="responsive">
|
||||
<table class="border medium-space">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>{ITEM.key}</td>
|
||||
<td>{ITEM.amount}</td>
|
||||
<td>
|
||||
<nav class="right-align">
|
||||
<button class="none">
|
||||
<i>more_vert</i>
|
||||
<div class="dropdown left no-wrap">
|
||||
<!-- svelte-ignore a11y-missing-attribute -->
|
||||
<a>Edit</a>
|
||||
<!-- svelte-ignore a11y-missing-attribute -->
|
||||
<a>Disable</a>
|
||||
<!-- svelte-ignore a11y-missing-attribute -->
|
||||
<a>Delete</a>
|
||||
</div>
|
||||
</button>
|
||||
</nav>
|
||||
</td>
|
||||
<th>Enabled</th>
|
||||
<th>Name</th>
|
||||
<th>Amount</th>
|
||||
<th />
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</article>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each budgetItems as ITEM}
|
||||
<tr>
|
||||
<td>
|
||||
<label class="switch">
|
||||
{#if ITEM.isEnabled}
|
||||
<input
|
||||
type="checkbox"
|
||||
checked
|
||||
on:change={() => disableBudgetItem(ITEM.id)}
|
||||
/>
|
||||
{:else}
|
||||
<input
|
||||
type="checkbox"
|
||||
on:change={() => enableBudgetItem(ITEM.id)}
|
||||
/>
|
||||
{/if}
|
||||
<span />
|
||||
</label>
|
||||
</td>
|
||||
<td>
|
||||
<p>{ITEM.name}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>{ITEM.amount}</p>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<nav class="right-align">
|
||||
<!-- svelte-ignore a11y-missing-attribute -->
|
||||
<a>
|
||||
<i>edit</i>
|
||||
</a>
|
||||
<!-- svelte-ignore a11y-missing-attribute -->
|
||||
<a>
|
||||
<i>delete</i>
|
||||
</a>
|
||||
</nav>
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</article>
|
||||
{/if}
|
||||
</BaseLayout>
|
||||
|
@ -1,10 +1,19 @@
|
||||
<script>
|
||||
import { onMount } from "svelte";
|
||||
import BaseLayout from "../layouts/BaseLayout.svelte";
|
||||
import { pbClient, authUserID } from '../store'
|
||||
|
||||
let userName = "";
|
||||
|
||||
onMount(async ()=>{
|
||||
const user = await pbClient.users.getOne($authUserID);
|
||||
userName = user.profile.name;
|
||||
})
|
||||
</script>
|
||||
|
||||
<BaseLayout>
|
||||
<div>
|
||||
Home
|
||||
Welcome: {userName}
|
||||
</div>
|
||||
</BaseLayout>
|
||||
|
||||
|
@ -1,11 +1,14 @@
|
||||
<script>
|
||||
import { replace } from 'svelte-spa-router';
|
||||
import { isAuthed } from '../store';
|
||||
import NoNavLayout from '../layouts/NoNavLayout.svelte';
|
||||
import { pbClient, authUserID } from '../store';
|
||||
|
||||
function doLogin(){
|
||||
let userName = "";
|
||||
let userPassword = "";
|
||||
|
||||
async function doLogin(){
|
||||
const userAuthData = await pbClient.users.authViaEmail(userName, userPassword);
|
||||
replace("/");
|
||||
isAuthed.set(true);
|
||||
}
|
||||
|
||||
</script>
|
||||
@ -17,12 +20,12 @@
|
||||
|
||||
<p>Username:</p>
|
||||
<div class="field border">
|
||||
<input type="text">
|
||||
<input bind:value={userName} type="text">
|
||||
</div>
|
||||
|
||||
<p>Password:</p>
|
||||
<div class="field border">
|
||||
<input type="text">
|
||||
<input bind:value={userPassword} type="password">
|
||||
</div>
|
||||
|
||||
<button class="responsive" on:click={doLogin}>
|
||||
|
@ -1,9 +1,12 @@
|
||||
import { writable } from 'svelte/store';
|
||||
import PocketBase from 'pocketbase';
|
||||
export const pbClient = new PocketBase('https://pb.thomaspcole.com');
|
||||
|
||||
export const isAuthed = writable(false);
|
||||
export const activeNav = writable(0);
|
||||
export const authUserID = writable("");
|
||||
|
||||
|
||||
export function resetStore() {
|
||||
isAuthed.set(false);
|
||||
pbClient.authStore.clear();
|
||||
activeNav.set(0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user