Compare commits
2 Commits
b12db15bbe
...
e24b12ecd8
| Author | SHA1 | Date | |
|---|---|---|---|
| e24b12ecd8 | |||
| 1c2fdc1a66 |
File diff suppressed because one or more lines are too long
24
components/ContactFavorite.vue
Normal file
24
components/ContactFavorite.vue
Normal file
@@ -0,0 +1,24 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{
|
||||
contact: Pick<ContactRecord, "favorite">
|
||||
}>();
|
||||
|
||||
const favorite = computed(() => props.contact.favorite);
|
||||
const ariaLabel = computed(() => favorite.value ? "Remove from favorites" : "Add to favorites");
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<form method="post">
|
||||
<button
|
||||
:aria-label=ariaLabel
|
||||
name="favorite"
|
||||
:value="() => favorite ? 'false': 'true'"
|
||||
>
|
||||
{{ favorite ? "★" : "☆" }}
|
||||
</button>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
19
error.vue
Normal file
19
error.vue
Normal file
@@ -0,0 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
import type { NuxtError } from '#app';
|
||||
|
||||
const props = defineProps<{
|
||||
error: NuxtError
|
||||
}>();
|
||||
|
||||
// const handleError = () => clearError({ redirect: '/' });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main id="error-page">
|
||||
<h1>{{ props.error.name }}</h1>
|
||||
<p>{{ props.error.message }}</p>
|
||||
<pre v-if="props.error.stack">
|
||||
<code>{{ props.error.stack }}</code>
|
||||
</pre>
|
||||
</main>
|
||||
</template>
|
||||
39
layouts/default.vue
Normal file
39
layouts/default.vue
Normal file
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<div id="sidebar">
|
||||
<h1>Nuxt Contacts</h1>
|
||||
<div>
|
||||
<form id="search-form" role="search">
|
||||
<input
|
||||
id="q"
|
||||
aria-label="Search contacts"
|
||||
name="q"
|
||||
placeholder="Search"
|
||||
type="search"
|
||||
>
|
||||
<div
|
||||
id="search-spinner"
|
||||
aria-hidden
|
||||
hidden
|
||||
/>
|
||||
</form>
|
||||
<form method="post">
|
||||
<button type="submit">New</button>
|
||||
</form>
|
||||
</div>
|
||||
<nav>
|
||||
<ul>
|
||||
<li>
|
||||
<NuxtLink :to="{name: 'contacts-contactId', params: {contactId: 1}}">Your Name</NuxtLink>
|
||||
</li>
|
||||
<li>
|
||||
<NuxtLink :to="{name: 'contacts-contactId', params: {contactId: 2}}">Your Friend</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
<div id="detail">
|
||||
<slot/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
64
pages/contacts/[contactId].vue
Normal file
64
pages/contacts/[contactId].vue
Normal file
@@ -0,0 +1,64 @@
|
||||
<script setup lang="ts">
|
||||
// const route = useRoute();
|
||||
// route.params.contactId
|
||||
|
||||
const contact = ref({
|
||||
first: "Your",
|
||||
last: "Name",
|
||||
avatar: "https://placecats.com/200/200",
|
||||
twitter: "your_handle",
|
||||
notes: "Some notes",
|
||||
favorite: true,
|
||||
});
|
||||
|
||||
function deleteSubmit(event: Event) {
|
||||
const response = window.confirm(
|
||||
'Please confirm you want to delete this record.'
|
||||
);
|
||||
if (!response) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="contact">
|
||||
<div>
|
||||
<img
|
||||
:key="contact.avatar"
|
||||
:alt="() => `${contact.first} ${contact.last} avatar`"
|
||||
:src="contact.avatar"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h1>
|
||||
<template v-if="contact.first || contact.last">
|
||||
{{ `${contact.first} ${contact.last}` }}
|
||||
</template>
|
||||
<i v-else>No Name</i>
|
||||
<ContactFavorite :contact="contact"/>
|
||||
</h1>
|
||||
<p v-if="contact.twitter">
|
||||
<a :href="`https://twitter.com/${contact.twitter}`">{{ contact.twitter }}</a>
|
||||
</p>
|
||||
<p v-if="contact.notes">{{ contact.notes }}</p>
|
||||
<div>
|
||||
<form action="edit">
|
||||
<button type="submit">Edit</button>
|
||||
</form>
|
||||
|
||||
<form
|
||||
action="destroy"
|
||||
method="post"
|
||||
@submit="deleteSubmit">
|
||||
<button type="submit">Delete</button>
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,49 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
const { $trpc } = useNuxtApp();
|
||||
|
||||
const { data: hello } = await $trpc.hello.useQuery({ text: 'client' });
|
||||
|
||||
// Il typing sul risultato e' corretto, ma sul body no
|
||||
const { data: otherHello } = await useFetch('/api/test/HELLO', {
|
||||
method: 'post',
|
||||
body: {
|
||||
world: 'MONDO'
|
||||
}
|
||||
});
|
||||
|
||||
const clientSide = ref<{
|
||||
trpcData: string,
|
||||
fetchData: string,
|
||||
} | null>(null);
|
||||
|
||||
async function loadNewData() {
|
||||
const [{ data: a1 }, { data: b1 }] = await Promise.all([
|
||||
$trpc.hello.useQuery({ text: 'client' }),
|
||||
useFetch('/api/test/HELLO', {
|
||||
method: 'post',
|
||||
body: {
|
||||
world: 'MONDO'
|
||||
}
|
||||
})
|
||||
]);
|
||||
clientSide.value = { trpcData: a1.value?.greeting ?? 'no', fetchData: b1.value?.risultato ?? 'no2' };
|
||||
}
|
||||
// const { $trpc } = useNuxtApp();
|
||||
//
|
||||
// const { data: hello } = await $trpc.hello.useQuery({ text: 'client' });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h1>Index Page</h1>
|
||||
<div>
|
||||
<p>RPC Client output: {{ hello }}</p>
|
||||
<p>Nuxt API output: {{ otherHello?.risultato }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<button @click="loadNewData">Carica ClientSide</button>
|
||||
<div v-if="clientSide">
|
||||
<p>{{ clientSide.trpcData }}</p>
|
||||
<p>{{ clientSide.fetchData }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="contact">
|
||||
<p>Home Page!</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user