Skip to content

Commit ecf522e

Browse files
committed
feat: add reset button
and refactor components and tweak sizing
1 parent 135c5e7 commit ecf522e

File tree

4 files changed

+93
-35
lines changed

4 files changed

+93
-35
lines changed

app/app.vue

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,36 @@
1+
<script setup lang="ts">
2+
const runs = ref([]);
3+
4+
const handleRequestFormSubmit = async ({ url }): void => {
5+
if (!url.startsWith("http")) {
6+
url = `https://${url}`;
7+
}
8+
9+
try {
10+
// Destructuring would be confusing, since the response body contains fields named `status` and
11+
// `headers` (it's a request about a request...)
12+
const responseBody = await $fetch(
13+
`/api/inspect-url/${encodeURIComponent(url)}`,
14+
);
15+
16+
runs.value.push({
17+
url,
18+
status: responseBody.status,
19+
cacheHeaders: getCacheHeaders(responseBody.headers),
20+
durationInMs: responseBody.durationInMs,
21+
});
22+
} catch (err) {
23+
// TODO(serhalp) Proper error handling. ErrorBoundary?
24+
console.error("Error fetching URL", err);
25+
return;
26+
}
27+
};
28+
29+
const handleClickClear = (): void => {
30+
runs.value = [];
31+
};
32+
</script>
33+
134
<template>
235
<NuxtRouteAnnouncer />
336

@@ -10,8 +43,16 @@
1043
</header>
1144

1245
<main>
13-
<RequestForm />
46+
<RequestForm @submit="handleRequestFormSubmit" />
47+
48+
<div class="flex-btwn run-panels">
49+
<RunPanel v-for="run in runs" v-bind="run" />
50+
</div>
1451
</main>
52+
53+
<div class="reset-container">
54+
<button v-if="runs.length > 0" @click="handleClickClear()">Clear</button>
55+
</div>
1556
</template>
1657

1758
<style>
@@ -30,6 +71,22 @@ header {
3071
}
3172
3273
main {
74+
/* Override very airy defaults from Netlify Examples style, not great for a utility app */
3375
margin-top: 3em;
76+
padding-bottom: 3em;
77+
}
78+
79+
.run-panels {
80+
flex-wrap: wrap;
81+
}
82+
83+
.run-panels>* {
84+
flex: 1 1 20em;
85+
}
86+
87+
.reset-container {
88+
text-align: center;
89+
90+
background-color: inherit;
3491
}
3592
</style>

app/components/RawCacheHeaders.vue

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,9 @@ onUpdated(highlightJson);
1717
<code :ref="id" class="hljs language-json">{{ JSON.stringify(props.cacheHeaders, null, 2) }}</code>
1818
</pre>
1919
</template>
20+
21+
<style scoped>
22+
code {
23+
font-size: 0.7em;
24+
}
25+
</style>

app/components/RequestForm.vue

Lines changed: 5 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,20 @@
11
<script setup lang="ts">
22
const inputUrl = ref();
3-
const runs = ref([]);
43
5-
const inspectUrl = async (): void => {
6-
if (!inputUrl.value.startsWith("http")) {
7-
inputUrl.value = `https://${inputUrl.value}`;
8-
}
9-
10-
try {
11-
// Destructuring would be confusing, since the response body contains fields named `status` and
12-
// `headers` (it's a request about a request...)
13-
const responseBody = await $fetch(
14-
`/api/inspect-url/${encodeURIComponent(inputUrl.value)}`,
15-
);
4+
const emit = defineEmits(["submit"]);
165
17-
runs.value.push({
18-
url: inputUrl.value,
19-
status: responseBody.status,
20-
cacheHeaders: getCacheHeaders(responseBody.headers),
21-
durationInMs: responseBody.durationInMs,
22-
});
23-
} catch (err) {
24-
// TODO(serhalp) Proper error handling. ErrorBoundary?
25-
console.error("Error fetching URL", err);
26-
return;
27-
}
6+
const handleSubmit = () => {
7+
emit("submit", { url: inputUrl.value });
288
};
299
</script>
3010

3111
<template>
3212
<div class="form">
3313
<label class="url-input">
3414
<strong>URL:</strong>
35-
<input v-model.trim="inputUrl" @keyup.enter="inspectUrl()" />
15+
<input v-model.trim="inputUrl" @keyup.enter="handleSubmit()" />
3616
</label>
37-
<button @click="inspectUrl()">Inspect</button>
38-
</div>
39-
40-
<!-- TODO(serhalp) Move this into another component. Wrong place. -->
41-
<div class="flex-btwn">
42-
<div v-for="run in runs">
43-
<h3>{{ run.url }}</h3>
44-
<small>HTTP {{ run.status }} ({{ run.durationInMs }} ms)</small>
45-
<RawCacheHeaders :cacheHeaders="run.cacheHeaders" />
46-
</div>
17+
<button @click="handleSubmit()">Inspect</button>
4718
</div>
4819
</template>
4920

app/components/RunPanel.vue

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<script setup lang="ts">
2+
const props = defineProps<{
3+
url: string;
4+
status: number;
5+
durationInMs: number;
6+
cacheHeaders: Record<string, string>;
7+
}>();
8+
</script>
9+
10+
<template>
11+
<div>
12+
<h3>{{ props.url }}</h3>
13+
14+
<small>HTTP {{ props.status }} ({{ props.durationInMs }} ms)</small>
15+
16+
<RawCacheHeaders :cacheHeaders="props.cacheHeaders" />
17+
</div>
18+
</template>
19+
20+
<style scoped>
21+
h3 {
22+
font-size: 1em;
23+
}
24+
</style>

0 commit comments

Comments
 (0)