mirror of
https://github.com/acid-info/Kurate.git
synced 2025-01-13 01:14:12 +00:00
feat: epic 6 (#67)
This commit is contained in:
parent
8248633887
commit
4f93342883
18
src/lib/components/icons/logout.svelte
Normal file
18
src/lib/components/icons/logout.svelte
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { IconProps } from '$lib/types'
|
||||||
|
|
||||||
|
type $$Props = IconProps
|
||||||
|
|
||||||
|
let cls: string | undefined = undefined
|
||||||
|
export { cls as class }
|
||||||
|
export let size = 20
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width={size} height={size} class={cls}>
|
||||||
|
<path
|
||||||
|
d="M6,30H18a2.0023,2.0023,0,0,0,2-2V25H18v3H6V4H18V7h2V4a2.0023,2.0023,0,0,0-2-2H6A2.0023,2.0023,0,0,0,4,4V28A2.0023,2.0023,0,0,0,6,30Z"
|
||||||
|
/>
|
||||||
|
<polygon
|
||||||
|
points="20.586 20.586 24.172 17 10 17 10 15 24.172 15 20.586 11.414 22 10 28 16 22 22 20.586 20.586"
|
||||||
|
/>
|
||||||
|
</svg>
|
15
src/lib/components/icons/undo.svelte
Normal file
15
src/lib/components/icons/undo.svelte
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { IconProps } from '$lib/types'
|
||||||
|
|
||||||
|
type $$Props = IconProps
|
||||||
|
|
||||||
|
let cls: string | undefined = undefined
|
||||||
|
export { cls as class }
|
||||||
|
export let size = 20
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width={size} height={size} class={cls}>
|
||||||
|
<path
|
||||||
|
d="M20,10H7.8149l3.5874-3.5859L10,5,4,11,10,17l1.4023-1.4146L7.8179,12H20a6,6,0,0,1,0,12H12v2h8a8,8,0,0,0,0-16Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
@ -2,6 +2,7 @@ export const ROUTES = {
|
|||||||
HOME: '/',
|
HOME: '/',
|
||||||
PROFILE: '/profile',
|
PROFILE: '/profile',
|
||||||
PROFILE_ADDRESS: (address: string) => `/profile/${address}`,
|
PROFILE_ADDRESS: (address: string) => `/profile/${address}`,
|
||||||
PROFILE_NEW: '/profile/new',
|
IDENTITY: '/identity',
|
||||||
|
IDENTITY_NEW: '/identity/new',
|
||||||
POST_NEW: '/post/new',
|
POST_NEW: '/post/new',
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,9 @@ import { writable, type Writable } from 'svelte/store'
|
|||||||
import type { User } from './user'
|
import type { User } from './user'
|
||||||
|
|
||||||
export interface Profile {
|
export interface Profile {
|
||||||
key?: boolean // FIXME: this will need to change
|
key?: {
|
||||||
|
publicKey: string
|
||||||
|
}
|
||||||
profiles: User[]
|
profiles: User[]
|
||||||
active?: User
|
active?: User
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<Header user={$profile.active} />
|
<Header user={$profile.active} />
|
||||||
{#if $profile.active !== undefined}
|
{#if $profile.active !== undefined}
|
||||||
<div>
|
<div>
|
||||||
<Avatar src={$profile.active.avatar} />
|
<Avatar src={$profile.active.avatar} on:click={() => goto(ROUTES.PROFILE)} />
|
||||||
Share freely...
|
Share freely...
|
||||||
<Button
|
<Button
|
||||||
variant="primary"
|
variant="primary"
|
||||||
@ -27,7 +27,7 @@
|
|||||||
on:click={() => goto(ROUTES.POST_NEW)}
|
on:click={() => goto(ROUTES.POST_NEW)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{:else if $profile.key === true}
|
{:else if $profile.key?.publicKey !== undefined}
|
||||||
<div>
|
<div>
|
||||||
<Button
|
<Button
|
||||||
variant="primary"
|
variant="primary"
|
||||||
|
71
src/routes/identity/+page.svelte
Normal file
71
src/routes/identity/+page.svelte
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { goto } from '$app/navigation'
|
||||||
|
import Button from '$lib/components/button.svelte'
|
||||||
|
import Close from '$lib/components/icons/close.svelte'
|
||||||
|
import CodeSigningService from '$lib/components/icons/code-signing-service.svelte'
|
||||||
|
import GroupSecurity from '$lib/components/icons/group-security.svelte'
|
||||||
|
import Identity from '$lib/components/identity.svelte'
|
||||||
|
import { ROUTES } from '$lib/routes'
|
||||||
|
import { profile } from '$lib/stores/profile'
|
||||||
|
import type { User } from '$lib/stores/user'
|
||||||
|
|
||||||
|
const onSelectIdentityClick = (id: User) => {
|
||||||
|
$profile.active = id
|
||||||
|
history.back()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="header">
|
||||||
|
<h1>{$profile.key ? 'Choose' : 'Create'} identity</h1>
|
||||||
|
<Button icon={Close} on:click={() => history.back()} />
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
{#if $profile.key}
|
||||||
|
{#each $profile.profiles as p}
|
||||||
|
<Identity identity={p} click={onSelectIdentityClick} />
|
||||||
|
{/each}
|
||||||
|
<Button
|
||||||
|
icon={GroupSecurity}
|
||||||
|
label="Create new identity"
|
||||||
|
on:click={() => goto(ROUTES.IDENTITY_NEW)}
|
||||||
|
/>
|
||||||
|
<span>You can create multiple identities under the same account.</span>
|
||||||
|
<a href="/">Learn more about identities.</a>
|
||||||
|
{:else}
|
||||||
|
<div class="icon">
|
||||||
|
<GroupSecurity size={200} />
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant="primary"
|
||||||
|
icon={CodeSigningService}
|
||||||
|
label="Generate new keypair"
|
||||||
|
on:click={() => {
|
||||||
|
$profile.key = { publicKey: '0x90b1c0A1EeF1fe519AeE75D2Ee04855219923f26' }
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
>You need to generate a new address to be associated with your identity. This address will
|
||||||
|
different that your account address.</span
|
||||||
|
>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.header {
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.icon :global(svg) {
|
||||||
|
fill: grey;
|
||||||
|
}
|
||||||
|
</style>
|
@ -5,11 +5,10 @@
|
|||||||
import Input from '$lib/components/input.svelte'
|
import Input from '$lib/components/input.svelte'
|
||||||
import InputFile from '$lib/components/input-file.svelte'
|
import InputFile from '$lib/components/input-file.svelte'
|
||||||
import Image from '$lib/components/icons/image.svelte'
|
import Image from '$lib/components/icons/image.svelte'
|
||||||
|
import Renew from '$lib/components/icons/renew.svelte'
|
||||||
import InputString from '$lib/components/input-string.svelte'
|
import InputString from '$lib/components/input-string.svelte'
|
||||||
import { profile } from '$lib/stores/profile'
|
import { profile } from '$lib/stores/profile'
|
||||||
import { formatAddress } from '$lib/utils'
|
import { formatAddress } from '$lib/utils'
|
||||||
import { goto } from '$app/navigation'
|
|
||||||
import { ROUTES } from '$lib/routes'
|
|
||||||
|
|
||||||
const generateRandomHex = (size: number) =>
|
const generateRandomHex = (size: number) =>
|
||||||
`0x${[...Array(size)].map(() => Math.floor(Math.random() * 16).toString(16)).join('')}`
|
`0x${[...Array(size)].map(() => Math.floor(Math.random() * 16).toString(16)).join('')}`
|
||||||
@ -28,7 +27,7 @@
|
|||||||
|
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<h1>Create identity</h1>
|
<h1>Create identity</h1>
|
||||||
<Button icon={Close} on:click={() => goto(ROUTES.PROFILE)} />
|
<Button icon={Close} on:click={() => history.back()} />
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<Input title="Public address">
|
<Input title="Public address">
|
||||||
@ -43,8 +42,10 @@
|
|||||||
<div class="profile">
|
<div class="profile">
|
||||||
{#if image !== undefined}
|
{#if image !== undefined}
|
||||||
<img src={image} alt={file?.name} />
|
<img src={image} alt={file?.name} />
|
||||||
|
<InputFile bind:files label="Change" icon={Renew} variant="secondary" />
|
||||||
|
{:else}
|
||||||
|
<InputFile bind:files label="Add image..." icon={Image} variant="secondary" />
|
||||||
{/if}
|
{/if}
|
||||||
<InputFile bind:files label="Add image..." icon={Image} variant="secondary" />
|
|
||||||
</div>
|
</div>
|
||||||
{#if file !== undefined}
|
{#if file !== undefined}
|
||||||
<span>{file.name}</span>
|
<span>{file.name}</span>
|
||||||
@ -60,7 +61,7 @@
|
|||||||
on:click={() => {
|
on:click={() => {
|
||||||
const user = { address, name, avatar: image }
|
const user = { address, name, avatar: image }
|
||||||
$profile.profiles = [...$profile.profiles, user]
|
$profile.profiles = [...$profile.profiles, user]
|
||||||
goto(ROUTES.PROFILE)
|
history.back()
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
@ -36,7 +36,7 @@
|
|||||||
<Avatar src={$profile.active?.avatar} on:click={() => goto(ROUTES.PROFILE)} />
|
<Avatar src={$profile.active?.avatar} on:click={() => goto(ROUTES.PROFILE)} />
|
||||||
<div>{$profile.active?.name}</div>
|
<div>{$profile.active?.name}</div>
|
||||||
<div>{$profile.active?.address}</div>
|
<div>{$profile.active?.address}</div>
|
||||||
<Button variant="secondary" icon={Collaborate} on:click={() => goto(ROUTES.PROFILE)} />
|
<Button variant="secondary" icon={Collaborate} on:click={() => goto(ROUTES.IDENTITY)} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<InputString bind:value={postText} placeholder="Write here..." />
|
<InputString bind:value={postText} placeholder="Write here..." />
|
||||||
|
@ -1,52 +1,85 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { goto } from '$app/navigation'
|
import { goto } from '$app/navigation'
|
||||||
|
import Avatar from '$lib/components/avatar.svelte'
|
||||||
import Button from '$lib/components/button.svelte'
|
import Button from '$lib/components/button.svelte'
|
||||||
import Close from '$lib/components/icons/close.svelte'
|
import Collaborate from '$lib/components/icons/collaborate.svelte'
|
||||||
import CodeSigningService from '$lib/components/icons/code-signing-service.svelte'
|
import Logout from '$lib/components/icons/logout.svelte'
|
||||||
import GroupSecurity from '$lib/components/icons/group-security.svelte'
|
import Image from '$lib/components/icons/image.svelte'
|
||||||
import Identity from '$lib/components/identity.svelte'
|
import Undo from '$lib/components/icons/undo.svelte'
|
||||||
|
import Wallet from '$lib/components/icons/wallet.svelte'
|
||||||
|
import InputFile from '$lib/components/input-file.svelte'
|
||||||
|
import InputString from '$lib/components/input-string.svelte'
|
||||||
|
import Input from '$lib/components/input.svelte'
|
||||||
import { ROUTES } from '$lib/routes'
|
import { ROUTES } from '$lib/routes'
|
||||||
import { profile } from '$lib/stores/profile'
|
import { profile } from '$lib/stores/profile'
|
||||||
import type { User } from '$lib/stores/user'
|
import Renew from '$lib/components/icons/renew.svelte'
|
||||||
|
|
||||||
const onSelectIdentityClick = (id: User) => {
|
let files: FileList | undefined = undefined
|
||||||
$profile.active = id
|
let file: File | undefined = undefined
|
||||||
history.back()
|
|
||||||
}
|
$: file = files && files[0]
|
||||||
|
$: if ($profile.active && file) $profile.active.avatar = URL.createObjectURL(file)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<h1>{$profile.key ? 'Choose' : 'Create'} identity</h1>
|
<div>
|
||||||
<Button icon={Close} on:click={() => history.back()} />
|
<Button icon={Undo} on:click={() => history.back()} />
|
||||||
|
<h1>Account</h1>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant="primary"
|
||||||
|
icon={Logout}
|
||||||
|
label="Logout"
|
||||||
|
on:click={() => ($profile.key = undefined)}
|
||||||
|
disabled={!$profile.key}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
{#if $profile.key}
|
{#if $profile.key?.publicKey === undefined}
|
||||||
{#each $profile.profiles as p}
|
|
||||||
<Identity identity={p} click={onSelectIdentityClick} />
|
|
||||||
{/each}
|
|
||||||
<Button
|
|
||||||
icon={GroupSecurity}
|
|
||||||
label="Create new identity"
|
|
||||||
on:click={() => goto(ROUTES.PROFILE_NEW)}
|
|
||||||
/>
|
|
||||||
<span>You can create multiple identities under the same account.</span>
|
|
||||||
<a href="/">Learn more about identities.</a>
|
|
||||||
{:else}
|
|
||||||
<div class="icon">
|
|
||||||
<GroupSecurity size={200} />
|
|
||||||
</div>
|
|
||||||
<Button
|
<Button
|
||||||
variant="primary"
|
variant="primary"
|
||||||
icon={CodeSigningService}
|
icon={Wallet}
|
||||||
label="Generate new keypair"
|
label="Connect wallet to post"
|
||||||
on:click={() => {
|
on:click={() => ($profile.key = { publicKey: '0x90b1c0A1EeF1fe519AeE75D2Ee04855219923f26' })}
|
||||||
$profile.key = true
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
<span
|
<span>Connect a wallet to access or create your account.</span>
|
||||||
>You need to generate a new address to be associated with your identity. This address will
|
{:else}
|
||||||
different that your account address.</span
|
<span>Wallet & Identity</span>
|
||||||
>
|
<Input title="Connected wallet">
|
||||||
|
<span>{$profile.key.publicKey}</span>
|
||||||
|
</Input>
|
||||||
|
{#if $profile.active === undefined}
|
||||||
|
<Button
|
||||||
|
variant="primary"
|
||||||
|
icon={Collaborate}
|
||||||
|
label="Select identity"
|
||||||
|
on:click={() => goto(ROUTES.IDENTITY)}
|
||||||
|
/>
|
||||||
|
<span>Select an identity to use with your account.</span>
|
||||||
|
{:else}
|
||||||
|
<div>
|
||||||
|
<span>Selected identity</span>
|
||||||
|
<Avatar src={$profile.active.avatar} />
|
||||||
|
<span>{$profile.active.name}</span>
|
||||||
|
<span>{$profile.active.address}</span>
|
||||||
|
<Button icon={Collaborate} on:click={() => goto(ROUTES.IDENTITY)} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Input title="Name">
|
||||||
|
<InputString bind:value={$profile.active.name} placeholder="Enter identity name…" />
|
||||||
|
</Input>
|
||||||
|
|
||||||
|
<Input title="Profile picture">
|
||||||
|
<div class="profile">
|
||||||
|
{#if $profile.active.avatar !== undefined}
|
||||||
|
<img src={$profile.active.avatar} alt={file?.name} />
|
||||||
|
<InputFile bind:files label="Change" icon={Renew} variant="secondary" />
|
||||||
|
{:else}
|
||||||
|
<InputFile bind:files label="Add image..." icon={Image} variant="secondary" />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</Input>
|
||||||
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -65,7 +98,4 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.icon :global(svg) {
|
|
||||||
fill: grey;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user