Compare commits
No commits in common. "80e1b521373a0bc6966ac3b92f80885844a2f11f" and "712b0a5ef29dd3943c04ce0e5f62f7cf3ac6756f" have entirely different histories.
80e1b52137
...
712b0a5ef2
1
.envrc
1
.envrc
@ -1,2 +1 @@
|
|||||||
export DATABASE_URL=sqlite3:./games.db
|
export DATABASE_URL=sqlite3:./games.db
|
||||||
export VITE_DB_DIR=/dev/
|
|
||||||
|
@ -6,24 +6,6 @@ vars:
|
|||||||
GREETING: Hello, World!
|
GREETING: Hello, World!
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
is-clean: git is-clean
|
|
||||||
integrate:
|
|
||||||
deps: [is-clean, test]
|
|
||||||
cmds:
|
|
||||||
- echo "do something"
|
|
||||||
test:unit:
|
|
||||||
cmds:
|
|
||||||
- vitest run
|
|
||||||
test:
|
|
||||||
deps: [test:unit, test:e2e]
|
|
||||||
preview:
|
|
||||||
deps: [build]
|
|
||||||
cmds:
|
|
||||||
- npm exec vite preview
|
|
||||||
test:e2e:
|
|
||||||
deps: [build]
|
|
||||||
cmds:
|
|
||||||
- npm exec playwright test
|
|
||||||
export-db:
|
export-db:
|
||||||
cmds:
|
cmds:
|
||||||
- sqlite3 /home/bggsell/games.db '.mode json' '.once /home/bggsell/db/games.json' 'select * from game'
|
- sqlite3 /home/bggsell/games.db '.mode json' '.once /home/bggsell/db/games.json' 'select * from game'
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
import { test, expect } from '@playwright/test';
|
|
||||||
|
|
||||||
test('hide game', async ({ page }) => {
|
|
||||||
await page.goto('/');
|
|
||||||
|
|
||||||
let nbr_games = 0;
|
|
||||||
|
|
||||||
await expect(async () => {
|
|
||||||
nbr_games = await page
|
|
||||||
.locator('.game')
|
|
||||||
.all()
|
|
||||||
.then((games) => games.length);
|
|
||||||
expect(nbr_games).toBeGreaterThan(0);
|
|
||||||
}).toPass();
|
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'visibility' }).first().click();
|
|
||||||
|
|
||||||
await expect(async () => {
|
|
||||||
const one_hidden = await page
|
|
||||||
.locator('.game')
|
|
||||||
.all()
|
|
||||||
.then((games) => games.length);
|
|
||||||
|
|
||||||
expect(one_hidden).toEqual(nbr_games - 1);
|
|
||||||
}).toPass({ timeout: 10_000 });
|
|
||||||
});
|
|
12
e2e/test.js
12
e2e/test.js
@ -1,12 +0,0 @@
|
|||||||
import { expect, test } from '@playwright/test';
|
|
||||||
|
|
||||||
for (const url of ['/', '/stats/', '/about/']) {
|
|
||||||
test(url + ' render', async ({ page }) => {
|
|
||||||
await page.goto(url);
|
|
||||||
await expect(
|
|
||||||
page.getByRole('heading', {
|
|
||||||
name: 'Ottawa board games for sale and trade',
|
|
||||||
}),
|
|
||||||
).toBeVisible();
|
|
||||||
});
|
|
||||||
}
|
|
@ -16,7 +16,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@changesets/cli": "^2.27.1",
|
"@changesets/cli": "^2.27.1",
|
||||||
"@playwright/test": "^1.41.2",
|
"@playwright/test": "^1.28.1",
|
||||||
"@sveltejs/kit": "^2.5.0",
|
"@sveltejs/kit": "^2.5.0",
|
||||||
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
||||||
"@types/eslint": "8.56.0",
|
"@types/eslint": "8.56.0",
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
/** @type {import('@playwright/test').PlaywrightTestConfig} */
|
/** @type {import('@playwright/test').PlaywrightTestConfig} */
|
||||||
const config = {
|
const config = {
|
||||||
webServer: {
|
webServer: {
|
||||||
command: 'npm exec vite preview',
|
command: 'npm run build && npm run preview',
|
||||||
port: 4173,
|
port: 4173
|
||||||
reuseExistingServer: true,
|
},
|
||||||
},
|
testDir: 'tests',
|
||||||
testDir: 'e2e',
|
testMatch: /(.+\.)?(test|spec)\.[jt]s/
|
||||||
testMatch: /(.+\.)?(test|spec)\.[jt]s/,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default config;
|
export default config;
|
||||||
|
@ -1,51 +0,0 @@
|
|||||||
import { readable, writable, derived } from 'svelte/store';
|
|
||||||
import { dev, browser } from '$app/environment';
|
|
||||||
import u from '@yanick/updeep-remeda';
|
|
||||||
|
|
||||||
const prefix = import.meta.env.VITE_DB_DIR ?? '/db/';
|
|
||||||
console.log({ prefix });
|
|
||||||
|
|
||||||
const _games_store = readable([], (set) => {
|
|
||||||
if (!browser) return;
|
|
||||||
|
|
||||||
fetch(prefix + 'games.json')
|
|
||||||
.then((doc) => doc.json())
|
|
||||||
.then((games) =>
|
|
||||||
games.map((game) => ({
|
|
||||||
...game,
|
|
||||||
id: [game.username, game.bgg_id].join('!'),
|
|
||||||
})),
|
|
||||||
)
|
|
||||||
.then(set);
|
|
||||||
});
|
|
||||||
|
|
||||||
export const sellers_store = readable({}, (set) => {
|
|
||||||
if (!browser) return;
|
|
||||||
|
|
||||||
fetch(prefix + 'sellers.json')
|
|
||||||
.then((doc) => doc.json())
|
|
||||||
.then((sellers_list) =>
|
|
||||||
set(
|
|
||||||
Object.fromEntries(
|
|
||||||
sellers_list.map((seller) => [seller.username, seller]),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
let stored = localStorage.getItem('games_hidden');
|
|
||||||
if (stored) stored = JSON.parse(stored);
|
|
||||||
const games_hidden_store = writable(stored || {});
|
|
||||||
games_hidden_store.subscribe((data) =>
|
|
||||||
localStorage.setItem('games_hidden', JSON.stringify(data)),
|
|
||||||
);
|
|
||||||
|
|
||||||
export const games_store = derived(
|
|
||||||
[_games_store, games_hidden_store],
|
|
||||||
([$games, $hidden]) =>
|
|
||||||
$games.map((game) => ({ ...game, is_hidden: $hidden[game.id] })),
|
|
||||||
);
|
|
||||||
|
|
||||||
games_store.toggle_hidden = (id) => {
|
|
||||||
games_hidden_store.update(u.updateIn(id, (v) => !v));
|
|
||||||
};
|
|
@ -15,9 +15,49 @@
|
|||||||
import { persisted } from 'svelte-persisted-store';
|
import { persisted } from 'svelte-persisted-store';
|
||||||
import u from '@yanick/updeep-remeda';
|
import u from '@yanick/updeep-remeda';
|
||||||
import AppTop from './AppTop.svelte';
|
import AppTop from './AppTop.svelte';
|
||||||
import { games_store, sellers_store } from '$lib/stores/index.js';
|
|
||||||
setContext('games', games_store);
|
const prefix = dev ? '/dev/' : '/db/';
|
||||||
setContext('sellers', sellers_store);
|
|
||||||
|
const games = readable([], (set) => {
|
||||||
|
if (!browser) return () => {};
|
||||||
|
|
||||||
|
fetch(prefix + 'games.json')
|
||||||
|
.then((doc) => doc.json())
|
||||||
|
.then(set);
|
||||||
|
|
||||||
|
return () => {};
|
||||||
|
});
|
||||||
|
setContext('games', games);
|
||||||
|
|
||||||
|
const sellers = readable({}, (set) => {
|
||||||
|
if (!browser) return () => {};
|
||||||
|
|
||||||
|
const sellers_list = fetch(prefix + 'sellers.json')
|
||||||
|
.then((doc) => doc.json())
|
||||||
|
.then((sellers_list) =>
|
||||||
|
set(
|
||||||
|
Object.fromEntries(
|
||||||
|
sellers_list.map((seller) => [seller.username, seller]),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return () => {};
|
||||||
|
});
|
||||||
|
setContext('sellers', sellers);
|
||||||
|
|
||||||
|
const games_hidden = writable(
|
||||||
|
JSON.parse(localStorage.getItem('games_hidden') || '{}'),
|
||||||
|
);
|
||||||
|
games_hidden.toggle = (username, bgg_id) => {
|
||||||
|
console.log({ username, bgg_id });
|
||||||
|
games_hidden.update(
|
||||||
|
u.updateIn([username, bgg_id].join('!'), (v) => !v),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
setContext('games_hidden', games_hidden);
|
||||||
|
games_hidden.subscribe((data) =>
|
||||||
|
localStorage.setItem('games_hidden', JSON.stringify(data)),
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<article>
|
<article>
|
||||||
{#if $games.length == 0}
|
{#await $games}
|
||||||
<div class="medium-height middle-align center-align">
|
<div class="medium-height middle-align center-align">
|
||||||
<div class="center-align">
|
<div class="center-align">
|
||||||
<progress class="circle"></progress>
|
<progress class="circle"></progress>
|
||||||
@ -7,13 +7,9 @@
|
|||||||
<h5>gathering games...</h5>
|
<h5>gathering games...</h5>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:then games}
|
||||||
<GameList
|
<GameList {games} sellers={$sellers} />
|
||||||
games={$games}
|
{/await}
|
||||||
sellers={$sellers}
|
|
||||||
on:toggle_game_visibility={({ detail }) =>
|
|
||||||
games.toggle_hidden(detail)} />
|
|
||||||
{/if}
|
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -1,114 +0,0 @@
|
|||||||
<div
|
|
||||||
transition:slide={{ delay: 250, duration: 300 }}
|
|
||||||
class:hidden={is_hidden}
|
|
||||||
class="game">
|
|
||||||
<div class="grid top-align">
|
|
||||||
<a
|
|
||||||
class="s12 m2"
|
|
||||||
target="_blank"
|
|
||||||
href={`https://boardgamegeek.com/boardgame/${bgg_id}`}>
|
|
||||||
<img alt="" loading="lazy" src={thumbnail} height="80" /></a>
|
|
||||||
<div class="grid s12 m10">
|
|
||||||
<div class="s8 left-align">
|
|
||||||
<strong>
|
|
||||||
<a
|
|
||||||
class="game-desc"
|
|
||||||
target="_blank"
|
|
||||||
href={`https://boardgamegeek.com/boardgame/${bgg_id}`}>
|
|
||||||
{name}</a>
|
|
||||||
</strong>
|
|
||||||
</div>
|
|
||||||
<div class="s3">
|
|
||||||
<div>
|
|
||||||
<a
|
|
||||||
target="_blank"
|
|
||||||
href={`https://boardgamegeek.com/collection/user/${username}?trade=1&subtype=boardgame&ff=1`}
|
|
||||||
>{username}</a>
|
|
||||||
|
|
||||||
<a
|
|
||||||
target="_blank"
|
|
||||||
href={`https://boardgamegeek.com/geekmail/compose?touser=${username}`}>
|
|
||||||
<i>email</i></a>
|
|
||||||
</div>
|
|
||||||
<div class="neighbourhood">
|
|
||||||
{seller?.neighbourhood ?? ''}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="s1 right-align">
|
|
||||||
{price ? '$' + price : ''}
|
|
||||||
</div>
|
|
||||||
<div class="notes s8">
|
|
||||||
{notes}
|
|
||||||
</div>
|
|
||||||
<div class="s3 updated-at">
|
|
||||||
{#if updated_at}
|
|
||||||
{pretty_date(updated_at)}
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<div class="s1">
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
class="transparent round"
|
|
||||||
title="hide game"
|
|
||||||
on:click={toggle_game_visibility}
|
|
||||||
>{#if is_hidden}<i>visibility_off</i>{:else}
|
|
||||||
<i>visibility</i>
|
|
||||||
{/if}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { createEventDispatcher } from 'svelte';
|
|
||||||
import { slide, fade } from 'svelte/transition';
|
|
||||||
|
|
||||||
export let username = '';
|
|
||||||
export let name = '';
|
|
||||||
export let is_hidden = false;
|
|
||||||
export let bgg_id = '';
|
|
||||||
export let thumbnail = '';
|
|
||||||
export let seller = {};
|
|
||||||
export let price = null;
|
|
||||||
export let notes = '';
|
|
||||||
export let updated_at = null;
|
|
||||||
|
|
||||||
function pretty_date(date) {
|
|
||||||
if (!date) return '';
|
|
||||||
|
|
||||||
return date.replace(/T.*/, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
|
||||||
const toggle_game_visibility = () => dispatch('toggle_visibility');
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
a {
|
|
||||||
color: var(--primary);
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
.grid {
|
|
||||||
margin-right: 2em;
|
|
||||||
font-size: var(--font-size-10);
|
|
||||||
}
|
|
||||||
.notes {
|
|
||||||
margin-top: 1em;
|
|
||||||
margin-left: 1em;
|
|
||||||
}
|
|
||||||
.updated-at {
|
|
||||||
font-size: smaller;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
.updated-at::before {
|
|
||||||
content: 'last update: ';
|
|
||||||
}
|
|
||||||
.neighbourhood {
|
|
||||||
font-size: smaller;
|
|
||||||
}
|
|
||||||
.hidden {
|
|
||||||
opacity: 60%;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -18,32 +18,106 @@
|
|||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.includes(target);
|
.includes(target);
|
||||||
}) as game}
|
}) as game}
|
||||||
{#if show_hidden || !game.is_hidden}
|
{#if show_hidden || !$games_hidden[[game.username, game.bgg_id].join('!')]}
|
||||||
<Game
|
<div
|
||||||
on:toggle_visibility={() => toggle_visibility(game.id)}
|
transition:slide={{ delay: 250, duration: 300 }}
|
||||||
{...game}
|
class:hidden={$games_hidden[
|
||||||
seller={sellers[game.username]} />
|
[game.username, game.bgg_id].join('!')
|
||||||
<div class="medium-divider"></div>
|
]}>
|
||||||
|
<div class="grid top-align">
|
||||||
|
<a
|
||||||
|
class="s12 m2"
|
||||||
|
target="_blank"
|
||||||
|
href={`https://boardgamegeek.com/boardgame/${game.bgg_id}`}>
|
||||||
|
<img
|
||||||
|
loading="lazy"
|
||||||
|
src={game.thumbnail}
|
||||||
|
height="80" /></a>
|
||||||
|
<div class="grid s12 m10">
|
||||||
|
<div class="s8 left-align">
|
||||||
|
<strong>
|
||||||
|
<a
|
||||||
|
class="game-desc"
|
||||||
|
target="_blank"
|
||||||
|
href={`https://boardgamegeek.com/boardgame/${game.bgg_id}`}>
|
||||||
|
{game.name}</a>
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
<div class="s3">
|
||||||
|
<div>
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
href={`https://boardgamegeek.com/collection/user/${game.username}?trade=1&subtype=boardgame&ff=1`}
|
||||||
|
>{game.username}</a>
|
||||||
|
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
href={`https://boardgamegeek.com/geekmail/compose?touser=${game.username}`}>
|
||||||
|
<i>email</i></a>
|
||||||
|
</div>
|
||||||
|
<div class="neighbourhood">
|
||||||
|
{sellers[game.username]?.neighbourhood ?? ''}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="s1 right-align">
|
||||||
|
{game.price ? '$' + game.price : ''}
|
||||||
|
</div>
|
||||||
|
<div class="notes s8">
|
||||||
|
{game.notes}
|
||||||
|
</div>
|
||||||
|
<div class="s3 updated-at">
|
||||||
|
{#if game.updated_at}
|
||||||
|
{pretty_date(game.updated_at)}
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="s1">
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
class="transparent round"
|
||||||
|
title="hide game"
|
||||||
|
on:click={() =>
|
||||||
|
toggle_game_visibility(
|
||||||
|
game.username,
|
||||||
|
game.bgg_id,
|
||||||
|
)}
|
||||||
|
>{#if $games_hidden[[game.username, game.bgg_id].join('!')]}<i
|
||||||
|
>visibility_off</i
|
||||||
|
>{:else}
|
||||||
|
<i>visibility</i>
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="medium-divider"></div>
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getContext, createEventDispatcher } from 'svelte';
|
import { getContext } from 'svelte';
|
||||||
import Game from './Game.svelte';
|
import { slide, fade } from 'svelte/transition';
|
||||||
|
|
||||||
export let games = [];
|
export let games;
|
||||||
export let sellers = {};
|
export let sellers = {};
|
||||||
|
|
||||||
let show_hidden = false;
|
let show_hidden = false;
|
||||||
|
|
||||||
let search_text = '';
|
let search_text = '';
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
|
||||||
const toggle_visibility = (id) => dispatch('toggle_game_visibility', id);
|
|
||||||
|
|
||||||
// add filter
|
// add filter
|
||||||
// add sort (user, game, price)
|
// add sort (user, game, price)
|
||||||
|
|
||||||
|
function pretty_date(date) {
|
||||||
|
if (!date) return '';
|
||||||
|
|
||||||
|
return date.replace(/T.*/, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
const games_hidden = getContext('games_hidden');
|
||||||
|
const toggle_game_visibility = games_hidden.toggle;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -1,162 +0,0 @@
|
|||||||
<div class="options">
|
|
||||||
<label class="switch icon">
|
|
||||||
<input type="checkbox" bind:checked={show_hidden} />
|
|
||||||
<span> show hidden </span>
|
|
||||||
</label>
|
|
||||||
<div class="field label prefix border">
|
|
||||||
<i>search</i>
|
|
||||||
<input type="text" bind:value={search_text} />
|
|
||||||
<label>Search</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="games">
|
|
||||||
{#each games.filter((game) => {
|
|
||||||
if (search_text.length < 3) return true;
|
|
||||||
const target = search_text.toLowerCase();
|
|
||||||
return game.name.toLowerCase().includes(target) || game.username
|
|
||||||
.toLowerCase()
|
|
||||||
.includes(target);
|
|
||||||
}) as game}
|
|
||||||
<<<<<<< HEAD
|
|
||||||
{#if show_hidden || !game.is_hidden}
|
|
||||||
<div
|
|
||||||
transition:slide={{ delay: 250, duration: 300 }}
|
|
||||||
class:hidden={game.is_hidden}>
|
|
||||||
<div class="grid top-align">
|
|
||||||
<a
|
|
||||||
class="s12 m2"
|
|
||||||
target="_blank"
|
|
||||||
href={`https://boardgamegeek.com/boardgame/${game.bgg_id}`}>
|
|
||||||
<img
|
|
||||||
loading="lazy"
|
|
||||||
src={game.thumbnail}
|
|
||||||
height="80" /></a>
|
|
||||||
<div class="grid s12 m10">
|
|
||||||
<div class="s8 left-align">
|
|
||||||
<strong>
|
|
||||||
<a
|
|
||||||
class="game-desc"
|
|
||||||
target="_blank"
|
|
||||||
href={`https://boardgamegeek.com/boardgame/${game.bgg_id}`}>
|
|
||||||
{game.name}</a>
|
|
||||||
</strong>
|
|
||||||
</div>
|
|
||||||
<div class="s3">
|
|
||||||
<div>
|
|
||||||
<a
|
|
||||||
target="_blank"
|
|
||||||
href={`https://boardgamegeek.com/collection/user/${game.username}?trade=1&subtype=boardgame&ff=1`}
|
|
||||||
>{game.username}</a>
|
|
||||||
|
|
||||||
<a
|
|
||||||
target="_blank"
|
|
||||||
href={`https://boardgamegeek.com/geekmail/compose?touser=${game.username}`}>
|
|
||||||
<i>email</i></a>
|
|
||||||
</div>
|
|
||||||
<div class="neighbourhood">
|
|
||||||
{sellers[game.username]?.neighbourhood ?? ''}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="s1 right-align">
|
|
||||||
{game.price ? '$' + game.price : ''}
|
|
||||||
</div>
|
|
||||||
<div class="notes s8">
|
|
||||||
{game.notes}
|
|
||||||
</div>
|
|
||||||
<div class="s3 updated-at">
|
|
||||||
{#if game.updated_at}
|
|
||||||
{pretty_date(game.updated_at)}
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<div class="s1">
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
class="transparent round"
|
|
||||||
title="hide game"
|
|
||||||
on:click={() => toggle_visibility(game.id)}
|
|
||||||
>{#if game.is_hidden}<i>visibility_off</i
|
|
||||||
>{:else}
|
|
||||||
<i>visibility</i>
|
|
||||||
{/if}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="medium-divider"></div>
|
|
||||||
</div>
|
|
||||||
=======
|
|
||||||
{#if show_hidden || !$games_hidden[[game.username, game.bgg_id].join('!')]}
|
|
||||||
<Game />
|
|
||||||
<div class="medium-divider"></div>
|
|
||||||
>>>>>>> 09f4064 (wip)
|
|
||||||
{/if}
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { getContext, createEventDispatcher } from 'svelte';
|
|
||||||
import { slide, fade } from 'svelte/transition';
|
|
||||||
|
|
||||||
export let games = [];
|
|
||||||
export let sellers = {};
|
|
||||||
|
|
||||||
let show_hidden = false;
|
|
||||||
|
|
||||||
let search_text = '';
|
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
|
||||||
const toggle_visibility = (id) => dispatch('toggle_game_visibility', id);
|
|
||||||
|
|
||||||
// add filter
|
|
||||||
// add sort (user, game, price)
|
|
||||||
|
|
||||||
function pretty_date(date) {
|
|
||||||
if (!date) return '';
|
|
||||||
|
|
||||||
return date.replace(/T.*/, '');
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.games {
|
|
||||||
margin-top: 3em;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: var(--primary);
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
.grid {
|
|
||||||
margin-right: 2em;
|
|
||||||
font-size: var(--font-size-10);
|
|
||||||
}
|
|
||||||
.notes {
|
|
||||||
margin-top: 1em;
|
|
||||||
margin-left: 1em;
|
|
||||||
}
|
|
||||||
.updated-at {
|
|
||||||
font-size: smaller;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
.updated-at::before {
|
|
||||||
content: 'last update: ';
|
|
||||||
}
|
|
||||||
.neighbourhood {
|
|
||||||
font-size: smaller;
|
|
||||||
}
|
|
||||||
.hidden {
|
|
||||||
opacity: 60%;
|
|
||||||
}
|
|
||||||
.switch span {
|
|
||||||
font-size: var(--font-size-10);
|
|
||||||
padding-left: 1em;
|
|
||||||
}
|
|
||||||
.options {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row-reverse;
|
|
||||||
}
|
|
||||||
.options > div {
|
|
||||||
margin-right: 1em;
|
|
||||||
}
|
|
||||||
</style>
|
|
6
tests/test.js
Normal file
6
tests/test.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { expect, test } from '@playwright/test';
|
||||||
|
|
||||||
|
test('index page has expected h1', async ({ page }) => {
|
||||||
|
await page.goto('/');
|
||||||
|
await expect(page.getByRole('heading', { name: 'Welcome to SvelteKit' })).toBeVisible();
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user