Skip to content

Commit

Permalink
fix(console): w.i.p
Browse files Browse the repository at this point in the history
  • Loading branch information
xmlking committed Jun 24, 2024
1 parent 5668c68 commit ff8263f
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 32 deletions.
1 change: 0 additions & 1 deletion apps/console/src/lib/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export { default as Meta } from './layout/meta.svelte';
export { default as SectionFrame } from './layout/section-frame.svelte';
34 changes: 34 additions & 0 deletions apps/console/src/routes/(app)/profile/+page.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
query GetUser($userId: uuid!) @cache(policy: CacheAndNetwork) {
# get all gragments needed for profile page.
user(id: $userId) {
id
displayName
email
phoneNumber
defaultOrg
defaultRole
avatarUrl
locale
plan: metadata(path: ".plan")
userOrgRoles(order_by: {organization: asc}) {
organization
role
isDefaultRole
}
securityKeys(order_by: { nickname: asc }) @list(name: "SecurityKeys") {
...SecurityKey
# nickname
# id
}
personalAccessTokens: refreshTokens {
id
metadata(path: ".name")
}
userProviders {
id
providerId
providerUserId
updatedAt
}
}
}
74 changes: 57 additions & 17 deletions apps/console/src/routes/(app)/profile/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,39 +1,79 @@
<script lang="ts">
import { Debug } from '@spectacular/skeleton/components';
import { page } from '$app/stores';
import { Meta } from '$lib/components';
import { nhost, user } from '$lib/stores/user';
import type { AuthErrorPayload } from '@nhost/nhost-js';
import { Avatar } from '@skeletonlabs/skeleton';
import { Debug } from '@spectacular/skeleton/components';
import SecurityKeysCard from './security-keys.svelte';
import type { PageData } from './$houdini';
// https://github.com/nhost/nhost/blob/main/examples/react-apollo/src/profile/security-keys.tsx
export let data
export let data: PageData;
let nickname: string
let error : AuthErrorPayload | null
$: ({ GetUser } = data);
$: securityKeys = $GetUser.data?.user?.securityKeys ?? [];
async function addSecurityKey() {
console.log({nickname})
const { key, error: addKeyError } = await nhost.auth.addSecurityKey(nickname)
// Something unexpected happened
if (error) {
console.log(error)
error = addKeyError
return
}
// Successfully added a new security key
console.log(key?.id)
// Variables
let nickname: string;
let error: AuthErrorPayload | null;
// Functions
async function addSecurityKey() {
console.log({ nickname });
const { key, error: addKeyError } = await nhost.auth.addSecurityKey(nickname);
// Something unexpected happened
if (error) {
console.log(error);
error = addKeyError;
return;
}
// Successfully added a new security key
console.log(key?.id);
}
// Reactivity
$: meta = {
title: 'Datablocks | Profile',
canonical: $page.url.toString(),
};
</script>

<Meta {...meta} />

<svelte:head>
<title>Datablocks | Profile</title>
<meta name="description" content="Account Profile" />
</svelte:head>



<div class="page-container">

<section class="rounded-lg bg-slate-50">aaa</section>

{#if $GetUser.fetching}
<span>loading...</span>
{:else}
<section>
<span>done....</span>
<div class="relative inline-block">
<span class="badge-icon variant-filled-warning absolute -top-0 -right-0 z-10">2</span>
<Avatar />
</div>
<!-- {$GetUser.data....} -->
</section>

<section class="rounded-lg bg-slate-50">
<SecurityKeysCard {securityKeys} />
</section>
{/if}

<div class="page-section">
<h2 class="h2">Profile</h2>
<Debug data={$user} />
</div>
<div class="page-section">
<section class="page-section">
<h3 class="h3">WebAuthn</h3>
<div class="card p-4">
<title>Security keys</title>
Expand Down Expand Up @@ -64,6 +104,6 @@ export let data
<button type="submit" class="btn variant-filled">Add a new device</button>
</form>
</div>
</div>
</section>
</div>

33 changes: 19 additions & 14 deletions apps/console/src/routes/(app)/profile/+page.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
import { CachePolicy, ListSecurityKeysStore, order_by } from '$houdini';
import { i18n } from '$lib/i18n.js';
import { changeEmailSchema, changePasswordSchema, webAuthnSchema } from '$lib/schema/user';
import { isAuthenticated } from '$lib/stores/user';
import { isAuthenticated, user } from '$lib/stores/user';
import { Logger } from '@spectacular/utils';
import { error } from '@sveltejs/kit';
import { redirect } from '@sveltejs/kit';
import { get } from 'svelte/store';
import { setError, setMessage, superValidate } from 'sveltekit-superforms';
import { zod } from 'sveltekit-superforms/adapters';
const log = new Logger('user.profile.browser');

const searchPoliciesStore = new ListSecurityKeysStore();
import type { BeforeLoadEvent, GetUserVariables as Variables } from './$houdini';

export const load = async (event) => {
const {
url: { pathname },
} = event;
const log = new Logger('user.profile.browser');

if (!isAuthenticated) {
redirect(303, i18n.resolveRoute(`/signin?redirectTo=${pathname}`));
export const _GetUserVariables: Variables = async (event) => {
const userId = get(user)?.id;
if (!userId) {
log.error('not authenticated');
throw error(400, 'not authenticated');
}
return { userId };
};

export async function _houdini_beforeLoad({ url }: BeforeLoadEvent) {
if (!get(isAuthenticated)) redirect(302, i18n.resolveRoute('/signin?redirectTo=/profile'));
const cpForm = await superValidate(zod(changePasswordSchema));
const ceForm = await superValidate(zod(changeEmailSchema));
const waForm = await superValidate(zod(webAuthnSchema));
const items = {}; // data?.policies;
return { cpForm, ceForm, waForm, items };
};
return { cpForm, ceForm, waForm };
}

// export async function _houdini_afterLoad({ event, input, data }: AfterLoadEvent) {
// }
54 changes: 54 additions & 0 deletions apps/console/src/routes/(app)/profile/security-key.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<script lang="ts">
import { fade } from 'svelte/transition';
import { RemoveSecurityKeyStore, fragment, graphql } from '$houdini';
import { Logger } from '@spectacular/utils';
import type { SecurityKey } from '$houdini';
const log = new Logger('auth:profile:browser');
let isDeleting = false;
export let securityKey: SecurityKey;
$: data = fragment(
securityKey,
graphql`
fragment SecurityKey on authUserSecurityKeys {
nickname
id
}
`,
);
const deleteSecurityKey = new RemoveSecurityKeyStore();
const handleDelete = async () => {
// before
isDeleting = true;
const { errors } = await deleteSecurityKey.mutate({ id: $data.id });
if (errors?.length) {
log.error({errors})
// window.location.reload();
return;
}
// after
// No need to reset as comments disappear.
};
</script>

<div class="relative">
<div class="flex items-center">
<p class="font-bold">{$data.nickname}</p>
<!-- <time class="ml-2 text-sm font-medium text-zinc-500" title={createdAt.toISO()}>
{createdAt.toFormat('MM/dd/yyyy')}
</time> -->
</div>

<div class="absolute bottom-0 right-0" transition:fade={{ duration: 75 }}>
<button on:click={handleDelete} disabled={isDeleting}>Delete</button>
</div>

</div>
24 changes: 24 additions & 0 deletions apps/console/src/routes/(app)/profile/security-keys.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script lang="ts">
import SecurityKeyItem from './security-key.svelte';
import { quintOut } from 'svelte/easing';
import { flip } from 'svelte/animate';
import { fade } from 'svelte/transition';
import type { SecurityKey } from '$houdini';
export const defaultDE = {
duration: 450,
easing: quintOut,
};
export let securityKeys: SecurityKey[];
</script>

<div class="divide-y divide-slate-200">
{#each securityKeys as securityKey (securityKey.id)}
<div transition:fade={defaultDE} animate:flip={defaultDE}>
<SecurityKeyItem {securityKey} />
</div>
{/each}
</div>

0 comments on commit ff8263f

Please sign in to comment.