mirror of
https://github.com/withastro/astro.git
synced 2024-12-30 22:03:56 -05:00
format
This commit is contained in:
parent
bbe2adf192
commit
6428abf706
16 changed files with 274 additions and 297 deletions
|
@ -10,6 +10,9 @@ benchmark/results/
|
|||
**/vendor
|
||||
**/.vercel
|
||||
|
||||
# Short-term need to format
|
||||
!packages/db/test/fixtures
|
||||
|
||||
# Directories
|
||||
.github
|
||||
.changeset
|
||||
|
|
|
@ -15,7 +15,13 @@ import type {
|
|||
import { SQLiteAsyncDialect } from 'drizzle-orm/sqlite-core';
|
||||
import { customAlphabet } from 'nanoid';
|
||||
import prompts from 'prompts';
|
||||
import { getCreateTableQuery, getModifiers, hasDefault, hasPrimaryKey, schemaTypeToSqlType } from '../internal.js';
|
||||
import {
|
||||
getCreateTableQuery,
|
||||
getModifiers,
|
||||
hasDefault,
|
||||
hasPrimaryKey,
|
||||
schemaTypeToSqlType,
|
||||
} from '../internal.js';
|
||||
|
||||
const sqlite = new SQLiteAsyncDialect();
|
||||
const genTempTableName = customAlphabet('abcdefghijklmnopqrstuvwxyz', 10);
|
||||
|
@ -157,15 +163,10 @@ export async function getCollectionChangeQueries({
|
|||
}
|
||||
}
|
||||
|
||||
const addedPrimaryKey = Object.entries(added).find(
|
||||
([, field]) => hasPrimaryKey(field)
|
||||
);
|
||||
const droppedPrimaryKey = Object.entries(dropped).find(
|
||||
([, field]) => hasPrimaryKey(field)
|
||||
);
|
||||
const addedPrimaryKey = Object.entries(added).find(([, field]) => hasPrimaryKey(field));
|
||||
const droppedPrimaryKey = Object.entries(dropped).find(([, field]) => hasPrimaryKey(field));
|
||||
const updatedPrimaryKey = Object.entries(updated).find(
|
||||
([, field]) =>
|
||||
(hasPrimaryKey(field.old) || hasPrimaryKey(field.new))
|
||||
([, field]) => hasPrimaryKey(field.old) || hasPrimaryKey(field.new)
|
||||
);
|
||||
const recreateTableQueries = getRecreateTableQueries({
|
||||
unescapedCollectionName: collectionName,
|
||||
|
@ -425,10 +426,7 @@ function canAlterTableDropColumn(field: DBField) {
|
|||
return true;
|
||||
}
|
||||
|
||||
type DataLossReason =
|
||||
| 'added-required'
|
||||
| 'added-unique'
|
||||
| 'updated-type';
|
||||
type DataLossReason = 'added-required' | 'added-unique' | 'updated-type';
|
||||
type DataLossResponse =
|
||||
| { dataLoss: false }
|
||||
| { dataLoss: true; fieldName: string; reason: DataLossReason };
|
||||
|
|
|
@ -44,7 +44,7 @@ export function integration(): AstroIntegration {
|
|||
dbPlugin = vitePluginDb({
|
||||
connectToStudio: true,
|
||||
collections,
|
||||
appToken
|
||||
appToken,
|
||||
});
|
||||
} else {
|
||||
const dbUrl = getLocalDbUrl(config.root);
|
||||
|
|
|
@ -5,7 +5,7 @@ import { DB_PATH } from './consts.js';
|
|||
|
||||
export function findLocalDatabase(localDbURL: string): string {
|
||||
let dbURL: URL | undefined = undefined;
|
||||
if(process.env.VERCEL) {
|
||||
if (process.env.VERCEL) {
|
||||
dbURL = new URL(DB_PATH, 'file://' + process.cwd() + '/vercel/path0/');
|
||||
} else {
|
||||
dbURL = new URL(localDbURL);
|
||||
|
|
|
@ -36,15 +36,15 @@ export function vitePluginDb(
|
|||
},
|
||||
async buildEnd() {
|
||||
// For local use, emit the database into the output
|
||||
if('dbUrl' in params) {
|
||||
if ('dbUrl' in params) {
|
||||
const data = await fs.promises.readFile(new URL(params.dbUrl));
|
||||
this.emitFile({
|
||||
fileName: 'content.db',
|
||||
source: data,
|
||||
type: 'asset'
|
||||
type: 'asset',
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -61,9 +61,9 @@ import { collectionToTable, createLocalDatabaseClient, findLocalDatabase } from
|
|||
export const dbUrl = findLocalDatabase(${JSON.stringify(dbUrl)});
|
||||
|
||||
const params = ${JSON.stringify({
|
||||
collections,
|
||||
seeding: false,
|
||||
})};
|
||||
collections,
|
||||
seeding: false,
|
||||
})};
|
||||
params.dbUrl = dbUrl;
|
||||
|
||||
export const db = await createLocalDatabaseClient(params);
|
||||
|
@ -84,7 +84,9 @@ export function getStudioVirtualModContents({
|
|||
return `
|
||||
import {collectionToTable, createRemoteDatabaseClient} from ${INTERNAL_MOD_IMPORT};
|
||||
|
||||
export const db = await createRemoteDatabaseClient(${JSON.stringify(appToken)}, import.meta.env.ASTRO_STUDIO_REMOTE_DB_URL);
|
||||
export const db = await createRemoteDatabaseClient(${JSON.stringify(
|
||||
appToken
|
||||
)}, import.meta.env.ASTRO_STUDIO_REMOTE_DB_URL);
|
||||
export * from ${DRIZZLE_MOD_IMPORT};
|
||||
|
||||
${getStringifiedCollectionExports(collections)}
|
||||
|
|
20
packages/db/test/fixtures/basics/astro.config.ts
vendored
20
packages/db/test/fixtures/basics/astro.config.ts
vendored
|
@ -20,21 +20,11 @@ export default defineConfig({
|
|||
collections: { Author, Themes },
|
||||
data({ seed }) {
|
||||
seed(Author, [
|
||||
{
|
||||
name: 'Ben',
|
||||
},
|
||||
{
|
||||
name: 'Nate',
|
||||
},
|
||||
{
|
||||
name: 'Erika',
|
||||
},
|
||||
{
|
||||
name: 'Bjorn',
|
||||
},
|
||||
{
|
||||
name: 'Sarah',
|
||||
},
|
||||
{ name: 'Ben' },
|
||||
{ name: 'Nate' },
|
||||
{ name: 'Erika' },
|
||||
{ name: 'Bjorn' },
|
||||
{ name: 'Sarah' },
|
||||
]);
|
||||
},
|
||||
},
|
||||
|
|
|
@ -5,8 +5,8 @@ const authors = await db.select().from(Author);
|
|||
|
||||
let error: any = {};
|
||||
try {
|
||||
db.insert(Author).values({ name: 'Person A' })
|
||||
} catch(err) {
|
||||
db.insert(Author).values({ name: 'Person A' });
|
||||
} catch (err) {
|
||||
error = err;
|
||||
}
|
||||
---
|
||||
|
|
|
@ -4,7 +4,7 @@ import { Themes, db } from 'astro:db';
|
|||
let error: any = {};
|
||||
try {
|
||||
db.insert(Themes).values({ name: 'Person A' });
|
||||
} catch(err) {
|
||||
} catch (err) {
|
||||
error = err;
|
||||
}
|
||||
---
|
||||
|
|
|
@ -1,43 +1,40 @@
|
|||
// Generated by simple:form
|
||||
|
||||
import { type ComponentProps, createContext } from "preact";
|
||||
import { useContext, useState } from "preact/hooks";
|
||||
import { navigate } from "astro:transitions/client";
|
||||
import { type ComponentProps, createContext } from 'preact';
|
||||
import { useContext, useState } from 'preact/hooks';
|
||||
import { navigate } from 'astro:transitions/client';
|
||||
import {
|
||||
type FieldErrors,
|
||||
type FormState,
|
||||
type FormValidator,
|
||||
formNameInputProps,
|
||||
getInitialFormState,
|
||||
toSetValidationErrors,
|
||||
toTrackAstroSubmitStatus,
|
||||
toValidateField,
|
||||
validateForm,
|
||||
} from "simple:form";
|
||||
type FieldErrors,
|
||||
type FormState,
|
||||
type FormValidator,
|
||||
formNameInputProps,
|
||||
getInitialFormState,
|
||||
toSetValidationErrors,
|
||||
toTrackAstroSubmitStatus,
|
||||
toValidateField,
|
||||
validateForm,
|
||||
} from 'simple:form';
|
||||
|
||||
export function useCreateFormContext(
|
||||
validator: FormValidator,
|
||||
fieldErrors?: FieldErrors
|
||||
) {
|
||||
const initial = getInitialFormState({ validator, fieldErrors });
|
||||
const [formState, setFormState] = useState<FormState>(initial);
|
||||
return {
|
||||
value: formState,
|
||||
set: setFormState,
|
||||
setValidationErrors: toSetValidationErrors(setFormState),
|
||||
validateField: toValidateField(setFormState),
|
||||
trackAstroSubmitStatus: toTrackAstroSubmitStatus(setFormState),
|
||||
};
|
||||
export function useCreateFormContext(validator: FormValidator, fieldErrors?: FieldErrors) {
|
||||
const initial = getInitialFormState({ validator, fieldErrors });
|
||||
const [formState, setFormState] = useState<FormState>(initial);
|
||||
return {
|
||||
value: formState,
|
||||
set: setFormState,
|
||||
setValidationErrors: toSetValidationErrors(setFormState),
|
||||
validateField: toValidateField(setFormState),
|
||||
trackAstroSubmitStatus: toTrackAstroSubmitStatus(setFormState),
|
||||
};
|
||||
}
|
||||
|
||||
export function useFormContext() {
|
||||
const formContext = useContext(FormContext);
|
||||
if (!formContext) {
|
||||
throw new Error(
|
||||
"Form context not found. `useFormContext()` should only be called from children of a <Form> component."
|
||||
);
|
||||
}
|
||||
return formContext;
|
||||
const formContext = useContext(FormContext);
|
||||
if (!formContext) {
|
||||
throw new Error(
|
||||
'Form context not found. `useFormContext()` should only be called from children of a <Form> component.'
|
||||
);
|
||||
}
|
||||
return formContext;
|
||||
}
|
||||
|
||||
type FormContextType = ReturnType<typeof useCreateFormContext>;
|
||||
|
@ -45,87 +42,82 @@ type FormContextType = ReturnType<typeof useCreateFormContext>;
|
|||
const FormContext = createContext<FormContextType | undefined>(undefined);
|
||||
|
||||
export function Form({
|
||||
children,
|
||||
validator,
|
||||
context,
|
||||
fieldErrors,
|
||||
name,
|
||||
...formProps
|
||||
children,
|
||||
validator,
|
||||
context,
|
||||
fieldErrors,
|
||||
name,
|
||||
...formProps
|
||||
}: {
|
||||
validator: FormValidator;
|
||||
context?: FormContextType;
|
||||
fieldErrors?: FieldErrors;
|
||||
} & Omit<ComponentProps<"form">, "method" | "onSubmit">) {
|
||||
const formContext = context ?? useCreateFormContext(validator, fieldErrors);
|
||||
validator: FormValidator;
|
||||
context?: FormContextType;
|
||||
fieldErrors?: FieldErrors;
|
||||
} & Omit<ComponentProps<'form'>, 'method' | 'onSubmit'>) {
|
||||
const formContext = context ?? useCreateFormContext(validator, fieldErrors);
|
||||
|
||||
return (
|
||||
<FormContext.Provider value={formContext}>
|
||||
<form
|
||||
{...formProps}
|
||||
method="POST"
|
||||
onSubmit={async (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const formData = new FormData(e.currentTarget);
|
||||
formContext.set((formState) => ({
|
||||
...formState,
|
||||
isSubmitPending: true,
|
||||
submitStatus: "validating",
|
||||
}));
|
||||
const parsed = await validateForm({ formData, validator });
|
||||
if (parsed.data) {
|
||||
const action =
|
||||
typeof formProps.action === "string"
|
||||
? formProps.action
|
||||
: // Check for Preact signals
|
||||
formProps.action?.value ?? "";
|
||||
navigate(action, { formData });
|
||||
return formContext.trackAstroSubmitStatus();
|
||||
}
|
||||
return (
|
||||
<FormContext.Provider value={formContext}>
|
||||
<form
|
||||
{...formProps}
|
||||
method="POST"
|
||||
onSubmit={async (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const formData = new FormData(e.currentTarget);
|
||||
formContext.set((formState) => ({
|
||||
...formState,
|
||||
isSubmitPending: true,
|
||||
submitStatus: 'validating',
|
||||
}));
|
||||
const parsed = await validateForm({ formData, validator });
|
||||
if (parsed.data) {
|
||||
const action =
|
||||
typeof formProps.action === 'string'
|
||||
? formProps.action
|
||||
: // Check for Preact signals
|
||||
formProps.action?.value ?? '';
|
||||
navigate(action, { formData });
|
||||
return formContext.trackAstroSubmitStatus();
|
||||
}
|
||||
|
||||
formContext.setValidationErrors(parsed.fieldErrors);
|
||||
}}
|
||||
>
|
||||
{name ? <input {...formNameInputProps} value={name} /> : null}
|
||||
{children}
|
||||
</form>
|
||||
</FormContext.Provider>
|
||||
);
|
||||
formContext.setValidationErrors(parsed.fieldErrors);
|
||||
}}
|
||||
>
|
||||
{name ? <input {...formNameInputProps} value={name} /> : null}
|
||||
{children}
|
||||
</form>
|
||||
</FormContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function Input({
|
||||
onInput,
|
||||
...inputProps
|
||||
}: ComponentProps<"input"> & { name: string }) {
|
||||
const formContext = useFormContext();
|
||||
const fieldState = formContext.value.fields[inputProps.name];
|
||||
if (!fieldState) {
|
||||
throw new Error(
|
||||
`Input "${inputProps.name}" not found in form. Did you use the <Form> component?`
|
||||
);
|
||||
}
|
||||
export function Input({ onInput, ...inputProps }: ComponentProps<'input'> & { name: string }) {
|
||||
const formContext = useFormContext();
|
||||
const fieldState = formContext.value.fields[inputProps.name];
|
||||
if (!fieldState) {
|
||||
throw new Error(
|
||||
`Input "${inputProps.name}" not found in form. Did you use the <Form> component?`
|
||||
);
|
||||
}
|
||||
|
||||
const { hasErroredOnce, validationErrors, validator } = fieldState;
|
||||
return (
|
||||
<>
|
||||
<input
|
||||
onBlur={async (e) => {
|
||||
const value = e.currentTarget.value;
|
||||
if (value === "") return;
|
||||
formContext.validateField(inputProps.name, value, validator);
|
||||
}}
|
||||
onInput={async (e) => {
|
||||
onInput?.(e);
|
||||
const { hasErroredOnce, validationErrors, validator } = fieldState;
|
||||
return (
|
||||
<>
|
||||
<input
|
||||
onBlur={async (e) => {
|
||||
const value = e.currentTarget.value;
|
||||
if (value === '') return;
|
||||
formContext.validateField(inputProps.name, value, validator);
|
||||
}}
|
||||
onInput={async (e) => {
|
||||
onInput?.(e);
|
||||
|
||||
if (!hasErroredOnce) return;
|
||||
const value = e.currentTarget.value;
|
||||
formContext.validateField(inputProps.name, value, validator);
|
||||
}}
|
||||
{...inputProps}
|
||||
/>
|
||||
{validationErrors?.map((e) => (
|
||||
<p key={e}>{e}</p>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
if (!hasErroredOnce) return;
|
||||
const value = e.currentTarget.value;
|
||||
formContext.validateField(inputProps.name, value, validator);
|
||||
}}
|
||||
{...inputProps}
|
||||
/>
|
||||
{validationErrors?.map((e) => <p key={e}>{e}</p>)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
---
|
||||
import { ViewTransitions } from "astro:transitions";
|
||||
import "open-props/normalize";
|
||||
import "open-props/style";
|
||||
import { ViewTransitions } from 'astro:transitions';
|
||||
import 'open-props/normalize';
|
||||
import 'open-props/style';
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
const { title } = Astro.props;
|
||||
|
@ -12,69 +12,69 @@ const { title } = Astro.props;
|
|||
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="description" content="Astro description" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<title>{title}</title>
|
||||
<ViewTransitions handleForms />
|
||||
</head>
|
||||
<body>
|
||||
<slot />
|
||||
<style is:global>
|
||||
main {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
padding: var(--size-4);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--size-4);
|
||||
}
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="description" content="Astro description" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<title>{title}</title>
|
||||
<ViewTransitions handleForms />
|
||||
</head>
|
||||
<body>
|
||||
<slot />
|
||||
<style is:global>
|
||||
main {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
padding: var(--size-4);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--size-4);
|
||||
}
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--size-2);
|
||||
margin-bottom: var(--size-4);
|
||||
background: var(--surface-2);
|
||||
padding-inline: var(--size-4);
|
||||
padding-block: var(--size-6);
|
||||
border-radius: var(--radius-2);
|
||||
}
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--size-2);
|
||||
margin-bottom: var(--size-4);
|
||||
background: var(--surface-2);
|
||||
padding-inline: var(--size-4);
|
||||
padding-block: var(--size-6);
|
||||
border-radius: var(--radius-2);
|
||||
}
|
||||
|
||||
.error {
|
||||
color: var(--red-6);
|
||||
margin-bottom: var(--size-2);
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
.error {
|
||||
color: var(--red-6);
|
||||
margin-bottom: var(--size-2);
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
form button {
|
||||
grid-column: 1 / -1;
|
||||
background: var(--orange-8);
|
||||
border-radius: var(--radius-2);
|
||||
padding-block: var(--size-2);
|
||||
}
|
||||
form button {
|
||||
grid-column: 1 / -1;
|
||||
background: var(--orange-8);
|
||||
border-radius: var(--radius-2);
|
||||
padding-block: var(--size-2);
|
||||
}
|
||||
|
||||
.youre-going {
|
||||
background: var(--surface-2);
|
||||
padding: var(--size-2);
|
||||
border-radius: var(--radius-2);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.youre-going {
|
||||
background: var(--surface-2);
|
||||
padding: var(--size-2);
|
||||
border-radius: var(--radius-2);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: var(--font-size-4);
|
||||
margin-bottom: var(--size-2);
|
||||
}
|
||||
h2 {
|
||||
font-size: var(--font-size-4);
|
||||
margin-bottom: var(--size-2);
|
||||
}
|
||||
|
||||
.newsletter {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--size-2);
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
.newsletter {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--size-2);
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,40 +1,40 @@
|
|||
import { createForm } from "simple:form";
|
||||
import { Form, Input } from "../../components/Form";
|
||||
import { z } from "zod";
|
||||
import { useState } from "preact/hooks";
|
||||
import { createForm } from 'simple:form';
|
||||
import { Form, Input } from '../../components/Form';
|
||||
import { z } from 'zod';
|
||||
import { useState } from 'preact/hooks';
|
||||
|
||||
export const ticketForm = createForm({
|
||||
email: z.string().email(),
|
||||
quantity: z.number().max(10),
|
||||
newsletter: z.boolean(),
|
||||
email: z.string().email(),
|
||||
quantity: z.number().max(10),
|
||||
newsletter: z.boolean(),
|
||||
});
|
||||
|
||||
export function TicketForm({ price }: { price: number }) {
|
||||
const [quantity, setQuantity] = useState(1);
|
||||
return (
|
||||
<>
|
||||
<Form validator={ticketForm.validator}>
|
||||
<h3>${(quantity * price) / 100}</h3>
|
||||
const [quantity, setQuantity] = useState(1);
|
||||
return (
|
||||
<>
|
||||
<Form validator={ticketForm.validator}>
|
||||
<h3>${(quantity * price) / 100}</h3>
|
||||
|
||||
<label for="quantity">Quantity</label>
|
||||
<Input
|
||||
id="quantity"
|
||||
{...ticketForm.inputProps.quantity}
|
||||
onInput={(e) => {
|
||||
const value = Number(e.currentTarget.value);
|
||||
setQuantity(value);
|
||||
}}
|
||||
/>
|
||||
<label for="quantity">Quantity</label>
|
||||
<Input
|
||||
id="quantity"
|
||||
{...ticketForm.inputProps.quantity}
|
||||
onInput={(e) => {
|
||||
const value = Number(e.currentTarget.value);
|
||||
setQuantity(value);
|
||||
}}
|
||||
/>
|
||||
|
||||
<label for="email">Email</label>
|
||||
<Input id="email" {...ticketForm.inputProps.email} />
|
||||
<label for="email">Email</label>
|
||||
<Input id="email" {...ticketForm.inputProps.email} />
|
||||
|
||||
<div class="newsletter">
|
||||
<Input id="newsletter" {...ticketForm.inputProps.newsletter} />
|
||||
<label for="newsletter">Hear about the next event in your area</label>
|
||||
</div>
|
||||
<button>Buy tickets</button>
|
||||
</Form>
|
||||
</>
|
||||
);
|
||||
<div class="newsletter">
|
||||
<Input id="newsletter" {...ticketForm.inputProps.newsletter} />
|
||||
<label for="newsletter">Hear about the next event in your area</label>
|
||||
</div>
|
||||
<button>Buy tickets</button>
|
||||
</Form>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,56 +1,48 @@
|
|||
---
|
||||
import { Event, Ticket, db, eq } from "astro:db";
|
||||
import Layout from "../../layouts/Layout.astro";
|
||||
import { TicketForm, ticketForm } from "./_Ticket";
|
||||
import { Event, Ticket, db, eq } from 'astro:db';
|
||||
import Layout from '../../layouts/Layout.astro';
|
||||
import { TicketForm, ticketForm } from './_Ticket';
|
||||
|
||||
if (!Astro.params.event) return Astro.redirect("/404");
|
||||
if (!Astro.params.event) return Astro.redirect('/404');
|
||||
|
||||
const event = await db
|
||||
.select()
|
||||
.from(Event)
|
||||
.where(eq(Event.id, Astro.params.event))
|
||||
.get();
|
||||
const event = await db.select().from(Event).where(eq(Event.id, Astro.params.event)).get();
|
||||
|
||||
if (!event) return Astro.redirect("/404");
|
||||
if (!event) return Astro.redirect('/404');
|
||||
|
||||
const res = await Astro.locals.form.getData(ticketForm);
|
||||
|
||||
if (res?.data) {
|
||||
await db.insert(Ticket).values({
|
||||
eventId: Astro.params.event,
|
||||
email: res.data.email,
|
||||
quantity: res.data.quantity,
|
||||
newsletter: res.data.newsletter,
|
||||
});
|
||||
await db.insert(Ticket).values({
|
||||
eventId: Astro.params.event,
|
||||
email: res.data.email,
|
||||
quantity: res.data.quantity,
|
||||
newsletter: res.data.newsletter,
|
||||
});
|
||||
}
|
||||
|
||||
const ticket = await db
|
||||
.select()
|
||||
.from(Ticket)
|
||||
.where(eq(Ticket.eventId, Astro.params.event))
|
||||
.get();
|
||||
const ticket = await db.select().from(Ticket).where(eq(Ticket.eventId, Astro.params.event)).get();
|
||||
---
|
||||
|
||||
<Layout title="Welcome to Astro.">
|
||||
<main>
|
||||
<h1>{event.name}</h1>
|
||||
<p>
|
||||
{event.description}
|
||||
</p>
|
||||
<main>
|
||||
<h1>{event.name}</h1>
|
||||
<p>
|
||||
{event.description}
|
||||
</p>
|
||||
|
||||
<TicketForm price={event.ticketPrice} client:load />
|
||||
{
|
||||
ticket && (
|
||||
<section class="youre-going">
|
||||
<h2>You're going 🙌</h2>
|
||||
<p>
|
||||
You have purchased {ticket.quantity} tickets for {event.name}!
|
||||
</p>
|
||||
<p>
|
||||
Check <strong>{ticket.email}</strong> for your tickets.
|
||||
</p>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
</main>
|
||||
<TicketForm price={event.ticketPrice} client:load />
|
||||
{
|
||||
ticket && (
|
||||
<section class="youre-going">
|
||||
<h2>You're going 🙌</h2>
|
||||
<p>
|
||||
You have purchased {ticket.quantity} tickets for {event.name}!
|
||||
</p>
|
||||
<p>
|
||||
Check <strong>{ticket.email}</strong> for your tickets.
|
||||
</p>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
</main>
|
||||
</Layout>
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
---
|
||||
import { Event, db } from "astro:db";
|
||||
import { Event, db } from 'astro:db';
|
||||
|
||||
const firstEvent = await db.select().from(Event).get();
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Eventbrite</title>
|
||||
</head>
|
||||
<body>
|
||||
<meta http-equiv="refresh" content={`0; url=${firstEvent!.id}`} />
|
||||
</body>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Eventbrite</title>
|
||||
</head>
|
||||
<body>
|
||||
<meta http-equiv="refresh" content={`0; url=${firstEvent!.id}`} />
|
||||
</body>
|
||||
</html>
|
||||
|
|
Loading…
Reference in a new issue