finish manage-credentials page and rework home screen

This commit is contained in:
Joseph Montanaro 2024-06-28 06:25:55 -04:00
parent bb980c5eef
commit bf0a2ca72d
10 changed files with 118 additions and 50 deletions

View File

@ -4,6 +4,8 @@
export let value = ''; export let value = '';
export let placeholder = ''; export let placeholder = '';
export let autofocus = false; export let autofocus = false;
let classes = '';
export {classes as class};
let show = false; let show = false;
</script> </script>
@ -22,7 +24,7 @@
type={show ? 'text' : 'password'} type={show ? 'text' : 'password'}
{value} {placeholder} {autofocus} {value} {placeholder} {autofocus}
on:input on:change on:focus on:blur on:input on:change on:focus on:blur
class="input input-bordered flex-grow join-item placeholder:text-gray-500" class="input input-bordered flex-grow join-item placeholder:text-gray-500 {classes}"
on:input={e => value = e.target.value} on:input={e => value = e.target.value}
/> />

View File

@ -0,0 +1,8 @@
<script>
let classes = '';
export {classes as class}
</script>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class={classes}>
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 9V5.25A2.25 2.25 0 0 0 13.5 3h-6a2.25 2.25 0 0 0-2.25 2.25v13.5A2.25 2.25 0 0 0 7.5 21h6a2.25 2.25 0 0 0 2.25-2.25V15m3 0 3-3m0 0-3-3m3 3H9" />
</svg>

View File

@ -0,0 +1,8 @@
<script>
let classes = '';
export {classes as class}
</script>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class={classes}>
<path stroke-linecap="round" stroke-linejoin="round" d="m6.75 7.5 3 2.25-3 2.25m4.5 0h3m-9 8.25h13.5A2.25 2.25 0 0 0 21 18V6a2.25 2.25 0 0 0-2.25-2.25H5.25A2.25 2.25 0 0 0 3 6v12a2.25 2.25 0 0 0 2.25 2.25Z" />
</svg>

8
src/ui/icons/key.svelte Normal file
View File

@ -0,0 +1,8 @@
<script>
let classes = '';
export {classes as class}
</script>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class={classes}>
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 5.25a3 3 0 0 1 3 3m3 0a6 6 0 0 1-7.029 5.912c-.563-.097-1.159.026-1.563.43L10.5 17.25H8.25v2.25H6v2.25H2.25v-2.818c0-.597.237-1.17.659-1.591l6.499-6.499c.404-.404.527-1 .43-1.563A6 6 0 1 1 21.75 8.25Z" />
</svg>

View File

@ -0,0 +1,8 @@
<script>
let classes = '';
export {classes as class}
</script>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class={classes}>
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75m-3-7.036A11.959 11.959 0 0 1 3.598 6 11.99 11.99 0 0 0 3 9.749c0 5.592 3.824 10.29 9 11.623 5.176-1.332 9-6.03 9-11.622 0-1.31-.21-2.571-.598-3.751h-.152c-3.196 0-6.1-1.248-8.25-3.285Z" />
</svg>

View File

@ -31,23 +31,37 @@
</Nav> </Nav>
<div class="flex flex-col h-screen items-center justify-center p-4 space-y-4"> <div class="flex flex-col h-screen items-center justify-center p-4 space-y-4">
<div class="flex flex-col items-center space-y-4"> <div class="grid grid-cols-2 gap-6">
<h2 class="text-2xl font-bold">Waiting for requests</h2> <Link target="ManageCredentials">
<button class="btn btn-primary w-full" on:click={launchTerminal}> <div class="flex flex-col items-center gap-4 h-full max-w-56 rounded-box p-4 border border-primary hover:bg-base-200 transition-colors">
Launch Terminal <Icon name="key" class="size-12 stroke-1 stroke-primary" />
</button> <h3 class="text-lg font-bold">Credentials</h3>
<label class="label cursor-pointer flex items-center space-x-2"> <p class="text-sm">Add, remove, and change defaults credentials.</p>
<span class="label-text">Launch with long-lived credentials</span> </div>
<input type="checkbox" class="checkbox checkbox-sm" bind:checked={launchBase}>
</label>
<button class="btn btn-primary w-full" on:click={lock}>
Lock Creddy
</button>
<Link target="ChangePassphrase" class="w-full">
<button class="btn btn-primary w-full">Change passphrase</button>
</Link> </Link>
<Link target="ManageCredentials" class="w-full">
<button class="btn btn-primary w-full">Manage credentials</button> <Link target={launchTerminal}>
<div class="flex flex-col items-center gap-4 h-full max-w-56 rounded-box p-4 border border-secondary hover:bg-base-200 transition-colors">
<Icon name="command-line" class="size-12 stroke-1 stroke-secondary" />
<h3 class="text-lg font-bold">Terminal</h3>
<p class="text-sm">Launch a terminal pre-configured with AWS credentials.</p>
</div>
</Link>
<Link target={lock}>
<div class="flex flex-col items-center gap-4 h-full max-w-56 rounded-box p-4 border border-accent hover:bg-base-200 transition-colors">
<Icon name="shield-check" class="size-12 stroke-1 stroke-accent" />
<h3 class="text-lg font-bold">Lock</h3>
<p class="text-sm">Lock Creddy.</p>
</div>
</Link>
<Link target="">
<div class="flex flex-col items-center gap-4 h-full max-w-56 rounded-box p-4 border border-warning hover:bg-base-200 transition-colors">
<Icon name="arrow-right-start-on-rectangle" class="size-12 stroke-1 stroke-warning" />
<h3 class="text-lg font-bold">Exit</h3>
<p class="text-sm">Close Creddy.</p>
</div>
</Link> </Link>
</div> </div>
</div> </div>

View File

@ -19,12 +19,12 @@
} }
onMount(loadCreds); onMount(loadCreds);
function newCred() { function newAws() {
records.push({ records.push({
id: crypto.randomUUID(), id: crypto.randomUUID(),
name: '', name: null,
is_default: false, is_default: false,
credential: {type: 'AwsBase', AccessKeyId: '', SecretAccessKey: ''}, credential: {type: 'AwsBase', AccessKeyId: null, SecretAccessKey: null},
isNew: true, isNew: true,
}); });
records = records; records = records;
@ -42,20 +42,18 @@
</div> </div>
{#if records.length > 0} {#if records.length > 0}
<div class="rounded-box border-2 border-neutral-content/30 divide-y-2 divide-neutral-content/30"> {#each records as record (record.id)}
{#each records as record (record.id)} <AwsCredential {record} {defaults} on:update={loadCreds} />
<AwsCredential {record} {defaults} on:update={loadCreds} /> {/each}
{/each} <button class="btn btn-primary btn-wide mx-auto" on:click={newAws}>
</div>
<button class="btn btn-primary btn-wide mx-auto" on:click={newCred}>
<Icon name="plus-circle-mini" class="size-5" /> <Icon name="plus-circle-mini" class="size-5" />
Add Add
</button> </button>
{:else} {:else}
<div class="flex flex-col gap-6 items-center rounded-box border-2 border-dashed border-neutral-content/30 p-6"> <div class="flex flex-col gap-6 items-center rounded-box border-2 border-dashed border-neutral-content/30 p-6">
<div>You have no saved AWS credentials.</div> <div>You have no saved AWS credentials.</div>
<button class="btn btn-primary btn-wide mx-auto" on:click={newCred}> <button class="btn btn-primary btn-wide mx-auto" on:click={newAws}>
<Icon name="plus-circle-mini" /> <Icon name="plus-circle-mini" class="size-5" />
Add Add
</button> </button>
</div> </div>

View File

@ -75,12 +75,12 @@
</TimeSetting> </TimeSetting>
{/if} {/if}
<Setting title="Update credentials"> <Setting title="Update passphrase">
<Link slot="input" target="EnterAwsCredential"> <Link slot="input" target="ChangePassphrase">
<button type="button" class="btn btn-sm btn-primary">Update</button> <button type="button" class="btn btn-sm btn-primary">Update</button>
</Link> </Link>
<svelte:fragment slot="description"> <svelte:fragment slot="description">
Update or re-enter your encrypted credentials. Change your master passphrase.
</svelte:fragment> </svelte:fragment>
</Setting> </Setting>

View File

@ -64,28 +64,31 @@
</script> </script>
<div transition:slide|local={{duration: record.isNew ? 300 : 0}} class="px-6 py-4 space-y-4"> <div
<div class="flex items-center gap-x-4"> transition:slide|local={{duration: record.isNew ? 300 : 0}}
<h3 class="text-lg font-bold">{record.name}</h3> class="rounded-box space-y-4 bg-base-200 {record.is_default ? 'border border-accent' : ''}"
>
<div class="flex items-center px-6 py-4 gap-x-4">
<h3 class="text-lg font-bold">{record.name || ''}</h3>
{#if record.is_default} {#if record.is_default}
<span class="badge badge-secondary">Default</span> <span class="badge badge-accent">Default</span>
{/if} {/if}
<div class="join ml-auto"> <div class="join ml-auto">
<button <button
type="button" type="button"
class="btn btn-sm btn-primary join-item" class="btn btn-outline join-item"
on:click={() => showDetails = !showDetails} on:click={() => showDetails = !showDetails}
> >
<Icon name="pencil" class="w-5 h-5" /> <Icon name="pencil" class="size-6" />
</button> </button>
<button <button
type="button" type="button"
class="btn btn-sm btn-error join-item" class="btn btn-outline btn-error join-item"
on:click={conditionalDelete} on:click={conditionalDelete}
> >
<Icon name="trash" class="w-5 h-5" /> <Icon name="trash" class="size-6" />
</button> </button>
</div> </div>
</div> </div>
@ -93,12 +96,14 @@
{#if showDetails} {#if showDetails}
{#if error} {#if error}
<ErrorAlert bind:this={alert}>{error}</ErrorAlert> <div class="px-6">
<ErrorAlert bind:this={alert}>{error}</ErrorAlert>
</div>
{/if} {/if}
<form <form
transition:slide|local={{duration: 200}} transition:slide|local={{duration: 200}}
class="space-y-4" class=" px-6 pb-4 space-y-4"
on:submit|preventDefault={saveCredential} on:submit|preventDefault={saveCredential}
> >
<div class="grid grid-cols-[auto_1fr] items-center gap-4"> <div class="grid grid-cols-[auto_1fr] items-center gap-4">
@ -106,7 +111,7 @@
<span class="justify-self-end">Name</span> <span class="justify-self-end">Name</span>
<input <input
type="text" type="text"
class="input input-bordered" class="input input-bordered bg-transparent"
bind:value={local.name} bind:value={local.name}
> >
{/if} {/if}
@ -114,20 +119,20 @@
<span class="justify-self-end">Key ID</span> <span class="justify-self-end">Key ID</span>
<input <input
type="text" type="text"
class="input input-bordered font-mono" class="input input-bordered font-mono bg-transparent"
bind:value={local.credential.AccessKeyId} bind:value={local.credential.AccessKeyId}
> >
<span>Secret key</span> <span>Secret key</span>
<div class="font-mono"> <div class="font-mono">
<PassphraseInput bind:value={local.credential.SecretAccessKey} /> <PassphraseInput class="bg-transparent" bind:value={local.credential.SecretAccessKey} />
</div> </div>
</div> </div>
<div class="flex justify-between"> <div class="flex justify-between">
<label class="label cursor-pointer justify-self-start space-x-4"> <label class="label cursor-pointer justify-self-start space-x-4">
<span class="label-text">Default for type</span> <span class="label-text">Default for type</span>
<input type="checkbox" class="toggle toggle-secondary" bind:checked={local.is_default}> <input type="checkbox" class="toggle toggle-accent" bind:checked={local.is_default}>
</label> </label>
{#if isModified} {#if isModified}
<button <button

View File

@ -14,18 +14,35 @@ module.exports = {
themes: [ themes: [
{ {
creddy: { creddy: {
"primary": "#115e59", "primary": "#0ea5e9",
"secondary": "#8b5cf6", "secondary": "#fb923c",
"accent": "#0ea5e9", "accent": "#8b5cf6",
"neutral": "#2f292c", "neutral": "#2f292c",
"base-100": "#252e3a", "base-100": "#252e3a",
"info": "#3aa8ff", "info": "#66cccc",
"success": "#52bf73", "success": "#52bf73",
"warning": "#d97706", "warning": "#d1a900",
"error": "#f87171", "error": "#f87171",
}, },
}, },
{
"summer-night": {
"primary": "#0ea5e9",
"secondary": "#0ea5e9",
"accent": "#fb923c",
"neutral": "#393939",
"base-100": "#2d2d2d",
"info": "#66cccc",
"success": "#22c55e",
"warning": "#d1a900",
"error": "#f2777a"
},
},
"dark", "dark",
"night",
"dracula",
"sunset",
"dim",
"light" "light"
] ]
}, },