Skip to content

Commit

Permalink
feat: webapi detail pages
Browse files Browse the repository at this point in the history
  • Loading branch information
toniengelhardt committed Feb 13, 2023
1 parent 1fd2087 commit 4524f98
Show file tree
Hide file tree
Showing 13 changed files with 355 additions and 106 deletions.
46 changes: 46 additions & 0 deletions components/api/Status.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<script setup lang="ts">
defineProps<{
status?: WebAPIStatus
}>()
</script>

<template>
<div class="status" :class="status?.name">
<span class="status-icon">
<Icon :name="status?.icon || ''" />
</span>
<span class="status-label">
{{ status?.label }}
</span>
</div>
</template>

<style lang="postcss" scoped>
.status {
@apply flex items-center;
&.available {
.status-icon {
@apply text-lime-600 border-lime-600 dark:(text-lime-300 border-lime-300);
}
}
&.experimental {
.status-icon {
@apply text-purple-700 border-purple-700 dark:(text-purple-300 border-purple-300);
}
}
&.unavailable {
.status-icon {
@apply text-rose-500 border-rose-500;
}
}
.status-icon {
@apply flex justify-center items-center w-4 h-4 border-solid border-1 rounded-full box-border;
.icon {
@apply text-0.6rem;
}
.status-label {
@apply ml-1.5 text-xs;
}
}
}
</style>
5 changes: 4 additions & 1 deletion components/api/grid/Grid.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 2xl:grid-cols-5 gap-1 p-1">
<ApiGridItem
v-for="api in apis"
:key="api.key"
:key="api.name"
:api="api"
:available="webApiStatuses[api.id]"
/>
</div>
</template>
Expand All @@ -12,4 +13,6 @@
defineProps<{
apis: WebAPI[]
}>()
const webApiStatuses: Ref<{ [key: keyof typeof webApiData]: boolean }> = useState('webApiStatuses')
</script>
10 changes: 5 additions & 5 deletions components/api/grid/GridItem.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
<template>
<NuxtLink
:to="api.url"
:to="`/apis/${api.id}`"
:title="`${api.name} documentation`"
target="_blank"
class="grid-item" :class="itemClass"
@click="useTrackEvent('click: API link', { props: { api: api.name } })"
>
Expand All @@ -16,7 +15,7 @@
{{ api.path || 'N/A' }}
</div>
<div class="flex-1 min-h-12">
<template v-if="api.available">
<template v-if="available">
<component
:is="api.detail"
v-if="api.detail"
Expand Down Expand Up @@ -57,10 +56,11 @@
<script setup lang="ts">
const props = defineProps<{
api: WebAPI
available?: boolean
}>()
const status = computed(() => {
if (props.api.available) {
if (props.available) {
if (props.api.experimental) {
return {
name: 'experimental',
Expand All @@ -74,7 +74,7 @@ const status = computed(() => {
label: 'Available',
}
}
if (props.api.available === false) {
if (props.available === false) {
return {
name: 'unavailable',
icon: 'cross',
Expand Down
5 changes: 4 additions & 1 deletion components/api/list/List.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
<div class="grid grid-cols-1 gap-0.5 p-0.5">
<ApiListItem
v-for="api in apis"
:key="api.key"
:key="api.name"
:api="api"
:available="webApiStatuses[api.id]"
/>
</div>
</template>
Expand All @@ -12,4 +13,6 @@
defineProps<{
apis: WebAPI[]
}>()
const webApiStatuses: Ref<{ [key: keyof typeof webApiData]: boolean }> = useState('webApiStatuses')
</script>
5 changes: 3 additions & 2 deletions components/api/list/ListItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@
<script setup lang="ts">
const props = defineProps<{
api: WebAPI
available?: boolean
}>()
const status = computed(() => {
if (props.api.available) {
if (props.available) {
if (props.api.experimental) {
return {
name: 'experimental',
Expand All @@ -43,7 +44,7 @@ const status = computed(() => {
label: 'Available',
}
}
if (props.api.available === false) {
if (props.available === false) {
return {
name: 'unavailable',
icon: 'cross',
Expand Down
10 changes: 7 additions & 3 deletions components/brand/Name.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<template>
<div class="text-1.2rem font-bold text-zinc-500 dark:text-zinc-400">
<span class="text-base dark:text-white font-black">WebAPI</span> check
</div>
<NuxtLink
to="/"
title="Home"
text-1.2rem font-bold
>
<span class="text-base dark:text-white font-black">WebAPI</span> <span text-dim>check</span>
</NuxtLink>
</template>
38 changes: 38 additions & 0 deletions composables/webapis.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
export const useWebApiList = () => {
const list = Object.keys(webApiData).reduce((list: WebAPI[], apiKey: string) => {
list.push({
id: apiKey,
...webApiData[apiKey],
})
return list
}, [])
sortByField(list, 'name')
return ref(list)
}

export const useWebApiStatus = (api: WebAPI, available?: boolean) => {
return computed(() => {
if (available) {
if (api.experimental) {
return {
name: 'experimental',
icon: 'experimental',
label: 'Experimental',
}
}
return {
name: 'available',
icon: 'check',
label: 'Available',
}
}
if (available === false) {
return {
name: 'unavailable',
icon: 'cross',
label: 'Not available',
}
}
return undefined
})
}
160 changes: 160 additions & 0 deletions pages/apis/[id].vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
<script setup lang="ts">
definePageMeta({
validate: ({ params }) => {
return Object.keys(webApiData).includes(params.id.toString())
},
})
const route = useRoute()
const webAPIStatuses: Ref<{ [key: keyof typeof webApiData]: boolean }> = useState('WebAPIStatuses')
const webApiId = computed(() => route.params.id.toString())
const webApi = computed(() => ({ id: webApiId.value, ...webApiData[webApiId.value] }))
const available = computed(() => webAPIStatuses.value[webApiId.value])
const status = computed(() => {
if (available) {
if (webApi.value.experimental) {
return {
name: 'experimental',
icon: 'experimental',
label: 'Available on this device (experimental)',
}
}
return {
name: 'available',
icon: 'check',
label: 'Available on this device',
}
}
if (available === false) {
return {
name: 'unavailable',
icon: 'cross',
label: 'Not available on this device',
}
}
return undefined
})
</script>

<template>
<div>
<NuxtLayout>
<div max-w-screen-lg mx-auto px-4>
<h1>{{ webApi.name }}</h1>
<div class="status" :class="status?.name">
<span class="status-icon">
<Icon :name="status?.icon || ''" />
</span>
<span class="status-label">
{{ status?.label }}
</span>
</div>
<div class="box" grid md:grid-cols-2 gap-4 mt-8>
<div>
<div class="label">
Property
</div>
<div class="value">
{{ webApi.path }}
</div>
</div>
<div>
<div class="label">
Source
</div>
<div class="value">
<ApiSource :api="webApi" />
</div>
</div>
<div>
<div class="label">
Documentation
</div>
<div inline-flex items-center>
<NuxtLink
:to="webApi.path"
:title="`Documentation for ${webApi.name}`"
target="_blank"
btn-xs btn-outline
>
OPEN <Icon name="external" class="ml-0.5" />
</NuxtLink>
</div>
</div>
</div>
<div mt-8>
<div v-if="webApi.experimental" class="panel">
<div flex items-center>
<Icon name="experimental" mr-1.5 text-faint size="1.25rem" /> Experimental
</div>
</div>
<div v-if="webApi.availableInWebWorkers" class="panel">
<div flex items-center>
<Icon name="webworker" mr-1.5 text-faint size="1.25rem" /> Available in Web Workers
</div>
</div>
<div v-if="webApi.userInteractionRequired" class="panel">
<div flex items-center>
<Icon name="interaction" mr-1.5 text-faint size="1.25rem" /> User interaction required
</div>
</div>
<div v-if="webApi.permissionsRequired" class="panel">
<div flex items-center>
<Icon name="permission" mr-1.5 text-faint size="1.25rem" /> Permission/s required
</div>
</div>
<div v-if="webApi.secureContextRequired" class="panel">
<div flex items-center>
<Icon name="secure" mr-1.5 text-faint size="1.25rem" /> Secure context required
</div>
</div>
</div>
</div>
</NuxtLayout>
</div>
</template>

<style lang="postcss" scoped>
h1 {
@apply my-8;
}
.status {
@apply flex items-center;
&.available {
.status-icon {
@apply text-lime-600 border-lime-600 dark:(text-lime-300 border-lime-300);
}
}
&.experimental {
.status-icon {
@apply text-purple-700 border-purple-700 dark:(text-purple-300 border-purple-300);
}
}
&.unavailable {
.status-icon {
@apply text-rose-500 border-rose-500;
}
}
.status-icon {
@apply flex justify-center items-center w-6 h-6 border-solid border-1 rounded-full box-border;
}
.status-label {
@apply ml-2.5;
}
}
.box {
@apply p-4 border-solid border-1 border-base rounded;
}
.panel {
@apply p-4 bg-surface not-first:mt-4 rounded;
}
.label {
@apply mb-1.5 text-sm text-dim font-bold;
}
.value {
@apply flex items-center h-5;
}
</style>
Loading

0 comments on commit 4524f98

Please sign in to comment.