Skip to content

Commit

Permalink
Merge pull request #2075 from undb-io/release/v1.0.0-94
Browse files Browse the repository at this point in the history
Release version v1.0.0-94
  • Loading branch information
nichenqin authored Sep 30, 2024
2 parents 2c732ad + bb29a80 commit 9b7a44a
Show file tree
Hide file tree
Showing 100 changed files with 807 additions and 1,833 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Changelog

## v1.0.0-94


### 🚀 Enhancements

- Login to create template ([ffe01de](https://github.com/undb-io/undb/commit/ffe01de))

### ❤️ Contributors

- Nichenqin ([@nichenqin](http://github.com/nichenqin))

## v1.0.0-93


Expand Down
17 changes: 16 additions & 1 deletion apps/backend/src/modules/template/template.module.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { singleton } from "@undb/di"
import { None } from "@undb/domain"
import { baseTemplateSchema, injectTemplateQueryRepository, type ITemplateQueryRepository } from "@undb/template"
import Elysia from "elysia"
import Elysia, { t } from "elysia"

@singleton()
export class TemplateModule {
Expand All @@ -21,5 +21,20 @@ export class TemplateModule {
templates,
}
})
.get(
"/api/templates/:templateId",
async ({ params: { templateId } }) => {
const template = (await this.templateRepo.findOneById(templateId)).expect("template not found")

return {
template,
}
},
{
params: t.Object({
templateId: t.String(),
}),
},
)
}
}
1 change: 1 addition & 0 deletions apps/backend/src/modules/web/web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ export class Web {
.get("/verify-email", () => index)
.get("/reset-password/*", () => index)
.get("/create-from-share/*", () => index)
.get("/templates/*", () => index)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<script lang="ts">
import * as Tabs from "$lib/components/ui/tabs"
import Login from "./login.svelte"
import Signup from "./signup.svelte"
export let registrationEnabled: boolean
export let redirect: string | null
export let onSuccess: () => void = () => {}
export let githubEnabled: boolean
export let googleEnabled: boolean
export let invitationId: string | null
export let email: string | null
</script>

<Tabs.Root value="login" class="w-full">
<Tabs.List class="w-full">
<Tabs.Trigger value="login" class="flex-1">Login</Tabs.Trigger>
<Tabs.Trigger value="signup" class="flex-1">Signup</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="login">
<Login {registrationEnabled} {redirect} {onSuccess} {githubEnabled} {googleEnabled} />
</Tabs.Content>
<Tabs.Content value="signup">
<Signup {redirect} {onSuccess} {githubEnabled} {googleEnabled} {invitationId} {email} />
</Tabs.Content>
</Tabs.Root>
176 changes: 176 additions & 0 deletions apps/frontend/src/lib/components/blocks/auth/login.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
<script lang="ts">
import { goto } from "$app/navigation"
import { Input } from "$lib/components/ui/input/index.js"
import { Label } from "$lib/components/ui/label/index.js"
import Github from "$lib/images/github.svg"
import Google from "$lib/images/Google.svg"
import { createMutation } from "@tanstack/svelte-query"
import { z } from "@undb/zod"
import { defaults, superForm } from "sveltekit-superforms"
import { zodClient } from "sveltekit-superforms/adapters"
import * as Form from "$lib/components/ui/form"
import { Button } from "$lib/components/ui/button"
import { Separator } from "$lib/components/ui/separator"
import PasswordInput from "$lib/components/ui/input/password-input.svelte"
import * as Alert from "$lib/components/ui/alert/index.js"
import autoAnimate from "@formkit/auto-animate"
import { LoaderCircleIcon } from "lucide-svelte"
import ResetPassword from "$lib/components/blocks/auth/reset-password.svelte"
import { page } from "$app/stores"
export let registrationEnabled: boolean
export let redirect: string | null
export let onSuccess: () => void = () => {}
export let githubEnabled: boolean
export let googleEnabled: boolean
const schema = z.object({
email: z.string().email(),
password: z.string(),
})
type LoginSchema = z.infer<typeof schema>
let loginError = false
const loginMutation = createMutation({
mutationFn: async (input: LoginSchema) => {
try {
const { ok } = await fetch("/api/login", { method: "POST", body: JSON.stringify(input) })
if (!ok) {
throw new Error("Failed to login")
}
return
} catch (error) {
loginError = true
}
},
onMutate(variables) {
loginError = false
},
async onSuccess(data, variables, context) {
onSuccess()
},
async onError(error, variables, context) {
loginError = true
},
})
const form = superForm(
defaults(
{
email: $page.url.searchParams.get("email") ?? "",
password: "",
},
zodClient(schema),
),
{
SPA: true,
dataType: "json",
validators: zodClient(schema),
resetForm: false,
invalidateAll: false,
async onUpdate(event) {
if (!event.form.valid) {
console.log(event.form.errors)
return
}
await $loginMutation.mutateAsync(event.form.data)
},
},
)
const { enhance, form: formData } = form
let resetPassword = false
</script>

{#if resetPassword}
<ResetPassword />
{:else}
<form method="POST" use:enhance>
<div class="grid gap-4">
<div class="grid gap-2">
<Form.Field {form} name="email">
<Form.Control let:attrs>
<Form.Label for="email">Email</Form.Label>
<Input
{...attrs}
id="email"
type="email"
placeholder="Enter your email to login"
bind:value={$formData.email}
/>
</Form.Control>
<Form.Description />
<Form.FieldErrors />
</Form.Field>
</div>
<div class="grid gap-2">
<Form.Field {form} name="password">
<Form.Control let:attrs>
<div class="flex justify-between">
<Label for="password">Password</Label>
<Button
tabindex={-1}
variant="link"
class="ml-auto h-auto p-0 text-sm"
on:click={() => {
resetPassword = true
}}>Forgot your password?</Button
>
</div>
<PasswordInput {...attrs} id="password" placeholder="*****" bind:value={$formData.password} />
</Form.Control>
<Form.Description />
<Form.FieldErrors />
</Form.Field>
</div>
<Form.Button type="submit" class="w-full" disabled={$loginMutation.isPending}>
{#if $loginMutation.isPending}
<LoaderCircleIcon class="mr-2 h-5 w-5 animate-spin" />
{/if}
Login
</Form.Button>
</div>
<div class="mt-4" use:autoAnimate>
{#if loginError}
<Alert.Root variant="destructive">
<Alert.Title>Error</Alert.Title>
<Alert.Description>Invalid email or password.</Alert.Description>
</Alert.Root>
{/if}
</div>
{#if registrationEnabled}
<div class="mt-4 text-center text-sm">
Don&apos;t have an account?
{#if redirect}
<a href="/signup?redirect={encodeURIComponent(redirect)}" class="underline"> Sign up </a>
{:else}
<a href="/signup" class="underline"> Sign up </a>
{/if}
</div>
{:else}
<p class="text-muted-foreground mt-4 text-center text-xs">
Registration is disabled. <br /> Contact your administrator to request access.
</p>
{/if}
{#if githubEnabled || googleEnabled}
<Separator class="my-6" />
<div class="space-y-2">
{#if githubEnabled}
<Button href="/login/github" variant="secondary" class="w-full">
<img class="mr-2 h-4 w-4" src={Github} alt="github" />
Login with Github
</Button>
{/if}
{#if googleEnabled}
<Button href="/login/google" variant="secondary" class="w-full">
<img class="mr-2 h-4 w-4" src={Google} alt="google" />
Login with Google
</Button>
{/if}
</div>
{/if}
</form>
{/if}
Loading

0 comments on commit 9b7a44a

Please sign in to comment.