Skip to content

Commit a41546f

Browse files
committed
chore: update
1 parent 6678a6e commit a41546f

File tree

12 files changed

+253
-50
lines changed

12 files changed

+253
-50
lines changed

_nuxtflare/server/utils/database.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { ofetch } from 'ofetch'
88
import Database from 'better-sqlite3'
99
import { join } from 'pathe'
1010

11-
// export * as tables from '~/server/database/schema'
11+
export * as tables from '~/server/database/schema'
1212

1313
let _db: DrizzleD1Database | BetterSQLite3Database | SqliteRemoteDatabase | null = null
1414
let _client: any = null
@@ -30,11 +30,13 @@ export const useDatabase = () => {
3030
method: 'POST',
3131
body: { sql, params, method }
3232
})
33-
console.log(method, rows)
3433
if (method === 'run') return rows
3534
return { rows }
36-
} catch (err) {
37-
console.error('Error from remote database', { sql, params, method }, err.data)
35+
} catch (err: any) {
36+
if (['begin', 'commit'].includes(sql)) {
37+
return { rows: [] }
38+
}
39+
console.error('Error from remote database:', err.data.message, '\n', { sql, params, method })
3840
return { rows: [] }
3941
}
4042
})

app.config.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,22 @@
11
export default defineAppConfig({
22
ui: {
3-
primary: 'lime',
4-
gray: 'neutral'
3+
primary: 'emerald',
4+
container: {
5+
constrained: 'max-w-2xl'
6+
},
7+
card: {
8+
header: {
9+
base: 'flex flex-wrap items-center justify-between'
10+
},
11+
body: {
12+
base: 'space-y-4'
13+
}
14+
},
15+
dropdown: {
16+
width: 'w-full',
17+
popper: {
18+
strategy: 'absolute'
19+
}
20+
}
521
}
622
})

app.vue

Lines changed: 60 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,70 @@
1-
<script setup lang="ts">
1+
<script setup>
2+
const { loggedIn } = useUserSession()
23
const colorMode = useColorMode()
34
4-
const color = computed(() => colorMode.value === 'dark' ? '#111827' : 'white')
5+
watch(loggedIn, () => {
6+
if (!loggedIn.value) {
7+
navigateTo('/')
8+
}
9+
})
10+
11+
function toggleColorMode() {
12+
colorMode.preference = colorMode.preference === 'dark' ? 'light' : 'dark'
13+
}
514
615
useHead({
7-
meta: [
8-
{ charset: 'utf-8' },
9-
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
10-
{ key: 'theme-color', name: 'theme-color', content: color }
11-
],
12-
link: [
13-
{ rel: 'icon', href: '/favicon.ico' }
14-
],
15-
htmlAttrs: {
16-
lang: 'en'
17-
}
16+
htmlAttrs: { lang: 'en' },
17+
link: [{ rel: 'icon', href: '/icon.png' }],
18+
})
19+
20+
useSeoMeta({
21+
viewport: 'width=device-width, initial-scale=1, maximum-scale=1',
22+
title: 'Nuxt Todos Edge',
23+
description:
24+
'A Nuxt demo hosted with Edge-side rendering, authentication and queyring a SQLite database',
25+
ogImage: '/social-image.png',
26+
twitterImage: '/social-image.png',
27+
twitterCard: 'summary_large_image',
1828
})
1929
</script>
2030

2131
<template>
22-
<div>
23-
<NuxtLoadingIndicator />
32+
<UContainer class="min-h-screen flex flex-col justify-center">
33+
<div class="mb-2 text-right">
34+
<UButton
35+
square
36+
variant="ghost"
37+
color="black"
38+
:icon="$colorMode.preference === 'dark' ? 'i-heroicons-moon' : 'i-heroicons-sun'"
39+
@click="toggleColorMode"
40+
/>
41+
</div>
42+
43+
<NuxtPage />
2444

25-
<NuxtLayout>
26-
<NuxtPage />
27-
</NuxtLayout>
45+
<footer class="text-center mt-2">
46+
<NuxtLink
47+
href="https://github.com/atinux/nuxt-todos-edge"
48+
target="_blank"
49+
class="text-sm text-gray-500 hover:text-gray-700"
50+
>
51+
GitHub
52+
</NuxtLink>
53+
·
54+
<NuxtLink
55+
href="https://twitter.com/Atinux"
56+
target="_blank"
57+
class="text-sm text-gray-500 hover:text-gray-700"
58+
>
59+
Twitter
60+
</NuxtLink>
61+
</footer>
62+
</UContainer>
63+
<UNotifications />
64+
</template>
2865

29-
<UNotifications />
30-
</div>
31-
</template>
66+
<style lang="postcss">
67+
body {
68+
@apply font-sans text-gray-950 bg-gray-50 dark:bg-gray-950 dark:text-gray-50;
69+
}
70+
</style>

nuxt.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ export default defineNuxtConfig({
22
devtools: { enabled: true },
33
// extends: '@nuxt/ui-pro',
44
extends: [
5-
'/Users/atinux/Projects/nuxt/ui-pro',
5+
// '/Users/atinux/Projects/nuxt/ui-pro',
66
'./_nuxtflare'
77
],
88
modules: [

pages/todos.vue

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<script setup>
2+
definePageMeta({
3+
middleware: 'auth'
4+
})
5+
const loading = ref(false)
6+
const newTodo = ref('')
7+
const newTodoInput = ref(null)
8+
9+
const toast = useToast()
10+
const { user, clear } = useUserSession()
11+
const { data: todos } = await useFetch('/api/todos')
12+
13+
async function addTodo () {
14+
if (!newTodo.value.trim()) { return }
15+
16+
loading.value = true
17+
18+
try {
19+
const todo = await $fetch('/api/todos', {
20+
method: 'POST',
21+
body: {
22+
title: newTodo.value,
23+
completed: 0
24+
}
25+
})
26+
todos.value.push(todo)
27+
toast.add({ title: `Todo "${todo.title}" created.` })
28+
newTodo.value = ''
29+
nextTick(() => {
30+
newTodoInput.value?.input?.focus()
31+
})
32+
} catch (err) {
33+
if (err.data?.data?.issues) {
34+
const title = err.data.data.issues.map(issue => issue.message).join('\n')
35+
toast.add({ title, color: 'red' })
36+
}
37+
}
38+
loading.value = false
39+
}
40+
41+
async function toggleTodo (todo) {
42+
todo.completed = Number(!todo.completed)
43+
await useFetch(`/api/todos/${todo.id}`, {
44+
method: 'PATCH',
45+
body: {
46+
completed: todo.completed
47+
}
48+
})
49+
}
50+
51+
async function deleteTodo (todo) {
52+
await useFetch(`/api/todos/${todo.id}`, { method: 'DELETE' })
53+
todos.value = todos.value.filter(t => t.id !== todo.id)
54+
toast.add({ title: `Todo "${todo.title}" deleted.` })
55+
}
56+
57+
const items = [[{
58+
label: 'Logout',
59+
icon: 'i-heroicons-arrow-left-on-rectangle',
60+
click: clear
61+
}]]
62+
</script>
63+
64+
<template>
65+
<UCard @submit.prevent="addTodo">
66+
<template #header>
67+
<h3 class="text-lg font-semibold leading-6">
68+
<NuxtLink to="/">
69+
Todo List
70+
</NuxtLink>
71+
</h3>
72+
73+
<UDropdown v-if="user" :items="items">
74+
<UButton color="white" trailing-icon="i-heroicons-chevron-down-20-solid">
75+
<UAvatar :src="`https://github.com/${user.login}.png`" :alt="user.login" size="3xs" />
76+
{{ user.login }}
77+
</UButton>
78+
</UDropdown>
79+
</template>
80+
81+
<div class="flex items-center gap-2">
82+
<UInput
83+
ref="newTodoInput"
84+
v-model="newTodo"
85+
name="todo"
86+
:disabled="loading"
87+
class="flex-1"
88+
placeholder="Make a Nuxt demo"
89+
autocomplete="off"
90+
autofocus
91+
:ui="{ wrapper: 'flex-1' }"
92+
/>
93+
94+
<UButton type="submit" icon="i-heroicons-plus-20-solid" :loading="loading" :disabled="newTodo.trim().length === 0" />
95+
</div>
96+
97+
<ul class="divide-y divide-gray-200 dark:divide-gray-800">
98+
<li
99+
v-for="todo of todos"
100+
:key="todo.id"
101+
class="flex items-center gap-4 py-2"
102+
>
103+
<span class="flex-1 font-medium" :class="[todo.completed ? 'line-through text-gray-500' : '']">{{ todo.title }}</span>
104+
105+
<UToggle :model-value="Boolean(todo.completed)" @update:model-value="toggleTodo(todo)" />
106+
107+
<UButton
108+
color="red"
109+
variant="soft"
110+
size="2xs"
111+
icon="i-heroicons-x-mark-20-solid"
112+
@click="deleteTodo(todo)"
113+
/>
114+
</li>
115+
</ul>
116+
</UCard>
117+
</template>

server/api/test.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ export default defineEventHandler(async (event) => {
66

77
const tables = await db.all(sql`
88
SELECT
9-
name
9+
name,
10+
type
1011
FROM
1112
sqlite_schema
1213
WHERE
@@ -19,18 +20,18 @@ export default defineEventHandler(async (event) => {
1920
id: integer('id').primaryKey(),
2021
text: text('text')
2122
})
22-
const inserted = await db.insert(todos).values({ text: 'hello' }).returning().get()
23-
const todo = await db.select().from(todos).where(eq(todos.id, inserted.id)).get()
24-
const updated = await db.update(todos).set({ text: 'Bonjour' }).where(eq(todos.id, inserted.id)).returning()
23+
// const inserted = await db.insert(todos).values({ text: 'hello' }).returning().get()
24+
// const todo = await db.select().from(todos).where(eq(todos.id, inserted.id)).get()
25+
// const updated = await db.update(todos).set({ text: 'Bonjour' }).where(eq(todos.id, inserted.id)).returning()
2526
const all = await db.select().from(todos).limit(3)
26-
const deleted = await db.delete(todos).where(eq(todos.id, all[0].id))
27+
// const deleted = await db.delete(todos).where(eq(todos.id, all[0].id))
2728

2829
return {
29-
tables,
30-
todo,
31-
inserted,
32-
updated,
33-
deleted,
30+
// tables,
31+
// todo,
32+
// inserted,
33+
// updated,
34+
// deleted,
3435
all
3536
}
3637
})
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CREATE TABLE `todos` (
2+
`id` integer PRIMARY KEY NOT NULL,
3+
`user_id` integer NOT NULL,
4+
`title` text NOT NULL,
5+
`completed` integer DEFAULT 0 NOT NULL,
6+
`created_at` integer NOT NULL
7+
);

server/database/migrations/0000_swift_stone_men.sql

Lines changed: 0 additions & 4 deletions
This file was deleted.

server/database/migrations/meta/0000_snapshot.json

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"version": "5",
33
"dialect": "sqlite",
4-
"id": "6d6fc5db-ed1d-4e06-bfbd-6b8a014b0b00",
4+
"id": "4f710177-2751-43af-9d16-88ac9acdbc35",
55
"prevId": "00000000-0000-0000-0000-000000000000",
66
"tables": {
77
"todos": {
@@ -14,12 +14,34 @@
1414
"notNull": true,
1515
"autoincrement": false
1616
},
17-
"text": {
18-
"name": "text",
17+
"user_id": {
18+
"name": "user_id",
19+
"type": "integer",
20+
"primaryKey": false,
21+
"notNull": true,
22+
"autoincrement": false
23+
},
24+
"title": {
25+
"name": "title",
1926
"type": "text",
2027
"primaryKey": false,
2128
"notNull": true,
2229
"autoincrement": false
30+
},
31+
"completed": {
32+
"name": "completed",
33+
"type": "integer",
34+
"primaryKey": false,
35+
"notNull": true,
36+
"autoincrement": false,
37+
"default": 0
38+
},
39+
"created_at": {
40+
"name": "created_at",
41+
"type": "integer",
42+
"primaryKey": false,
43+
"notNull": true,
44+
"autoincrement": false
2345
}
2446
},
2547
"indexes": {},

server/database/migrations/meta/_journal.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
{
66
"idx": 0,
77
"version": "5",
8-
"when": 1706118044364,
9-
"tag": "0000_swift_stone_men",
8+
"when": 1706120994243,
9+
"tag": "0000_good_jackpot",
1010
"breakpoints": true
1111
}
1212
]

0 commit comments

Comments
 (0)