Compare commits
2 Commits
e3bfbec53d
...
43a5704043
| Author | SHA1 | Date |
|---|---|---|
|
|
43a5704043 | 2 years ago |
|
|
d558cb7e99 | 2 years ago |
@ -1,78 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div
|
|
||||||
class="bg-secondary mx-auto mt-12 flex h-96 w-96 flex-col items-center justify-center gap-8 rounded-xl p-8">
|
|
||||||
<div class="flex w-full flex-col gap-2">
|
|
||||||
<label> Email </label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
v-model="credential.email"
|
|
||||||
placeholder="username" />
|
|
||||||
</div>
|
|
||||||
<div class="flex w-full flex-col gap-2">
|
|
||||||
<label> Password </label>
|
|
||||||
<input
|
|
||||||
type="password"
|
|
||||||
v-model="credential.password"
|
|
||||||
placeholder="password" />
|
|
||||||
</div>
|
|
||||||
<p
|
|
||||||
v-if="mode === 'login'"
|
|
||||||
class="cursor-pointer text-blue-500 underline">
|
|
||||||
Don't have an account? Sign up
|
|
||||||
</p>
|
|
||||||
<p
|
|
||||||
v-if="mode === 'signup'"
|
|
||||||
class="cursor-pointer text-blue-500 underline">
|
|
||||||
Already have an account? Login
|
|
||||||
</p>
|
|
||||||
<button
|
|
||||||
v-on="
|
|
||||||
mode === 'login'
|
|
||||||
? { click: () => signIn($event) }
|
|
||||||
: { click: () => signUp($event) }
|
|
||||||
">
|
|
||||||
{{ mode === 'login' ? 'Login' : 'Sign Up' }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
interface Props {
|
|
||||||
mode: 'login' | 'signup'
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Credential {
|
|
||||||
email: string
|
|
||||||
password: string
|
|
||||||
name?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const credential: Credential = reactive({
|
|
||||||
email: '',
|
|
||||||
password: '',
|
|
||||||
})
|
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
|
||||||
mode: 'login',
|
|
||||||
})
|
|
||||||
|
|
||||||
const supabase = useSupabaseAuthClient()
|
|
||||||
|
|
||||||
const signUp = async (event: Event) => {
|
|
||||||
const { data: user, error } = await supabase.auth.signUp({
|
|
||||||
email: credential.email,
|
|
||||||
password: credential.password,
|
|
||||||
})
|
|
||||||
console.log('user', user)
|
|
||||||
console.log('error', error)
|
|
||||||
}
|
|
||||||
|
|
||||||
const signIn = async (event: Event) => {
|
|
||||||
const { data: user, error } = await supabase.auth.signInWithPassword({
|
|
||||||
email: credential.email,
|
|
||||||
password: credential.password,
|
|
||||||
})
|
|
||||||
console.log('user', user)
|
|
||||||
console.log('error', error)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
<template>
|
|
||||||
<textarea
|
|
||||||
class="bg-secondary w-full max-w-2xl resize-none border-none outline-none placeholder:text-zinc-700 focus:outline-none"
|
|
||||||
v-model="data"
|
|
||||||
:rows="props.row"
|
|
||||||
:placeholder="props.placeholder"
|
|
||||||
@input="updateData()">
|
|
||||||
</textarea>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
interface Props {
|
|
||||||
modelValue: string
|
|
||||||
placeholder?: string
|
|
||||||
row?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
const props = defineProps<Props>()
|
|
||||||
const emit = defineEmits(['update:modelValue'])
|
|
||||||
|
|
||||||
const data = ref<string>(props.modelValue)
|
|
||||||
|
|
||||||
const updateData = () => {
|
|
||||||
emit('update:modelValue', data.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.modelValue,
|
|
||||||
() => (data.value = props.modelValue)
|
|
||||||
)
|
|
||||||
</script>
|
|
||||||
@ -1,110 +1,103 @@
|
|||||||
<template>
|
<template>
|
||||||
<NuxtLayout
|
<NuxtLayout name="edit">
|
||||||
name="edit"
|
<template #content>
|
||||||
@keydown.ctrl.s.prevent="submit(note)">
|
<div class="sticky top-0 flex w-full justify-between">
|
||||||
<template #content>
|
<div @click="toggleComp('text')" class="bg-lightgray w-1/2 p-2 text-center text-xl"
|
||||||
<div class="sticky top-0 flex w-full justify-between">
|
:class="{ 'bg-secondary': comp === 'text' }">
|
||||||
<div
|
Text
|
||||||
@click="toggleComp('text')"
|
</div>
|
||||||
class="bg-lightgray w-1/2 p-2 text-center text-xl"
|
<div @click="toggleComp('md')" class="bg-lightgray w-1/2 p-2 text-center text-xl"
|
||||||
:class="{ 'bg-secondary': comp === 'text' }">
|
:class="{ 'bg-secondary': comp === 'md' }">
|
||||||
Text
|
Markdown
|
||||||
</div>
|
</div>
|
||||||
<div
|
</div>
|
||||||
@click="toggleComp('md')"
|
<div class="flex h-full w-full flex-col">
|
||||||
class="bg-lightgray w-1/2 p-2 text-center text-xl"
|
<textarea ref="noteTextArea" v-show="comp === 'text'"
|
||||||
:class="{ 'bg-secondary': comp === 'md' }">
|
class="bg-secondary min-h-screen w-full flex-grow resize-none border-none p-4 outline-none placeholder:text-zinc-700 focus:outline-none"
|
||||||
Markdown
|
v-model="input" @change="submit()">
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex h-full w-full flex-col">
|
|
||||||
<textarea
|
|
||||||
ref="noteTextArea"
|
|
||||||
v-show="comp === 'text'"
|
|
||||||
class="bg-secondary min-h-screen w-full flex-grow resize-none border-none p-4 outline-none placeholder:text-zinc-700 focus:outline-none"
|
|
||||||
v-model="input">
|
|
||||||
</textarea>
|
</textarea>
|
||||||
<CardMarkdownRenderer
|
<CardMarkdownRenderer v-show="comp === 'md'" :content="note.description" :state="'description'" />
|
||||||
v-show="comp === 'md'"
|
</div>
|
||||||
:content="note.description"
|
</template>
|
||||||
:state="'description'" />
|
</NuxtLayout>
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</NuxtLayout>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
middleware: ['auth'],
|
middleware: ['auth'],
|
||||||
})
|
})
|
||||||
|
|
||||||
type Comp = 'text' | 'md'
|
type Mode = 'text' | 'md'
|
||||||
|
|
||||||
const note = useNote()
|
const note = useNote()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const isLoading = ref<Boolean>(false)
|
const isLoading = ref<Boolean>(false)
|
||||||
const isSubmitting = ref<Boolean>(false)
|
const isSubmitting = ref<Boolean>(false)
|
||||||
const isDeleting = ref<Boolean>(false)
|
const isDeleting = ref<Boolean>(false)
|
||||||
const comp = ref<Comp>('text')
|
const comp = ref<Mode>('text')
|
||||||
const description = useDescription()
|
const { textarea: noteTextArea, input } = useTextareaAutosize()
|
||||||
const { textarea: noteTextArea, input } = useTextareaAutosize()
|
|
||||||
|
|
||||||
const toggleComp = (name: Comp) => {
|
const toggleComp = (name: Mode) => {
|
||||||
comp.value = name
|
comp.value = name
|
||||||
}
|
}
|
||||||
|
|
||||||
const { refresh } = await useFetch('/api/note', {
|
const { refresh } = await useFetch('/api/note', {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
query: {
|
query: {
|
||||||
id: route.params.id,
|
id: route.params.id,
|
||||||
},
|
},
|
||||||
onResponse({ response }) {
|
onResponse({ response }) {
|
||||||
console.log('Response: ', response)
|
console.log('Response: ', response)
|
||||||
if (response.status === 500) {
|
if (response.status === 500) {
|
||||||
console.log(`Error: ${response._data.message}`)
|
console.log(`Error: ${response._data.message}`)
|
||||||
router.push('/notes')
|
router.push('/notes')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
note.value.title = response._data.note.title
|
note.value.title = response._data.note.title
|
||||||
note.value.description = response._data.note.description
|
note.value.description = response._data.note.description
|
||||||
description.value = note.value.description
|
input.value = note.value.description
|
||||||
input.value = note.value.description
|
},
|
||||||
},
|
})
|
||||||
})
|
|
||||||
|
|
||||||
const submit = async (note: Note) => {
|
const submitTimeout = ref()
|
||||||
isSubmitting.value = true
|
|
||||||
await submitNote(note, { id: route.params.id })
|
|
||||||
isSubmitting.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
const deleteNote = async () => {
|
const submit = async () => {
|
||||||
isDeleting.value = true
|
isSubmitting.value = true
|
||||||
await useFetch('/api/note', {
|
|
||||||
method: 'DELETE',
|
|
||||||
query: {
|
|
||||||
id: route.params.id,
|
|
||||||
},
|
|
||||||
onResponse({ response }) {
|
|
||||||
isDeleting.value = false
|
|
||||||
console.log('DELETE:', response._data.message)
|
|
||||||
router.push('/notes')
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
if (submitTimeout.value) clearTimeout(submitTimeout.value)
|
||||||
isLoading.value = true
|
|
||||||
refresh()
|
|
||||||
isLoading.value = false
|
|
||||||
})
|
|
||||||
|
|
||||||
watch(
|
submitTimeout.value = setTimeout(async () => {
|
||||||
() => note.value.description,
|
await submitNote(note.value, { id: route.params.id })
|
||||||
() => {
|
isSubmitting.value = false
|
||||||
description.value = note.value.description
|
}, 1000)
|
||||||
input.value = note.value.description
|
}
|
||||||
}
|
|
||||||
)
|
const deleteNote = async () => {
|
||||||
|
isDeleting.value = true
|
||||||
|
await useFetch('/api/note', {
|
||||||
|
method: 'DELETE',
|
||||||
|
query: {
|
||||||
|
id: route.params.id,
|
||||||
|
},
|
||||||
|
onResponse({ response }) {
|
||||||
|
isDeleting.value = false
|
||||||
|
console.log('DELETE:', response._data.message)
|
||||||
|
router.push('/notes')
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
isLoading.value = true
|
||||||
|
refresh()
|
||||||
|
isLoading.value = false
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => input.value,
|
||||||
|
() => {
|
||||||
|
note.value.description = input.value
|
||||||
|
}
|
||||||
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Loading…
Reference in New Issue