diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..42d95fb --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the authors (onWidget) +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/astro.config.mjs b/astro.config.mjs new file mode 100644 index 0000000..f00b057 --- /dev/null +++ b/astro.config.mjs @@ -0,0 +1,73 @@ +import path from 'path'; +import { fileURLToPath } from 'url'; + +import { defineConfig } from 'astro/config'; + +import tailwind from '@astrojs/tailwind'; +import sitemap from '@astrojs/sitemap'; +import image from '@astrojs/image'; +import mdx from '@astrojs/mdx'; +import partytown from '@astrojs/partytown'; +import compress from 'astro-compress'; + +import { remarkReadingTime } from './src/utils/frontmatter.mjs'; +import { SITE } from './src/config.mjs'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +const whenExternalScripts = (items = []) => + SITE.googleAnalyticsId ? (Array.isArray(items) ? items.map((item) => item()) : [items()]) : []; + +export default defineConfig({ + site: SITE.origin, + base: SITE.basePathname, + trailingSlash: SITE.trailingSlash ? 'always' : 'never', + + output: 'static', + + integrations: [ + tailwind({ + config: { + applyBaseStyles: false, + }, + }), + sitemap(), + image({ + serviceEntryPoint: '@astrojs/image/sharp', + }), + mdx(), + + ...whenExternalScripts(() => + partytown({ + config: { forward: ['dataLayer.push'] }, + }) + ), + + compress({ + css: true, + html: true, + img: true, + js: true, + svg: true, + + logger: 1, + }), + ], + + markdown: { + remarkPlugins: [remarkReadingTime], + extendDefaultPlugins: true, + }, + + vite: { + resolve: { + alias: { + '~': path.resolve(__dirname, './src'), + }, + }, + }, + + experimental: { + contentCollections: true, + }, +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000..ca1e8ba --- /dev/null +++ b/package.json @@ -0,0 +1,49 @@ +{ + "name": "@onwidget/astrowind", + "description": "A template to make your website using Astro + Tailwind CSS.", + "version": "0.9.6", + "private": true, + "scripts": { + "dev": "astro dev", + "start": "astro dev", + "build": "astro build", + "preview": "astro preview", + "astro": "astro", + "format": "prettier -w .", + "lint:eslint": "eslint . --ext .js,.ts,.astro", + "subfont": "subfont -ir --no-fallbacks --silent --root dist" + }, + "devDependencies": { + "@astrojs/image": "^0.12.1", + "@astrojs/mdx": "^0.14.0", + "@astrojs/partytown": "^1.0.2", + "@astrojs/rss": "^2.0.0", + "@astrojs/sitemap": "^1.0.0", + "@astrojs/tailwind": "^2.1.3", + "@astrolib/analytics": "^0.2.4", + "@astrolib/seo": "^0.2.1", + "@fontsource/inter": "^4.5.14", + "@tailwindcss/typography": "^0.5.8", + "@typescript-eslint/eslint-plugin": "^5.48.0", + "@typescript-eslint/parser": "^5.48.0", + "astro": "^1.9.1", + "astro-compress": "1.1.25", + "astro-icon": "^0.8.0", + "eslint": "^8.31.0", + "eslint-plugin-astro": "^0.21.1", + "eslint-plugin-jsx-a11y": "^6.6.1", + "limax": "^2.1.0", + "mdast-util-to-string": "^3.1.0", + "prettier": "^2.8.2", + "prettier-plugin-astro": "^0.7.2", + "reading-time": "^1.5.0", + "sharp": "^0.31.3", + "subfont": "^6.12.4", + "svgo": "2.8.0", + "tailwindcss": "^3.2.4", + "typescript": "^4.9.4" + }, + "engines": { + "node": "^14.15.0 || >=16.0.0" + } +} diff --git a/public/_headers b/public/_headers new file mode 100644 index 0000000..1892f57 --- /dev/null +++ b/public/_headers @@ -0,0 +1,2 @@ +/assets/* + Cache-Control: public, max-age=31536000, immutable \ No newline at end of file diff --git a/public/assets/images/pika-logo-text-dark.svg b/public/assets/images/pika-logo-text-dark.svg new file mode 100644 index 0000000..a3d6d14 --- /dev/null +++ b/public/assets/images/pika-logo-text-dark.svg @@ -0,0 +1,15 @@ + + pika-logo-text-dark-svg + + + + + + + + + + + \ No newline at end of file diff --git a/public/assets/images/pika-logo-text.svg b/public/assets/images/pika-logo-text.svg new file mode 100644 index 0000000..8d0cd94 --- /dev/null +++ b/public/assets/images/pika-logo-text.svg @@ -0,0 +1,15 @@ + + pika-logo-text-svg + + + + + + + + + + + \ No newline at end of file diff --git a/public/favicon.svg b/public/favicon.svg new file mode 100644 index 0000000..a1ec6d3 --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1,59 @@ + + pika-logo-svg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..6f27bb6 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: \ No newline at end of file diff --git a/sandbox.config.json b/sandbox.config.json new file mode 100644 index 0000000..9178af7 --- /dev/null +++ b/sandbox.config.json @@ -0,0 +1,11 @@ +{ + "infiniteLoopProtection": true, + "hardReloadOnChange": false, + "view": "browser", + "template": "node", + "container": { + "port": 3000, + "startScript": "start", + "node": "14" + } +} diff --git a/src/assets/images/caos.jpg b/src/assets/images/caos.jpg new file mode 100644 index 0000000..491099b Binary files /dev/null and b/src/assets/images/caos.jpg differ diff --git a/src/assets/images/colors.jpg b/src/assets/images/colors.jpg new file mode 100644 index 0000000..e104e62 Binary files /dev/null and b/src/assets/images/colors.jpg differ diff --git a/src/assets/images/creativity.jpg b/src/assets/images/creativity.jpg new file mode 100644 index 0000000..6a07991 Binary files /dev/null and b/src/assets/images/creativity.jpg differ diff --git a/src/assets/images/default.png b/src/assets/images/default.png new file mode 100644 index 0000000..1ad0959 Binary files /dev/null and b/src/assets/images/default.png differ diff --git a/src/assets/images/do-more.jpg b/src/assets/images/do-more.jpg new file mode 100644 index 0000000..6ede197 Binary files /dev/null and b/src/assets/images/do-more.jpg differ diff --git a/src/assets/images/hero.png b/src/assets/images/hero.png new file mode 100644 index 0000000..72d7df4 Binary files /dev/null and b/src/assets/images/hero.png differ diff --git a/src/assets/images/pika-logo-text-dark.svg b/src/assets/images/pika-logo-text-dark.svg new file mode 100644 index 0000000..a3d6d14 --- /dev/null +++ b/src/assets/images/pika-logo-text-dark.svg @@ -0,0 +1,15 @@ + + pika-logo-text-dark-svg + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/images/pika-logo-text.svg b/src/assets/images/pika-logo-text.svg new file mode 100644 index 0000000..8d0cd94 --- /dev/null +++ b/src/assets/images/pika-logo-text.svg @@ -0,0 +1,15 @@ + + pika-logo-text-svg + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/images/stickers.jpg b/src/assets/images/stickers.jpg new file mode 100644 index 0000000..0c7dbd1 Binary files /dev/null and b/src/assets/images/stickers.jpg differ diff --git a/src/assets/images/tools.jpg b/src/assets/images/tools.jpg new file mode 100644 index 0000000..4af0ee9 Binary files /dev/null and b/src/assets/images/tools.jpg differ diff --git a/src/assets/images/vintage.jpg b/src/assets/images/vintage.jpg new file mode 100644 index 0000000..aa4e5d0 Binary files /dev/null and b/src/assets/images/vintage.jpg differ diff --git a/src/assets/styles/base.css b/src/assets/styles/base.css new file mode 100644 index 0000000..b37a57c --- /dev/null +++ b/src/assets/styles/base.css @@ -0,0 +1,56 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer components { + .btn { + @apply inline-flex items-center justify-center rounded-md shadow-md border-gray-400 border bg-transparent font-medium text-center text-base text-gray-700 leading-snug transition py-3.5 px-6 md:px-7 ease-in duration-200 focus:ring-blue-500 focus:ring-offset-blue-200 focus:ring-2 focus:ring-offset-2 hover:bg-gray-100 hover:border-gray-600 dark:text-slate-300 dark:border-slate-500 dark:hover:bg-slate-800 dark:hover:border-slate-800; + } + + .btn-ghost { + @apply border-none shadow-none text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white; + } + + .btn-primary { + @apply font-semibold bg-primary-800 text-white border-primary-800 hover:bg-primary-900 hover:border-primary-900 hover:text-white dark:text-white dark:bg-primary-700 dark:border-primary-700 dark:hover:border-primary-900 dark:hover:bg-primary-900; + } +} + +#header.scroll { + @apply shadow-md md:shadow-lg bg-white md:bg-white/90 md:backdrop-blur-sm dark:bg-slate-900 dark:md:bg-slate-900/90; +} + +.dropdown:hover .dropdown-menu { + display: block; +} + +[astro-icon].icon-light > * { + stroke-width: 1.2; +} + +[astro-icon].icon-bold > * { + stroke-width: 2.4; +} + +[data-aw-toggle-menu] path { + @apply transition; +} +[data-aw-toggle-menu].expanded g > path:first-child { + @apply -rotate-45 translate-y-[15px] translate-x-[-3px]; +} + +[data-aw-toggle-menu].expanded g > path:last-child { + @apply rotate-45 translate-y-[-8px] translate-x-[14px]; +} + +.dark .pikalogo { + background-image: url("images/pika-logo-text-dark.svg"); + background-position: center; + background-size: cover; +} + +.pikalogo { + background-image: url("images/pika-logo-text.svg"); + background-position: center; + background-size: cover; +} \ No newline at end of file diff --git a/src/components/Card.astro b/src/components/Card.astro new file mode 100644 index 0000000..ee57d4d --- /dev/null +++ b/src/components/Card.astro @@ -0,0 +1,62 @@ +--- +export interface Props { + title: string; + body: string; + href: string; +} + +const { href, title, body } = Astro.props; +--- + + + diff --git a/src/components/common/BasicScripts.astro b/src/components/common/BasicScripts.astro new file mode 100644 index 0000000..a94e924 --- /dev/null +++ b/src/components/common/BasicScripts.astro @@ -0,0 +1,119 @@ +--- +import { SITE } from '~/config.mjs'; +--- + + diff --git a/src/components/common/Fonts.astro b/src/components/common/Fonts.astro new file mode 100644 index 0000000..c455323 --- /dev/null +++ b/src/components/common/Fonts.astro @@ -0,0 +1,5 @@ +--- +import '@fontsource/inter/variable.css'; +--- + + diff --git a/src/components/common/Logo.astro b/src/components/common/Logo.astro new file mode 100644 index 0000000..a02ece4 --- /dev/null +++ b/src/components/common/Logo.astro @@ -0,0 +1,6 @@ +--- +--- + + diff --git a/src/components/common/MetaTags.astro b/src/components/common/MetaTags.astro new file mode 100644 index 0000000..cc7da0b --- /dev/null +++ b/src/components/common/MetaTags.astro @@ -0,0 +1,97 @@ +--- +import { AstroSeo } from '@astrolib/seo'; +import { GoogleAnalytics } from '@astrolib/analytics'; +import { getImage } from '@astrojs/image'; + +import { SITE } from '~/config.mjs'; +import { MetaSEO } from '~/types'; +import { getPermalink, getCanonical } from '~/utils/permalinks'; +import { getRelativeUrlByFilePath } from '~/utils/directories'; + +import Fonts from '~/components/common/Fonts.astro'; +import SplitbeeAnalytics from './SplitbeeAnalytics.astro'; + +export interface Props extends MetaSEO { + dontUseTitleTemplate?: boolean; +} + +const defaultImage = SITE.defaultImage + ? ( + await getImage({ + src: SITE.defaultImage, + alt: 'Default image', + width: 1200, + height: 628, + }) + ).src + : ''; + +const { + title = SITE.name, + description = '', + image: _image = defaultImage, + + canonical = getCanonical(String(Astro.url.pathname)), + noindex = false, + nofollow = false, + + ogTitle = title, + ogType = 'website', + + dontUseTitleTemplate = false, +} = Astro.props; + +const image = + typeof _image === 'string' + ? new URL(_image, Astro.site) + : _image && typeof _image['src'] !== 'undefined' + ? // @ts-ignore + new URL(getRelativeUrlByFilePath(_image.src), Astro.site) + : null; +--- + + + + + + + + + +{SITE.googleSiteVerificationId && } + + +{SITE.googleAnalyticsId && } + +{SITE.splitbeeAnalytics?.enabled && } + + + + diff --git a/src/components/common/Pagination.astro b/src/components/common/Pagination.astro new file mode 100644 index 0000000..cdb3d5c --- /dev/null +++ b/src/components/common/Pagination.astro @@ -0,0 +1,34 @@ +--- +import { Icon } from 'astro-icon'; +import { getPermalink } from '~/utils/permalinks'; + +export interface Props { + prevUrl: string; + nextUrl: string; + prevText?: string; + nextText?: string; +} + +const { prevUrl, nextUrl, prevText = 'Newer posts', nextText = 'Older posts' } = Astro.props; +--- + +{ + (prevUrl || nextUrl) && ( + + ) +} diff --git a/src/components/common/SocialShare.astro b/src/components/common/SocialShare.astro new file mode 100644 index 0000000..ae26912 --- /dev/null +++ b/src/components/common/SocialShare.astro @@ -0,0 +1,30 @@ +--- +import { Icon } from 'astro-icon'; + +export interface Props { + text: string; + url: string | URL; + class?: string; +} + +const { text, url, class: className = 'inline-block' } = Astro.props; +--- + +
+ Share: + + + + + +
diff --git a/src/components/common/SplitbeeAnalytics.astro b/src/components/common/SplitbeeAnalytics.astro new file mode 100644 index 0000000..b3c349a --- /dev/null +++ b/src/components/common/SplitbeeAnalytics.astro @@ -0,0 +1,6 @@ +--- +const { doNotTrack = true, noCookieMode = false, url = 'https://cdn.splitbee.io/sb.js' } = Astro.props; +--- + + + diff --git a/src/components/common/Tags.astro b/src/components/common/Tags.astro new file mode 100644 index 0000000..12bf55f --- /dev/null +++ b/src/components/common/Tags.astro @@ -0,0 +1,29 @@ +--- +import { getPermalink } from '~/utils/permalinks'; + +import type { Post } from '~/types'; + +export interface Props { + tags: Post['tags']; + class?: string; +} + +const { tags, class: className = 'text-sm' } = Astro.props; +--- + +{ + tags && Array.isArray(tags) && ( + + ) +} diff --git a/src/components/common/ToggleMenu.astro b/src/components/common/ToggleMenu.astro new file mode 100644 index 0000000..73d3473 --- /dev/null +++ b/src/components/common/ToggleMenu.astro @@ -0,0 +1,22 @@ +--- +import { Icon } from 'astro-icon'; + +export interface Props { + label?: string; + class?: string; + iconClass?: string; + iconName?: string; +} + +const { + label = 'Toggle Menu', + class: + className = 'ml-1.5 text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 inline-flex items-center transition', + iconClass = 'w-6 h-6', + iconName = 'tabler:menu', +} = Astro.props; +--- + + diff --git a/src/components/common/ToggleTheme.astro b/src/components/common/ToggleTheme.astro new file mode 100644 index 0000000..3ab33d8 --- /dev/null +++ b/src/components/common/ToggleTheme.astro @@ -0,0 +1,22 @@ +--- +import { Icon } from 'astro-icon'; + +export interface Props { + label?: string; + class?: string; + iconClass?: string; + iconName?: string; +} + +const { + label = 'Toggle between Dark and Light mode', + class: + className = 'text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 inline-flex items-center', + iconClass = 'w-6 h-6', + iconName = 'tabler:sun', +} = Astro.props; +--- + + diff --git a/src/components/widgets/Announcement.astro b/src/components/widgets/Announcement.astro new file mode 100644 index 0000000..be58a2b --- /dev/null +++ b/src/components/widgets/Announcement.astro @@ -0,0 +1,28 @@ +--- +import { getPermalink } from '~/utils/permalinks'; +--- + + diff --git a/src/components/widgets/CallToAction.astro b/src/components/widgets/CallToAction.astro new file mode 100644 index 0000000..584bfe7 --- /dev/null +++ b/src/components/widgets/CallToAction.astro @@ -0,0 +1,57 @@ +--- +import { Icon } from 'astro-icon'; + +interface CallToAction { + text: string; + href: string; + icon?: string; +} + +export interface Props { + title?: string; + description?: string; + callToAction?: string | CallToAction; +} + +const { + title = await Astro.slots.render('title'), + subtitle = await Astro.slots.render('subtitle'), + callToAction = await Astro.slots.render('callToAction'), +} = Astro.props; +--- + +
+
+
+
+ { + title && ( +

+ ) + } + {subtitle &&

} + { + typeof callToAction === 'string' ? ( + + ) : ( + callToAction && + callToAction.text && + callToAction.href && ( +

+ ) + ) + } +

+
+
+
diff --git a/src/components/widgets/Content.astro b/src/components/widgets/Content.astro new file mode 100644 index 0000000..8dc0fba --- /dev/null +++ b/src/components/widgets/Content.astro @@ -0,0 +1,107 @@ +--- +import Icon from 'astro-icon'; +import { Picture } from '@astrojs/image/components'; + +interface Item { + title: string; + description?: string; + icon?: string; +} + +export interface Props { + title?: string; + subtitle?: string; + highlight?: string; + content?: string; + items?: Array; + image?: string | any; // TODO: find HTMLElementProps + isReversed?: boolean; + isAfterContent?: boolean; +} + +const { + title = await Astro.slots.render('title'), + subtitle = await Astro.slots.render('subtitle'), + highlight, + content = await Astro.slots.render('content'), + items = [], + image = await Astro.slots.render('image'), + isReversed = false, + isAfterContent = false, +} = Astro.props; +--- + +
+
+ { + (title || subtitle || highlight) && ( +
+ {highlight && ( +

+ )} + {title && ( +

+ )} + + {subtitle && ( +

+ )} +

+ ) + } +
+
+
+
+ {content &&
} + + { + items && ( +
+ {items.map(({ title: title2, description, icon }) => ( +
+
+
+ +
+
+
+ {title2 &&

{title2}

} + {description &&

} +

+
+ ))} +
+ ) + } +
+ +
+
+
diff --git a/src/components/widgets/FAQs.astro b/src/components/widgets/FAQs.astro new file mode 100644 index 0000000..caf3b8b --- /dev/null +++ b/src/components/widgets/FAQs.astro @@ -0,0 +1,66 @@ +--- +import { Icon } from 'astro-icon'; + +interface Item { + question: string; + answer: string; +} + +export interface Props { + title?: string; + subtitle?: string; + highlight?: string; + items: Array>; +} + +const { + title = await Astro.slots.render('title'), + subtitle = await Astro.slots.render('subtitle'), + highlight, + items = [], +} = Astro.props; +--- + +
+
+ { + (title || subtitle || highlight) && ( +
+ {highlight && ( +

+ )} + {title && ( +

+ )} + {subtitle &&

} +

+ ) + } +
+
+
+ { + items && + items.map((subitems) => ( +
+ {subitems.map(({ question, answer }) => ( +
+

+ + {question} +

+ {answer &&
} +
+ ))} +
+ )) + } +
+
+
diff --git a/src/components/widgets/Features.astro b/src/components/widgets/Features.astro new file mode 100644 index 0000000..8b7caab --- /dev/null +++ b/src/components/widgets/Features.astro @@ -0,0 +1,71 @@ +--- +import { Icon } from 'astro-icon'; + +interface Item { + title: string; + description: string; + icon?: string; +} + +export interface Props { + title?: string; + subtitle?: string; + highlight?: string; + items: Array>; +} + +const { + title = await Astro.slots.render('title'), + subtitle = await Astro.slots.render('subtitle'), + highlight, + items = [], +} = Astro.props; +--- + +
+
+ { + (title || subtitle || highlight) && ( +
+ {highlight && ( +

+ )} + {title && ( +

+ )} + + {subtitle && ( +

+ )} +

+ ) + } +
+ { + items.map((subitems) => ( +
+ {subitems.map(({ title, description, icon }) => ( +
+
+
+ {icon && } +
+
+
+

{title}

+

+

+
+ ))} +
+ )) + } +
+
+
diff --git a/src/components/widgets/Features2.astro b/src/components/widgets/Features2.astro new file mode 100644 index 0000000..23505af --- /dev/null +++ b/src/components/widgets/Features2.astro @@ -0,0 +1,69 @@ +--- +import { Icon } from 'astro-icon'; + +interface Item { + title?: string; + description?: string; + icon?: string; +} + +export interface Props { + title?: string; + subtitle?: string; + highlight?: string; + items: Array; +} + +const { + title = await Astro.slots.render('title'), + subtitle = await Astro.slots.render('subtitle'), + highlight, + items = [], +} = Astro.props; +--- + +
+ +
+
+ { + (title || subtitle || highlight) && ( +
+ {highlight && ( +

+ )} + {title && ( +

+ )} + + {subtitle && ( +

+ )} +

+ ) + } +
+ { + items.map(({ title, description, icon }) => ( +
+
+ +
{title}
+
+ {description &&

} +

+ )) + } +
+
+
+
diff --git a/src/components/widgets/Footer.astro b/src/components/widgets/Footer.astro new file mode 100644 index 0000000..54c055e --- /dev/null +++ b/src/components/widgets/Footer.astro @@ -0,0 +1,70 @@ +--- +import { Icon } from 'astro-icon'; +import { getHomePermalink, getPermalink } from '~/utils/permalinks'; + +const links = [ + { + title: 'PikaOS', + items: [ + { title: 'Features', href: '#features' }, + { title: 'Download', href: '#download' }, + ], + }, +]; + +const social = [ + { label: 'Discord', icon: 'tabler:brand-discord', href: 'https://discord.gg/aGR4YFCB' }, + { label: 'Github', icon: 'tabler:brand-github', href: 'https://github.com/PikaOS-Linux' }, +]; +--- + +
+
+
+ { + links.map(({ title, items }) => ( +
+
{title}
+ {items && Array.isArray(items) && items.length > 0 && ( + + )} +
+ )) + } +
+
+
    + { + social.map(({ label, href, icon }) => ( +
  • + + + +
  • + )) + } +
+ +
+ + Made by the PikaOS team Β· + All rights reserved. +
+
+
+
diff --git a/src/components/widgets/Header.astro b/src/components/widgets/Header.astro new file mode 100644 index 0000000..3a80670 --- /dev/null +++ b/src/components/widgets/Header.astro @@ -0,0 +1,91 @@ +--- +import { Icon } from 'astro-icon'; +import Logo from '~/components/common/Logo.astro'; +import ToggleTheme from '~/components/common/ToggleTheme.astro'; +import ToggleMenu from '~/components/common/ToggleMenu.astro'; + +import { getHomePermalink} from '~/utils/permalinks'; + +const links = [ + { + text: 'Features', + href: '#features', + }, + { + text: 'Download', + href: '#download', + }, + // { + // text: 'About us', + // href: '#about', + // }, +]; +--- + + diff --git a/src/components/widgets/Hero.astro b/src/components/widgets/Hero.astro new file mode 100644 index 0000000..6075fd8 --- /dev/null +++ b/src/components/widgets/Hero.astro @@ -0,0 +1,106 @@ +--- +import { Icon } from 'astro-icon'; +import { Picture } from '@astrojs/image/components'; + +interface CallToAction { + text: string; + href: string; + icon?: string; +} + +export interface Props { + title?: string; + subtitle?: string; + callToAction?: string | CallToAction; + callToAction2?: string | CallToAction; + image?: string | any; // TODO: find HTMLElementProps +} + +const { + title = await Astro.slots.render('title'), + subtitle = await Astro.slots.render('subtitle'), + callToAction = await Astro.slots.render('callToAction'), + callToAction2 = await Astro.slots.render('callToAction2'), + image = await Astro.slots.render('image'), +} = Astro.props; +--- + +
+
+
+
+ { + title && ( +

+ ) + } +
+ {subtitle &&

} +

+ { + callToAction && ( +
+ {typeof callToAction === 'string' ? ( + + ) : ( + + {callToAction?.icon && ( + <> + {' '} + + )} + {callToAction?.text} + + )} +
+ ) + } + { + callToAction2 && ( +
+ {typeof callToAction2 === 'string' ? ( + + ) : ( + + {callToAction2?.icon && ( + <> + {' '} + + )} + {callToAction2.text} + + )} +
+ ) + } +
+
+

+
+ { + image && ( +
+ {typeof image === 'string' ? ( + + ) : ( + + )} +
+ ) + } +
+
+
+
diff --git a/src/components/widgets/Note.astro b/src/components/widgets/Note.astro new file mode 100644 index 0000000..7ac3326 --- /dev/null +++ b/src/components/widgets/Note.astro @@ -0,0 +1,11 @@ +--- +import { Icon } from 'astro-icon'; +--- + +
+
+ + PikaOS: Performance, Simplicity and Birb +
+
diff --git a/src/components/widgets/Pricing.astro b/src/components/widgets/Pricing.astro new file mode 100644 index 0000000..0161e91 --- /dev/null +++ b/src/components/widgets/Pricing.astro @@ -0,0 +1,274 @@ +--- +--- + + +
+ +
+

Pricing

+

+ Whatever your status, our offers evolve according to your needs. +

+
+ + + +
+ +
+

Free

+ Free +

Forever free

+ +
    +
  • + + + + 1 user +
  • + +
  • + + + + Plan features +
  • + +
  • + + + + Product support +
  • +
+ + +
+ + + +
+

+ Most popular +

+

Startup

+ + $ + 39 + +

All the basics for starting a new business

+ +
    +
  • + + + + 2 users +
  • + +
  • + + + + Plan features +
  • + +
  • + + + + Product support +
  • +
+ + +
+ + + +
+

Team

+ + $ + 89 + +

Everything you need for a growing business

+ +
    +
  • + + + + 5 users +
  • + +
  • + + + + Plan features +
  • + +
  • + + + + Product support +
  • +
+ + +
+ + + +
+

Enterprise

+ + $ + 149 + +

Advanced features for scaling your business

+ +
    +
  • + + + + 10 users +
  • + +
  • + + + + Plan features +
  • + +
  • + + + + Product support +
  • +
+ + +
+ +
+ +
+ diff --git a/src/components/widgets/Stats.astro b/src/components/widgets/Stats.astro new file mode 100644 index 0000000..ed716b4 --- /dev/null +++ b/src/components/widgets/Stats.astro @@ -0,0 +1,57 @@ +--- +interface Item { + name: string; + value: string; +} + +export interface Props { + title?: string; + subtitle?: string; + highlight?: string; + items?: Array; +} + +const { + title = await Astro.slots.render('title'), + subtitle = await Astro.slots.render('subtitle'), + highlight, + items = [], +} = Astro.props; +--- + +
+ { + (title || subtitle || highlight) && ( +
+ {highlight && ( +

+ {highlight} +

+ )} + {title && ( +

+ )} + {subtitle && ( +

+ )} +

+ ) + } +
+ { + items.map(({ name, value }) => ( +
+
+ {value} +
+

+ {name} +

+
+ )) + } +
+
diff --git a/src/components/widgets/Steps.astro b/src/components/widgets/Steps.astro new file mode 100644 index 0000000..3e3ba66 --- /dev/null +++ b/src/components/widgets/Steps.astro @@ -0,0 +1,72 @@ +--- +import { Icon } from 'astro-icon'; +import { Picture } from '@astrojs/image/components'; + +interface Item { + title: string; + description?: string; + icon?: string; +} + +export interface Props { + title?: string; + items: Array; + image?: string | any; // TODO: find HTMLElementProps +} + +const { + title = await Astro.slots.render('title'), + items = [], + image = await Astro.slots.render('image'), +} = Astro.props; +--- + +
+
+
+ {title &&

} + { + items && + items.length && + items.map(({ title, description, icon }, index) => ( +
+
+
+ {index !== items.length - 1 ? ( +
+ {icon && } +
+ ) : ( +
+ +
+ )} +
+
+
+
+ {title &&

} + {description &&

} +

+
+ )) + } +
+
+ { + image && + (typeof image === 'string' ? ( + + ) : ( + + )) + } +
+

+
diff --git a/src/components/widgets/Steps2.astro b/src/components/widgets/Steps2.astro new file mode 100644 index 0000000..05be448 --- /dev/null +++ b/src/components/widgets/Steps2.astro @@ -0,0 +1,127 @@ +--- +import { Icon } from 'astro-icon'; + +interface Item { + title: string; + description: string; + icon?: string; +} + +interface CallToAction { + text: string; + href: string; + icon?: string; +} + +export interface Props { + title?: string; + subtitle?: string; + highlight?: string; + callToAction?: string | CallToAction; + items: Array; +} + +const { + title = await Astro.slots.render('title'), + subtitle = await Astro.slots.render('subtitle'), + highlight, + callToAction = await Astro.slots.render('callToAction'), + items = [], +} = Astro.props; + +/** + * + + + + + */ +--- + +
+
+
+
+
+
+
+ { + highlight && ( +

+ ) + } + {title &&

} + {subtitle &&

} + +

+ { + typeof callToAction === 'string' ? ( + + ) : ( + callToAction && + callToAction.text && + callToAction.href && ( + + {callToAction.icon && } + {callToAction.text} + + ) + ) + } +
+

+
+
+
    + { + items && items.length + ? items.map(({ title: title2, description, icon }, index) => ( +
  • +
    + + {icon ? : index + 1} + +
    +
    +

    +

    +

    +
  • + )) + : '' + } +
+
+
+
+
+
+
diff --git a/src/config.mjs b/src/config.mjs new file mode 100644 index 0000000..d5c1474 --- /dev/null +++ b/src/config.mjs @@ -0,0 +1,32 @@ +import defaultImage from './assets/images/default.png'; + +const CONFIG = { + name: 'PikaOS', + + origin: 'https://pikaos.ferreo.dev', + basePathname: '/', + trailingSlash: false, + + title: 'PikaOS β€” The cool birb OS', + description: 'PikaOS is a gaming focused linux distribution focussing on ease of use and high compatability. Using the know how from Nobara combined with a Ubuntu base, PikaOS is almost unrivaled in software comaptability.', + defaultImage: defaultImage, + + defaultTheme: 'system', // Values: "system" | "light" | "dark" | "light:only" | "dark:only" + + language: 'en', + textDirection: 'ltr', + + dateFormatter: new Intl.DateTimeFormat('en', { + year: 'numeric', + month: 'short', + day: 'numeric', + timeZone: 'UTC', + }), + + googleAnalyticsId: false, // or "G-XXXXXXXXXX", + googleSiteVerificationId: false, + +}; + +export const SITE = {...CONFIG }; +export const DATE_FORMATTER = CONFIG.dateFormatter; \ No newline at end of file diff --git a/src/content/config.ts b/src/content/config.ts new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/content/config.ts @@ -0,0 +1 @@ + diff --git a/src/content/types.generated.d.ts b/src/content/types.generated.d.ts new file mode 100644 index 0000000..464c652 --- /dev/null +++ b/src/content/types.generated.d.ts @@ -0,0 +1,49 @@ +declare module 'astro:content' { + export { z } from 'astro/zod'; + export type CollectionEntry = + typeof entryMap[C][keyof typeof entryMap[C]] & Render; + + type BaseCollectionConfig = { + schema?: S; + slug?: (entry: { + id: CollectionEntry['id']; + defaultSlug: string; + collection: string; + body: string; + data: import('astro/zod').infer>; + }) => string | Promise; + }; + export function defineCollection( + input: BaseCollectionConfig + ): BaseCollectionConfig; + + export function getEntry( + collection: C, + entryKey: E + ): Promise; + export function getCollection< + C extends keyof typeof entryMap, + E extends keyof typeof entryMap[C] + >( + collection: C, + filter?: (data: typeof entryMap[C][E]) => boolean + ): Promise<(typeof entryMap[C][E] & Render)[]>; + + type InferEntrySchema = import('astro/zod').infer< + import('astro/zod').ZodObject['schema']> + >; + + type Render = { + render(): Promise<{ + Content: import('astro').MarkdownInstance<{}>['Content']; + headings: import('astro').MarkdownHeading[]; + injectedFrontmatter: Record; + }>; + }; + + const entryMap: { + + }; + + type ContentConfig = never; +} diff --git a/src/env.d.ts b/src/env.d.ts new file mode 100644 index 0000000..9231795 --- /dev/null +++ b/src/env.d.ts @@ -0,0 +1 @@ +/// diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro new file mode 100644 index 0000000..80ff7a2 --- /dev/null +++ b/src/layouts/BaseLayout.astro @@ -0,0 +1,33 @@ +--- +import '~/assets/styles/base.css'; + +import MetaTags from '~/components/common/MetaTags.astro'; +import BasicScripts from '~/components/common/BasicScripts.astro'; + +import { MetaSEO } from '~/types'; +import { SITE } from '~/config.mjs'; + +export interface Props { + meta?: MetaSEO; +} + +const { meta = {} } = Astro.props; +const { language = 'en', textDirection = 'ltr' } = SITE; +--- + + + + + + + + + + + + + diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro new file mode 100644 index 0000000..f1a62a5 --- /dev/null +++ b/src/layouts/Layout.astro @@ -0,0 +1,35 @@ +--- +export interface Props { + title: string; +} + +const { title } = Astro.props; +--- + + + + + + + + + {title} + + + + + + diff --git a/src/layouts/MarkdownLayout.astro b/src/layouts/MarkdownLayout.astro new file mode 100644 index 0000000..d339178 --- /dev/null +++ b/src/layouts/MarkdownLayout.astro @@ -0,0 +1,32 @@ +--- +import Layout from '~/layouts/BaseLayout.astro'; +import Header from '~/components/widgets/Header.astro'; +import Footer from '~/components/widgets/Footer.astro'; +import Announcement from '~/components/widgets/Announcement.astro'; + +import { MetaSEO } from '~/types'; + +export interface Props {} + +const { frontmatter } = Astro.props; + +const meta: MetaSEO = { + title: frontmatter?.title, +}; +--- + + + +
+
+
+

{frontmatter.title}

+
+ +
+
+
+