Skip to content

Commit

Permalink
sastify the typescript gods
Browse files Browse the repository at this point in the history
  • Loading branch information
bryantgillespie committed Oct 22, 2023
1 parent 8cf328d commit 1251e4b
Show file tree
Hide file tree
Showing 84 changed files with 738 additions and 1,169 deletions.
3 changes: 3 additions & 0 deletions app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ export default defineAppConfig({
loadingIcon: 'material-symbols:sync-rounded',
},
},
badge: {
rounded: 'rounded-button',
},
input: {
default: {
loadingIcon: 'material-symbols:sync-rounded',
Expand Down
2 changes: 1 addition & 1 deletion components/BlockContainer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ withDefaults(defineProps<BlockContainerProps>(), {
});
</script>
<template>
<section :class="['py-24 mx-auto', !fullWidth ? 'px-6 lg:px-16 max-w-6xl' : '']">
<section :class="['py-8 mx-auto', !fullWidth ? 'px-6 lg:px-16 lg:py-24 max-w-6xl' : '']">
<slot />
</section>
</template>
20 changes: 17 additions & 3 deletions components/Category.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,32 @@ const colorChoices = [
'yellow',
];
function randomBackgroundColor(seed, colors) {
function randomBackgroundColor(seed: number, colors: string[]) {
return colors[seed % colors.length];
}
const badgeColor = computed(() => {
return props.color || randomBackgroundColor(slots.default()[0].children.length, colorChoices);
if (props.color) return props.color;
const defaultSlot = slots.default ? slots.default()[0] : undefined;
if (!defaultSlot || !defaultSlot?.children) return null;
return randomBackgroundColor(defaultSlot?.children.length as number, colorChoices);
});
const styleProp = computed(() => {
if (!props.color) return undefined;
return {
backgroundColor: props.color,
color: getContrastColor(props.color),
};
});
</script>

<template>
<span
:style="[props.color ? { backgroundColor: props.color, color: getContrastColor(props.color) } : null]"
:style="styleProp"
:class="[
'inline-flex items-center font-display font-medium rounded-button',
badgeColor === 'gray' ? `bg-gray-100 text-gray-800` : '',
Expand Down
44 changes: 23 additions & 21 deletions components/GlobalSearch.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
<script setup lang="ts">
import type { GlobalSearchResult } from '~/types/api/global-search';
const props = defineProps({
collections: {
type: Array as PropType<string[]>,
required: true,
validator: (value: string[]) => {
return value.every((collection) => {
return ['posts', 'pages', 'categories', 'projects'].includes(collection);
});
},
},
placeholder: {
type: String,
default: 'Search items',
},
});
defineShortcuts({
meta_k: {
usingInput: true,
Expand All @@ -16,7 +34,7 @@ const groups = computed(() => {
return [
{
key: 'search',
label: (q) => q && `Results matching “${q}”...`,
label: (q: string) => q && `Results matching “${q}”...`,
search: async (q: string) => {
loading.value = true;
Expand All @@ -27,14 +45,14 @@ const groups = computed(() => {
}
try {
const { data } = await $fetch('/api/search', {
const { data }: { data: GlobalSearchResult[] } = await $fetch('/api/search', {
params: {
search: q,
collections: props.collections, // Use the collections prop to filter the search
},
});
return data.map((hit) => {
return data.map((hit: any) => {
return {
id: hit.id,
label: hit.title,
Expand All @@ -44,7 +62,7 @@ const groups = computed(() => {
};
});
} catch (error) {
console.log(error);
// console.log(error);
} finally {
loading.value = false;
}
Expand All @@ -53,7 +71,7 @@ const groups = computed(() => {
];
});
function onSelect(option) {
function onSelect(option: any) {
if (option.click) {
option.click();
} else if (option.to) {
Expand All @@ -63,22 +81,6 @@ function onSelect(option) {
}
}
const props = defineProps({
collections: {
type: Array as PropType<string[]>,
required: true,
validator: (value) => {
return value.every((collection) => {
return ['posts', 'pages', 'categories', 'projects'].includes(collection);
});
},
},
placeholder: {
type: String,
default: 'Search items',
},
});
const query = ref('');
const results = ref([]);
const selected = ref(null);
Expand Down
10 changes: 4 additions & 6 deletions components/OgImage/Template.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<script setup lang="ts">
import colors from 'tailwindcss/colors';
const appConfig = useAppConfig();
type DefaultColors = typeof colors;
// console.log(colors[appConfig.ui.primary]);
const appConfig = useAppConfig();
export interface OgImageProps {
imageUrl?: string;
Expand All @@ -13,18 +13,16 @@ export interface OgImageProps {
authorImage?: string;
badgeLabel?: string;
badgeColor?: string;
primaryColor?: string;
grayColor?: string;
}
defineProps<OgImageProps>();
const primaryColor = computed(() => {
return colors[appConfig.ui.primary];
return colors[appConfig.ui.primary as keyof DefaultColors];
});
const grayColor = computed(() => {
return colors[appConfig.ui.gray];
return colors[appConfig.ui.gray as keyof DefaultColors];
});
// inherited attrs can mess up the satori parser
Expand Down
17 changes: 7 additions & 10 deletions components/PageBuilder.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
<script setup lang="ts">
import type { Page } from '~/types';
import type { Page, PageBlock, BlockType } from '~/types';
// Map the page builder collection names to the components
// https://nuxt.com/docs/guide/directory-structure/components#dynamic-components
const map = {
const componentMap: Record<BlockType, any> = {
block_hero: resolveComponent('BlocksHero'),
block_faqs: resolveComponent('BlocksFaqs'),
block_richtext: resolveComponent('BlocksRichText'),
Expand All @@ -17,7 +15,7 @@ const map = {
block_video: resolveComponent('BlocksVideo'),
block_gallery: resolveComponent('BlocksGallery'),
block_steps: resolveComponent('BlocksSteps'),
block_columns: resolveComponent('BlocksColumns'),
block_column: resolveComponent('BlocksColumns'),
block_cardgroup: resolveComponent('BlocksCardGroup'),
block_divider: resolveComponent('BlocksDivider'),
};
Expand All @@ -27,17 +25,16 @@ const props = defineProps<{
}>();
const blocks = computed(() => {
// Filter out hidden blocks
if (!props.page) return;
return props.page.blocks.filter((block) => {
return !block.hide_block;
const blocks = unref(props.page as Page)?.blocks as PageBlock[];
return blocks?.filter((block) => {
return block.hide_block !== true;
});
});
</script>
<template>
<div id="content" class="mx-auto">
<template v-for="block in blocks" :key="block.id">
<component :is="map[block.collection]" :data="block.item" />
<component :is="componentMap[block.collection]" v-if="block && block.collection" :data="block.item" />
</template>
</div>
</template>
25 changes: 8 additions & 17 deletions components/TeamCard.vue
Original file line number Diff line number Diff line change
@@ -1,24 +1,15 @@
<script setup lang="ts">
const { theme } = useAppConfig();
import type { Team } from '~/types';
const props = defineProps<{
person: {
id: string;
name: string;
job_title: string;
image: string;
social_media?: {
service?: string;
url?: string;
};
};
defineProps<{
person: Team;
}>();
const flipped = ref(false);
</script>
<template>
<div class="opacity-0 cursor-pointer select-none animate-fade-in" @click="flipped = !flipped">
<div :class="`relative w-full h-full overflow-hidden group rounded-card`">
<div class="relative w-full h-full overflow-hidden group rounded-card">
<!-- Front of Team Card -->
<NuxtImg
class="object-cover w-full h-full transition duration-300 grayscale group-hover:grayscale-0"
Expand Down Expand Up @@ -74,11 +65,11 @@ const flipped = ref(false);
</Motionable>
<div class="absolute z-10 bottom-4 left-7 right-7">
<TypographyHeadline :content="person.name" size="sm" class="text-white drop-shadow">
{{ person.name }}
<TypographyHeadline v-if="person.name" :content="person.name" size="sm" class="text-white drop-shadow">
{{ person?.name }}
</TypographyHeadline>
<TypographyTitle>
{{ person.job_title }}
<TypographyTitle v-if="person.job_title">
{{ person?.job_title }}
</TypographyTitle>
</div>
Expand Down
1 change: 1 addition & 0 deletions components/base/Author.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const { fileUrl } = useFiles();
<div class="flex items-center flex-none group dark:text-gray-100">
<div class="mr-3">
<img
v-if="image"
:class="[
{
'w-8 h-8 sm:h-10 sm:w-10': size === 'sm',
Expand Down
12 changes: 8 additions & 4 deletions components/base/FormCustom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ const widthClassMap = {
'100': 'md:col-span-6',
};

function renderInput(item, name, state) {
function renderInput(item: { [key: string]: any }, name: string, state: any) {
const commonProps = {
modelValue: state[name],
'onUpdate:modelValue': (value) => (state[name] = value),
'onUpdate:modelValue': (value: any) => (state[name] = value),
};

switch (item.type) {
Expand Down Expand Up @@ -53,11 +53,13 @@ export default defineComponent({
},
setup(props) {
const groups = props.schema.map((item) => {
const { name, label, placeholder, width, description } = item;
const { name, label, placeholder, width, description } = item as { [key: string]: any };

// @ts-ignore
const cssClass = widthClassMap[item.width] || 'md:col-span-6';

return h(FormGroup, { name, label, description, class: cssClass, size: 'lg' }, () => [
// @ts-ignore
renderInput(item, name, props.state),
]);
});
Expand All @@ -71,14 +73,16 @@ export default defineComponent({
type: 'submit',
size: 'lg',
label: 'Submit',
onClick: (event) => {
onClick: (event: Event) => {
event.preventDefault();
// @ts-ignore
props.onSubmit();
},
}),
),
);

// @ts-ignore
return () => h(Form, { state: props.state, validate: props.validate }, () => groups);
},
});
15 changes: 7 additions & 8 deletions components/base/UForm.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script setup lang="ts">
import type { Form } from '~/types';
import type { FormError } from '@nuxt/ui/dist/runtime/types';
import { transformSchema } from '~/utils/formkit';
const props = defineProps<{
Expand All @@ -12,10 +13,10 @@ const emit = defineEmits(['submit', 'update:modelValue']);
const { query } = useRoute();
const formData = reactive({ ...query });
const loading = ref(false);
const error = ref(null);
const error: any = ref(null);
const success = ref(false);
const schema = transformSchema(props.form.schema);
// const schema = transformSchema(props.form.schema);
const validate = (state: any): FormError[] => {
const errors = [];
Expand All @@ -40,7 +41,7 @@ async function submitForm() {
if (props.form.on_success === 'redirect') {
return navigateTo(props.form.redirect_url);
}
} catch (err) {
} catch (err: any) {
error.value = err;
} finally {
loading.value = false;
Expand All @@ -59,11 +60,9 @@ watch(
<div v-auto-animate>
<div class="mb-4">
<VAlert v-if="error" type="error">Oops! {{ error }}</VAlert>
<VAlert
v-if="form.on_success === 'message' && success"
type="success"
v-html="form.success_message ?? 'Success! Your form has been submitted.'"
/>
<VAlert v-if="form.on_success === 'message' && success" type="success">
{{ form.success_message ?? 'Success! Your form has been submitted.' }}
</VAlert>
</div>
<!-- <FormKit v-if="!success" type="form" v-model="formData" @submit="submitForm" :submit-label="form.submit_label"> -->
<div>
Expand Down
2 changes: 1 addition & 1 deletion components/base/VAvatar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const { fileUrl } = useFiles();
},
'object-cover rounded-full dark:brightness-90',
]"
:src="fileUrl(author.avatar)"
:src="fileUrl(author.avatar as string)"
/>
</div>

Expand Down
4 changes: 2 additions & 2 deletions components/base/VBreadcrumbs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ export interface BreadcrumbsProps {
defineProps<BreadcrumbsProps>();
</script>
<template>
<div class="flex flex-wrap items-center space-x-2 text-sm dark:text-gray-200">
<template v-for="(item, itemIdx) in items">
<div class="flex flex-wrap items-center space-x-2 text -sm dark:text-gray-200">
<template v-for="(item, itemIdx) in items" :key="itemIdx">
<template v-if="item.href">
<NuxtLink :href="item.href" class="hover:text-primary">
{{ item.title }}
Expand Down
Loading

0 comments on commit 1251e4b

Please sign in to comment.