diff --git a/src/lib/utils/formatParse.ts b/src/lib/utils/formatParse.ts index 2d99924..bcb752c 100644 --- a/src/lib/utils/formatParse.ts +++ b/src/lib/utils/formatParse.ts @@ -36,23 +36,22 @@ export const removeTrailingSlash = (site: string) => { import fs from 'fs'; import path from 'path'; -export async function readJsonFile(filePath: string) { +export const readJsonFile = async (filePath: string) => { const jsonData = await fs.readFileSync(path.join(process.cwd(), 'src', 'content', filePath), 'utf-8'); return JSON.parse(jsonData); } // ======= MARKDOWN PARSER ======== - // https://github.com/jonschlinkert/gray-matter import * as matter from 'gray-matter'; // https://github.com/markedjs/marked // import marked from 'marked'; -export async function parseMarkdownFile(filePath: string) { +export const parseMarkdownFile = async (filePath: string) => { const markdownData = await fs.readFileSync(path.join(process.cwd(), 'src', 'content', filePath), 'utf-8'); const { data, content } = matter(markdownData); - return { frontmatter: data, content }; + return { frontmatter: data, content }; } // export function parseMarkdown(filePath: string): { frontmatter: T; content: string } { // const data = matter.read(filePath).data; @@ -66,3 +65,5 @@ export async function parseMarkdownFile(filePath: string) { // return { frontmatter: data, content }; // } + +console.log(parseMarkdownFile('../../content/permanentni-make-up/pmu/pmu.md')) diff --git a/src/lib/utils/getOGImage.ts b/src/lib/utils/getOGImage.ts new file mode 100644 index 0000000..a150db1 --- /dev/null +++ b/src/lib/utils/getOGImage.ts @@ -0,0 +1,49 @@ +// https://cloudinary.com/blog/guest_post/setup-a-developer-blog-with-social-images-using-sveltekit + +import cloudinary from 'cloudinary'; + +cloudinary.v2.config({ + cloud_name: import.meta.env.VITE_CLOUDINARY_CLOUD_NAME, +}); + + +async function getOgImage({ title, subTitle }) { + const url = cloudinary.v2.url('example_og_image.jpg', { + transformation: [ + { width: 1200, height: 627, crop: 'fill', quality: 'auto', format: 'auto' }, + { + crop: 'fit', + width: 700, + x: 480, + y: 254, + gravity: 'south_west', + color: 'white', + effect: 'shadow:40', + overlay: { + font_family: 'roboto', + font_size: 54, + font_weight: 'bold', + text: encodeURIComponent(title) + } + }, + { + crop: 'fit', + width: 700, + x: 480, + y: 154, + gravity: 'south_west', + color: 'white', + overlay: { + font_family: 'roboto', + font_size: 34, + font_weight: 'bold', + text: encodeURIComponent(subTitle) + } + } + ] + }); + + return url; +} + +export default getOgImage; diff --git a/src/lib/utils/helpers.ts b/src/lib/utils/helpers.ts new file mode 100644 index 0000000..8cc5d44 --- /dev/null +++ b/src/lib/utils/helpers.ts @@ -0,0 +1,60 @@ +import { readable } from 'svelte/store'; + +/** + * Determines if the current timezone is between 0 and +3 hours UTC. + * @returns {boolean} True if the timezone is between 0 and +3 hours UTC, false otherwise. + */ +export const isEurope = () => { + const offset = new Date().getTimezoneOffset(); + return offset <= 0 && offset >= -180; // Returns true if the timezone is between 0 and +3 hours UTC, false otherwise +}; + +/** + * Toggles the 'overflow-y-hidden' class on the 'html' element of the document. + * @param bool A boolean value indicating whether to show or hide the overflow-y scrollbar. + */ +export const showHideOverflowY = (bool: boolean) => { + const html = document.querySelector('html'); + if (html) { + if (bool) { + html.classList.add('overflow-y-hidden'); + } else { + html.classList.remove('overflow-y-hidden'); + } + } +}; + +/** + * Checks if a given URL is an external link. + * @param href - The URL to check. + * @returns True if the URL is an external link, false otherwise. + */ +export const isAnExternalLink = (href: string) => href.startsWith('http'); + +/** + * Checks if the user agent is running on a Mac or iPad. + * @returns {boolean} Returns true if the user agent is running on a Mac or iPad, false otherwise. + */ +export const isMac = () => + navigator.userAgent.includes('Macintosh') || navigator.userAgent.includes('iPad'); + +/** + * Returns a readable store that tracks whether the media query string matches the current viewport. + * @param mediaQueryString - The media query string to match against the viewport. + * @returns A readable store that tracks whether the media query string matches the current viewport. + */ +export const useMediaQuery = (mediaQueryString: string) => { + const matches = readable(undefined, (set) => { + if (typeof globalThis['window'] === 'undefined') return; + + const match = window.matchMedia(mediaQueryString); + set(match.matches); + const element = (event: MediaQueryListEvent) => set(event.matches); + match.addEventListener('change', element); + return () => { + match.removeEventListener('change', element); + }; + }); + return matches; +}; + diff --git a/src/lib/utils/list.ts b/src/lib/utils/list.ts new file mode 100644 index 0000000..a6bf6a7 --- /dev/null +++ b/src/lib/utils/list.ts @@ -0,0 +1,11 @@ +import { readJsonFile, parseMarkdownFile } from '../utils/formatParse'; + +export function listservices({params}) { + const servicesJson = readJsonFile('./path/to/services.json'); + const services = servicesJson.map((service: Service) => { + const markdownData = parseMarkdownFile(`./path/to/blog/${service.slug}.md`); + return { ...service, ...markdownData }; + }); + + return services; +}