Skip to content

Commit

Permalink
feat: domain submissions page
Browse files Browse the repository at this point in the history
  • Loading branch information
xynydev committed Dec 15, 2024
1 parent ced7d79 commit 0820fd0
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 5 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-svelte": "^2.45.1",
"globals": "^15.0.0",
"lucide-svelte": "^0.439.0",
"prettier": "^3.1.1",
"prettier-plugin-svelte": "^3.2.6",
"prettier-plugin-tailwindcss": "^0.6.5",
Expand All @@ -45,7 +46,6 @@
"@fontsource/hind-vadodara": "^5.1.0",
"@sveltejs/adapter-node": "^5.2.2",
"clsx": "^2.1.1",
"lucide-svelte": "^0.439.0",
"mode-watcher": "^0.4.1",
"tailwind-merge": "^2.5.2",
"tailwind-variants": "^0.2.1"
Expand Down
6 changes: 3 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

143 changes: 143 additions & 0 deletions src/routes/(nosearch)/domain-submissions/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
<script lang="ts">
import Button from '@/components/ui/button/button.svelte';
import Input from '@/components/ui/input/input.svelte';
import RiArrowDropLeftLine from '~icons/ri/arrow-drop-left-line';
import RiArrowDropRightLine from '~icons/ri/arrow-drop-right-line';
import RiLinksLine from '~icons/ri/links-line';
import RiLoader2Line from '~icons/ri/loader-2-line';
import type { SubmissionsResult } from './+page.js';
let { data } = $props();
let domainInput: string = $state('');
let submissionsForInput: Promise<SubmissionsResult> = $state(
Promise.resolve({ items: [], count: 0 })
);
async function fetchSubmissionsForInput() {
const res = await fetch(
'https://api.mwmbl.org/api/v1/platform/domain-submissions/domains/' + domainInput
);
if (res.ok) {
const submissions: SubmissionsResult = await res.json();
return submissions;
} else {
return { items: [], count: 0 };
}
}
// Allow API only to be called once every X ms
let debounceTimer = 0;
function debounce(callback: Function, ms: number) {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(callback, ms);
}
// TODO implement domain submission (server actions)
function submitDomain() {}
</script>

{#snippet submissions(submissions: SubmissionsResult)}
<ul class="grid w-fit grid-cols-[16rem,1fr,1fr] gap-2 pr-16">
{#each submissions.items as item}
<li class="contents">
<div class="grid grid-cols-[7rem,1fr] gap-x-2">
<div
class={`col-span-2 flex flex-col justify-center rounded-2xl p-2 px-4 ${item.status == 'APPROVED' ? ' bg-green-300' : item.status == 'REJECTED' ? ' !col-span-1 bg-red-300' : ' bg-gray-300'}`}
>
{item.status}
</div>
{#if item.status == 'REJECTED'}
<div class="mr-2 flex flex-col">
<div>reason: {item.rejection_reason}</div>
{#if item.rejection_detail}
<div>detail: {item.rejection_detail}</div>
{/if}
</div>
{/if}
</div>
<div class="flex flex-row items-center gap-2 pr-4">
<span>{item.name}</span>
</div>
<div class="flex flex-row items-center gap-2">
{new Date(item.submitted_on).toISOString().slice(0, 10)},
{new Date(item.submitted_on).toISOString().slice(11, 16)} (UTC)
</div>
</li>
{/each}
</ul>
{/snippet}

<main class="flex w-full max-w-4xl flex-col gap-2 self-center px-6">
<h2 class="-mx-2 text-3xl">Domain submissions</h2>
<hr class="my-2" />
<div class="w-full rounded-2xl bg-white p-4">
<h3 class="text-2xl">Submit domain</h3>
<hr class="my-2" />
<Input
class="mt-4"
type="text"
placeholder="example.org"
bind:value={domainInput}
onkeyup={() => {
submissionsForInput = new Promise(() => {});
debounce(() => (submissionsForInput = fetchSubmissionsForInput()), 500);
}}
/>
<div class="mt-2 p-2">
{#await submissionsForInput}
<RiLoader2Line class="h-8 w-8 animate-spin" />
{:then submissionsForInput}
{#if submissionsForInput.count > 0}
<div class="mb-4">Found {submissionsForInput.count} pre-existing submission(s)</div>
{@render submissions(submissionsForInput)}
{#if domainInput.length > 0}
<Button
title="unimplemented"
variant="secondary"
class="mt-6 flex w-full flex-row items-center gap-2 dark:bg-muted"
>
<RiLinksLine class="min-h-5 min-w-5 text-black dark:text-white" />
Resubmit Domain
</Button>
{/if}
{:else}
Found no pre-existing submission(s)
{#if domainInput.length > 0}
<Button
title="unimplemented"
variant="secondary"
class="mt-6 flex w-full flex-row items-center gap-2 dark:bg-muted"
>
<RiLinksLine class="min-h-5 min-w-5 text-black dark:text-white" />
Submit Domain
</Button>
{/if}
{/if}
{/await}
</div>
</div>
{@render submissions(data.submissions)}
<div class="flex flex-row items-center justify-center gap-4 p-4">
<Button
href={data.page == 0 ? '' : `?page=${data.page - 1}`}
variant="ghost"
class={data.page == 0 ? 'cursor-not-allowed opacity-75' : ''}
>
<RiArrowDropLeftLine class="h-4 w-4" /> Previous
</Button>
<Button variant="outline" size="icon" href="?page=0">0</Button>
...
<Button variant="outline" size="icon" href="?page={data.maxPage}">{data.maxPage}</Button>
<Button
href={data.page == data.maxPage ? '' : `?page=${data.page + 1}`}
variant="ghost"
class={data.page == data.maxPage ? 'cursor-not-allowed opacity-75' : ''}
>
Next <RiArrowDropRightLine class="h-4 w-4" />
</Button>
</div>
</main>
32 changes: 32 additions & 0 deletions src/routes/(nosearch)/domain-submissions/+page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const pageSize = 500;

export type SubmissionsResult = {
items: Array<{
id: number;
name: string;
submitted_by: number;
submitted_on: string;
status: string;
rejection_reason: string;
rejection_detail: string;
}>;
count: number;
};

export async function load({ fetch, url }) {
const page = Number(url.searchParams.get('page'));
const offset = page * pageSize;
const response = await fetch(
`https://api.mwmbl.org/api/v1/platform/domain-submissions?limit=${pageSize}&offset=${offset}`
);
const submissions: SubmissionsResult = await response.json();

return {
submissions,
page,
maxPage: Math.floor(submissions.count / pageSize)
};
}
// export const actions: Actions = {
// submitDomain: async ({ cookies, locals }) => {}
// };
10 changes: 9 additions & 1 deletion src/routes/search/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,17 @@
<MobileMenu status={data.status} />
</div>
<div class="mb-0 flex flex-row gap-4 max-lg:row-start-3 lg:col-start-2 lg:col-end-2">
<Button href="/" variant="secondary" class="flex flex-row items-center gap-2 dark:bg-muted">
<!-- <Button href="/" variant="secondary" class="flex flex-row items-center gap-2 dark:bg-muted">
<RiLinksLine class="min-h-5 min-w-5 text-black dark:text-white" />
Submit URL
</Button> -->
<Button
href="/domain-submissions"
variant="secondary"
class="flex flex-row items-center gap-2 dark:bg-muted"
>
<RiLinksLine class="min-h-5 min-w-5 text-black dark:text-white" />
Submit Domain
</Button>
<Popover.Root>
<Popover.Trigger asChild let:builder>
Expand Down

0 comments on commit 0820fd0

Please sign in to comment.