Compare commits
2 Commits
a06e0cb76a
...
ed306ae554
| Author | SHA1 | Date | |
|---|---|---|---|
|
ed306ae554
|
|||
|
2598f6c112
|
28
app/app.vue
28
app/app.vue
@@ -1,8 +1,5 @@
|
||||
<template>
|
||||
<n-config-provider
|
||||
:theme-overrides="themeOverrides"
|
||||
:theme="theme.value === 'dark' ? darkTheme : lightTheme"
|
||||
>
|
||||
<naive-config>
|
||||
<n-global-style />
|
||||
<n-loading-bar-provider>
|
||||
<n-dialog-provider>
|
||||
@@ -13,33 +10,18 @@
|
||||
</n-message-provider>
|
||||
</n-dialog-provider>
|
||||
</n-loading-bar-provider>
|
||||
</n-config-provider>
|
||||
</naive-config>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
darkTheme,
|
||||
lightTheme,
|
||||
NConfigProvider,
|
||||
NGlobalStyle,
|
||||
NLoadingBarProvider,
|
||||
NDialogProvider,
|
||||
NMessageProvider,
|
||||
} from "naive-ui";
|
||||
|
||||
import '@fontsource-variable/nunito';
|
||||
|
||||
const themeOverrides = {
|
||||
common: {
|
||||
fontFamily: "Nunito Variable, v-sans, ui-system, -apple-system, sans-serif",
|
||||
primaryColor: "#7D80BAFF",
|
||||
primaryColorHover: "#9294C5FF",
|
||||
primaryColorPressed: "#575B9DFF",
|
||||
primaryColorSuppl: "#6B6FC1FF",
|
||||
},
|
||||
};
|
||||
|
||||
const theme = useColorMode();
|
||||
import "@fontsource-variable/nunito";
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@@ -47,7 +29,9 @@ html,
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-family: Nunito Variable, sans-serif;
|
||||
font-family:
|
||||
Nunito Variable,
|
||||
sans-serif;
|
||||
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
29
app/assets/css/main.css
Normal file
29
app/assets/css/main.css
Normal file
@@ -0,0 +1,29 @@
|
||||
@import "tailwindcss";
|
||||
@plugin "daisyui";
|
||||
@plugin "@tailwindcss/typography";
|
||||
|
||||
@layer theme, base, components, utilities;
|
||||
@import "tailwindcss/theme.css" layer(theme);
|
||||
@import "tailwindcss/utilities.css" layer(utilities);
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--font-family: "Nunito Variable", "Helvatica", sans-serif;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
font-family: var(--font-family);
|
||||
}
|
||||
}
|
||||
|
||||
.page-enter-active,
|
||||
.page-leave-active {
|
||||
transition: all 0.4s;
|
||||
}
|
||||
|
||||
.page-enter-from,
|
||||
.page-leave-to {
|
||||
opacity: 0;
|
||||
filter: blur(1rem);
|
||||
}
|
||||
13
app/auto-imports.d.ts
vendored
Normal file
13
app/auto-imports.d.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
// @ts-nocheck
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
// Generated by unplugin-auto-import
|
||||
// biome-ignore lint: disable
|
||||
export {}
|
||||
declare global {
|
||||
const useDialog: typeof import('naive-ui').useDialog
|
||||
const useLoadingBar: typeof import('naive-ui').useLoadingBar
|
||||
const useMessage: typeof import('naive-ui').useMessage
|
||||
const useNotification: typeof import('naive-ui').useNotification
|
||||
}
|
||||
40
app/components.d.ts
vendored
Normal file
40
app/components.d.ts
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
// biome-ignore lint: disable
|
||||
// oxlint-disable
|
||||
// ------
|
||||
// Generated by unplugin-vue-components
|
||||
// Read more: https://github.com/vuejs/core/pull/3399
|
||||
import { GlobalComponents } from 'vue'
|
||||
|
||||
export {}
|
||||
|
||||
/* prettier-ignore */
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
NAvatar: typeof import('naive-ui')['NAvatar']
|
||||
NButton: typeof import('naive-ui')['NButton']
|
||||
NCard: typeof import('naive-ui')['NCard']
|
||||
NDropdown: typeof import('naive-ui')['NDropdown']
|
||||
NIcon: typeof import('naive-ui')['NIcon']
|
||||
NMenu: typeof import('naive-ui')['NMenu']
|
||||
NPopover: typeof import('naive-ui')['NPopover']
|
||||
NTag: typeof import('naive-ui')['NTag']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
}
|
||||
}
|
||||
|
||||
// For TSX support
|
||||
declare global {
|
||||
const NAvatar: typeof import('naive-ui')['NAvatar']
|
||||
const NButton: typeof import('naive-ui')['NButton']
|
||||
const NCard: typeof import('naive-ui')['NCard']
|
||||
const NDropdown: typeof import('naive-ui')['NDropdown']
|
||||
const NIcon: typeof import('naive-ui')['NIcon']
|
||||
const NMenu: typeof import('naive-ui')['NMenu']
|
||||
const NPopover: typeof import('naive-ui')['NPopover']
|
||||
const NTag: typeof import('naive-ui')['NTag']
|
||||
const RouterLink: typeof import('vue-router')['RouterLink']
|
||||
const RouterView: typeof import('vue-router')['RouterView']
|
||||
}
|
||||
@@ -1,53 +1,163 @@
|
||||
<template>
|
||||
<n-layout class="h-screen">
|
||||
<n-layout-header class="app-bar-blur">
|
||||
<div class="flex justify-between items-center container mx-auto">
|
||||
<router-link to="/" class="text-lg font-bold"> Solsynth </router-link>
|
||||
<div class="flex gap-3">
|
||||
<router-link to="/terms" class="text-md font-bold">
|
||||
Legal
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</n-layout-header>
|
||||
<div class="flex flex-col min-h-screen">
|
||||
<header
|
||||
class="navbar bg-transparent shadow-lg fixed top-0 left-0 right-0 backdrop-blur-2xl z-1000 h-[64px]"
|
||||
>
|
||||
<div class="container mx-auto flex items-center justify-between px-5">
|
||||
<nuxt-link to="/">
|
||||
<nuxt-img src="/favicon.png" alt="Solsynth" class="w-8 h-8" />
|
||||
</nuxt-link>
|
||||
|
||||
<n-layout-content>
|
||||
<n-menu
|
||||
v-if="breakpoints.isGreaterOrEqual('md')"
|
||||
v-model:value="activeKey"
|
||||
mode="horizontal"
|
||||
:options="menuOptions"
|
||||
style="width: auto"
|
||||
/>
|
||||
<n-popover v-else trigger="hover">
|
||||
<template #trigger>
|
||||
<n-button text>
|
||||
<template #icon>
|
||||
<n-icon :component="MenuOutlined" />
|
||||
</template>
|
||||
</n-button>
|
||||
</template>
|
||||
<n-menu
|
||||
v-model:value="activeKey"
|
||||
mode="vertical"
|
||||
:options="menuOptions"
|
||||
class="w-64"
|
||||
style="height: auto"
|
||||
/>
|
||||
</n-popover>
|
||||
|
||||
<naive-color-mode-switch />
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="grow mt-[64px]">
|
||||
<slot />
|
||||
</n-layout-content>
|
||||
</n-layout>
|
||||
</main>
|
||||
|
||||
<footer
|
||||
class="footer sm:footer-horizontal bg-base-200 text-base-content p-10"
|
||||
>
|
||||
<aside>
|
||||
<nuxt-img src="/favicon.png" alt="Solsynth" class="w-12 h-12" />
|
||||
<div>
|
||||
<h3 class="text-lg font-bold">Solsynth</h3>
|
||||
Making software, hardware and experiences since 2024
|
||||
</div>
|
||||
</aside>
|
||||
<nav>
|
||||
<h6 class="footer-title">Products</h6>
|
||||
<a href="https://solian.app" target="_blank" class="link link-hover"
|
||||
>Solar Network</a
|
||||
>
|
||||
<nuxt-link to="/products" class="link link-hover">Catalog</nuxt-link>
|
||||
</nav>
|
||||
<nav>
|
||||
<h6 class="footer-title">Company</h6>
|
||||
<nuxt-link to="/about" class="link link-hover">About us</nuxt-link>
|
||||
<a
|
||||
href="https://github.com/Solsynth"
|
||||
target="_blank"
|
||||
class="link link-hover"
|
||||
>GitHub</a
|
||||
>
|
||||
</nav>
|
||||
<nav>
|
||||
<h6 class="footer-title">Legal</h6>
|
||||
<nuxt-link to="/terms/user-agreement" class="link link-hover"
|
||||
>Terms of Service</nuxt-link
|
||||
>
|
||||
<nuxt-link to="/terms/privacy-policy" class="link link-hover"
|
||||
>Privacy Policy</nuxt-link
|
||||
>
|
||||
<nuxt-link to="/terms/refund-policy" class="link link-hover"
|
||||
>Refund Policy</nuxt-link
|
||||
>
|
||||
<nuxt-link to="/terms" class="link link-hover">All Documents</nuxt-link>
|
||||
</nav>
|
||||
</footer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { NLayout, NLayoutHeader, NLayoutContent } from "naive-ui";
|
||||
<script lang="ts" setup>
|
||||
import type { MenuOption } from "naive-ui";
|
||||
import { NIcon, NAvatar, NMenu } from "naive-ui";
|
||||
import { computed, h } from "vue";
|
||||
import { useRoute, RouterLink } from "vue-router";
|
||||
import {
|
||||
ExploreOutlined,
|
||||
CategoryOutlined,
|
||||
MenuOutlined,
|
||||
} from "@vicons/material";
|
||||
import { breakpointsTailwind } from "@vueuse/core";
|
||||
|
||||
const route = useRoute();
|
||||
const breakpoints = useBreakpoints(breakpointsTailwind);
|
||||
|
||||
const { data: recentProducts } = await useAsyncData("recent-products", () =>
|
||||
queryCollection("products").order("updatedDate", "DESC").limit(5).all()
|
||||
);
|
||||
|
||||
const activeKey = computed(() => {
|
||||
// Map route paths to menu keys
|
||||
if (route.path === "/") return "explore";
|
||||
if (route.path.startsWith("/products")) return "products";
|
||||
return null;
|
||||
});
|
||||
|
||||
function renderIcon(icon: any) {
|
||||
return () => h(NIcon, null, { default: () => h(icon) });
|
||||
}
|
||||
|
||||
function renderLabel(label: string, route: string) {
|
||||
return () => h(RouterLink, { to: route }, { default: () => label });
|
||||
}
|
||||
|
||||
function renderExternalLabel(label: string, url: string) {
|
||||
return () =>
|
||||
h("a", { href: url, target: "_blank" }, { default: () => label });
|
||||
}
|
||||
|
||||
const menuOptions = computed<MenuOption[]>(() => {
|
||||
const productChildren =
|
||||
recentProducts.value?.map((product: any) => {
|
||||
const id = product.stem.split("/").pop();
|
||||
const hasPage = product.hasPage;
|
||||
const url = hasPage ? `/products/${id}` : product.url;
|
||||
|
||||
return {
|
||||
label: hasPage
|
||||
? renderLabel(product.name, url)
|
||||
: renderExternalLabel(product.name, url),
|
||||
key: `product-${id}`,
|
||||
icon: product.icon
|
||||
? () =>
|
||||
h(NAvatar, {
|
||||
src: product.icon,
|
||||
size: 24,
|
||||
style: { backgroundColor: "transparent" },
|
||||
})
|
||||
: renderIcon(CategoryOutlined), // Fallback icon, ideally use product.icon if possible but requires NAvatar
|
||||
};
|
||||
}) || [];
|
||||
|
||||
return [
|
||||
{
|
||||
label: renderLabel("Explore", "/"),
|
||||
key: "explore",
|
||||
icon: renderIcon(ExploreOutlined),
|
||||
},
|
||||
{
|
||||
label: renderLabel("Products", "/products"),
|
||||
key: "products",
|
||||
icon: renderIcon(CategoryOutlined),
|
||||
children: productChildren,
|
||||
},
|
||||
];
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.n-layout-header {
|
||||
padding: 8px 24px;
|
||||
border-color: var(--n-border-color);
|
||||
height: 57px; /* Fixed height */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.n-layout-content {
|
||||
height: calc(100vh - 57px); /* Adjust based on header height */
|
||||
}
|
||||
|
||||
.app-bar-blur {
|
||||
-webkit-mask-image: linear-gradient(
|
||||
to bottom,
|
||||
rgba(0, 0, 0, 1) 40%,
|
||||
rgba(0, 0, 0, 0.5) 65%,
|
||||
rgba(0, 0, 0, 0) 100%
|
||||
);
|
||||
mask-image: linear-gradient(
|
||||
to bottom,
|
||||
rgba(0, 0, 0, 1) 40%,
|
||||
rgba(0, 0, 0, 0.5) 65%,
|
||||
rgba(0, 0, 0, 0) 100%
|
||||
);
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
127
app/pages/about.vue
Normal file
127
app/pages/about.vue
Normal file
@@ -0,0 +1,127 @@
|
||||
<template>
|
||||
<main class="container mx-auto h-full px-8 flex flex-col gap-16 py-16">
|
||||
<!-- Hero Section -->
|
||||
<div
|
||||
class="text-center flex flex-col items-center justify-center animate-fade-in-up"
|
||||
>
|
||||
<h1 class="text-5xl font-extrabold mb-6">About Us</h1>
|
||||
<p class="text-xl max-w-2xl opacity-80">
|
||||
We are a collective of creators, dreamers, and builders.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Mission Section -->
|
||||
<section
|
||||
class="grid grid-cols-1 md:grid-cols-2 gap-12 items-center animate-fade-in-up delay-100"
|
||||
>
|
||||
<div>
|
||||
<h2 class="text-3xl font-bold mb-4">Our Mission</h2>
|
||||
<p class="text-lg opacity-90 leading-relaxed">
|
||||
Our aim is not making a profit.
|
||||
<i class="text-sm opacity-70">At least not yet.</i> <br /><br />
|
||||
Instead, we hope we can spread the love to the world and make everyone
|
||||
enjoy the fun of the Internet and technology. We believe in open
|
||||
source, collaboration, and building things that bring joy.
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex justify-center">
|
||||
<n-card class="max-w-sm w-full bg-opacity-50 backdrop-blur-sm">
|
||||
<div class="flex flex-col items-center text-center p-4">
|
||||
<n-icon size="48" class="mb-4 text-primary">
|
||||
<heart-outlined />
|
||||
</n-icon>
|
||||
<h3 class="text-xl font-bold mb-2">Built with Love</h3>
|
||||
<p class="opacity-80">
|
||||
Every line of code is written with passion and care.
|
||||
</p>
|
||||
</div>
|
||||
</n-card>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Team Section -->
|
||||
<section class="animate-fade-in-up delay-200">
|
||||
<h2 class="text-3xl font-bold mb-8 text-center">Meet the Team</h2>
|
||||
<div class="flex flex-wrap justify-center gap-8">
|
||||
<!-- Team Member Card -->
|
||||
<n-card
|
||||
class="max-w-xs w-full hover:shadow-lg transition-shadow duration-300"
|
||||
>
|
||||
<div class="flex flex-col items-center text-center">
|
||||
<n-avatar
|
||||
src="https://fs.solian.app/api/files/200ee92546244ed1a6a02202f5ca9cc9"
|
||||
:size="120"
|
||||
class="mb-4 shadow-md"
|
||||
/>
|
||||
<h3 class="text-xl font-bold">LittleSheep</h3>
|
||||
<div class="flex items-center gap-2 mt-1 mb-3">
|
||||
<n-tag size="small" type="primary" round>Founder</n-tag>
|
||||
<n-button
|
||||
text
|
||||
tag="a"
|
||||
size="small"
|
||||
href="https://id.solian.app/@littlesheep"
|
||||
target="_blank"
|
||||
>
|
||||
<n-icon size="18">
|
||||
<info-outlined />
|
||||
</n-icon>
|
||||
</n-button>
|
||||
</div>
|
||||
<p class="text-sm opacity-75 mb-4">
|
||||
Founder, CEO, CTO, Senior Developer, Marketing Engineer, Customer
|
||||
Service Engineer, DevOps, Database Administrator, Product Manager,
|
||||
UI/UX Designer, QA Engineer, Mobile Developer, Security Engineer,
|
||||
Technical Writer, Project Manager, Community Manager, Software
|
||||
Architect
|
||||
</p>
|
||||
<div class="flex gap-3">
|
||||
<n-button
|
||||
circle
|
||||
size="small"
|
||||
tag="a"
|
||||
href="https://github.com/LittleSheep"
|
||||
target="_blank"
|
||||
>
|
||||
<template #icon
|
||||
><n-icon><logo-github /></n-icon
|
||||
></template>
|
||||
</n-button>
|
||||
</div>
|
||||
</div>
|
||||
</n-card>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { InfoOutlined } from "@vicons/material";
|
||||
|
||||
useHead({
|
||||
title: "About Us - Solsynth",
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.animate-fade-in-up {
|
||||
animation: fadeInUp 0.8s ease-out forwards;
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
|
||||
.delay-100 {
|
||||
animation-delay: 0.1s;
|
||||
}
|
||||
|
||||
.delay-200 {
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,219 +1,260 @@
|
||||
<template>
|
||||
<main class="container mx-auto h-full px-8 flex flex-col gap-16">
|
||||
<div class="text-center py-56 flex flex-col items-center justify-center">
|
||||
<nuxt-img src="/favicon.png" class="w-28 h-28 mb-4" />
|
||||
<h1 class="text-5xl font-extrabold mb-3">We <span id="who-are-we" /></h1>
|
||||
<p class="text-xl mb-8">
|
||||
<main class="container mx-auto h-full px-8 flex flex-col gap-24 pb-24">
|
||||
<!-- Hero Section -->
|
||||
<div
|
||||
class="text-center min-h-[80vh] flex flex-col items-center justify-center relative"
|
||||
>
|
||||
<!-- Background decoration -->
|
||||
<div
|
||||
class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] h-[600px] bg-primary/20 rounded-full blur-[120px] -z-10 pointer-events-none"
|
||||
></div>
|
||||
|
||||
<nuxt-img src="/favicon.png" class="w-32 h-32 mb-8 animate-float" />
|
||||
<h1 class="text-6xl font-extrabold mb-6 tracking-tight">
|
||||
We <span ref="typedElement" class="text-primary" />
|
||||
</h1>
|
||||
<p class="text-2xl mb-10 opacity-80 max-w-2xl">
|
||||
We are a group of friends that make software, hardware and any stuff
|
||||
that interesting.
|
||||
that is interesting.
|
||||
</p>
|
||||
<n-space justify="center">
|
||||
<n-button type="primary" size="large" round tag="a" href="#products"
|
||||
>Explore around</n-button
|
||||
>
|
||||
<n-button type="default" size="large" round tag="a" href="#about"
|
||||
>About us</n-button
|
||||
<n-space justify="center" size="large">
|
||||
<n-button
|
||||
type="primary"
|
||||
size="large"
|
||||
round
|
||||
tag="a"
|
||||
href="#products"
|
||||
class="px-8 text-lg font-bold shadow-lg shadow-primary/30 hover:shadow-primary/50 transition-shadow"
|
||||
>
|
||||
Explore Products
|
||||
</n-button>
|
||||
<n-button size="large" round tag="a" href="/about" class="px-8 text-lg">
|
||||
About Us
|
||||
</n-button>
|
||||
</n-space>
|
||||
|
||||
<div class="absolute bottom-10 animate-bounce">
|
||||
<n-icon
|
||||
size="32"
|
||||
class="opacity-50"
|
||||
:component="ArrowDownwardOutlined"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div id="products" class="pb-56">
|
||||
<client-only>
|
||||
<n-grid cols="1 m:2 l:2" responsive="screen" x-gap="32" y-gap="16">
|
||||
<n-gi>
|
||||
<div class="flex items-center justify-center">
|
||||
<n-carousel
|
||||
show-arrow
|
||||
autoplay
|
||||
dot-type="line"
|
||||
class="rounded-xl w-full max-h-[360px] aspect-video flex-shrink-1"
|
||||
|
||||
<!-- Products Section -->
|
||||
<div id="products" class="scroll-mt-24">
|
||||
<div class="text-center mb-16">
|
||||
<h2 class="text-4xl font-bold mb-4">Our Creations</h2>
|
||||
<p class="text-xl opacity-70 max-w-2xl mx-auto">
|
||||
From social networks to cloud drives, we build tools that empower and
|
||||
connect.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
<n-card
|
||||
v-for="product in products"
|
||||
:key="product.path"
|
||||
class="product-card"
|
||||
content-style="padding: 0"
|
||||
>
|
||||
<div class="relative aspect-video overflow-hidden group">
|
||||
<img
|
||||
:src="product.background"
|
||||
class="w-full h-full object-cover transition-transform duration-700 group-hover:scale-110"
|
||||
/>
|
||||
<div
|
||||
class="absolute inset-0 bg-linear-to-t from-black/80 via-black/20 to-transparent opacity-90"
|
||||
></div>
|
||||
|
||||
<div
|
||||
class="absolute top-4 right-4 flex gap-2 opacity-0 group-hover:opacity-100 transition-opacity duration-300"
|
||||
>
|
||||
<n-button
|
||||
v-if="product.repo"
|
||||
circle
|
||||
color="white"
|
||||
size="small"
|
||||
tag="a"
|
||||
:href="product.repo"
|
||||
target="_blank"
|
||||
class="text-black"
|
||||
>
|
||||
<n-carousel-item
|
||||
v-for="product in products"
|
||||
:key="product.path"
|
||||
class="rounded-xl w-full max-h-[360px] aspect-video relative"
|
||||
:style="`background-color: ${product.background ? 'transparent' : themeVar.baseColor}`"
|
||||
>
|
||||
<img
|
||||
:src="product.background"
|
||||
class="absolute left-0 right-0 top-0 bottom-0 object-cover aspect-video"
|
||||
style="z-index: -1"
|
||||
/>
|
||||
<div
|
||||
style="
|
||||
background: linear-gradient(
|
||||
to top,
|
||||
rgba(0, 0, 0, 0.7),
|
||||
transparent
|
||||
);
|
||||
z-index: 1;
|
||||
"
|
||||
class="absolute left-0 right-0 top-1/2 bottom-0"
|
||||
/>
|
||||
<div
|
||||
class="absolute left-0 right-0 top-0 px-4 pt-4 flex justify-end gap-2.5"
|
||||
>
|
||||
<n-button
|
||||
v-if="product.repo"
|
||||
circle
|
||||
color="white"
|
||||
size="small"
|
||||
tag="a"
|
||||
:href="product.repo"
|
||||
target="_blank"
|
||||
>
|
||||
<n-icon color="black"><code-round /></n-icon>
|
||||
</n-button>
|
||||
<n-button
|
||||
v-if="product.url"
|
||||
circle
|
||||
color="white"
|
||||
size="small"
|
||||
tag="a"
|
||||
:href="product.url"
|
||||
target="_blank"
|
||||
>
|
||||
<n-icon color="black"><launch-round /></n-icon>
|
||||
</n-button>
|
||||
</div>
|
||||
<div
|
||||
class="absolute bottom-0 px-6 py-8 w-full"
|
||||
style="z-index: 2"
|
||||
>
|
||||
<nuxt-img :src="product.icon" class="w-12 h-12" />
|
||||
<p class="text-lg text-white line-height-1">
|
||||
{{ product.name }}
|
||||
</p>
|
||||
<p class="text-white line-height-1">
|
||||
{{ product.description }}
|
||||
</p>
|
||||
</div>
|
||||
</n-carousel-item>
|
||||
</n-carousel>
|
||||
<n-icon><code-round /></n-icon>
|
||||
</n-button>
|
||||
<n-button
|
||||
v-if="product.url"
|
||||
circle
|
||||
color="white"
|
||||
size="small"
|
||||
tag="a"
|
||||
:href="product.url"
|
||||
target="_blank"
|
||||
class="text-black"
|
||||
>
|
||||
<n-icon><launch-round /></n-icon>
|
||||
</n-button>
|
||||
</div>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<div
|
||||
class="flex justify-center text-right h-full py-8 px-4 flex-col"
|
||||
>
|
||||
<h2 class="text-3xl font-bold mb-3">Our products</h2>
|
||||
<p class="text-lg mb-1">
|
||||
The made various of software, from social network to cloud
|
||||
drive.
|
||||
</p>
|
||||
<p class="text-lg">
|
||||
Take a look of them on the left on your own
|
||||
<code>ヽ(>∀<☆)ノ</code>
|
||||
</p>
|
||||
</div>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
</client-only>
|
||||
</div>
|
||||
<div id="about" class="pb-56">
|
||||
<client-only>
|
||||
<n-grid cols="1 m:2 l:2" responsive="screen" x-gap="32" y-gap="16">
|
||||
<n-gi>
|
||||
<div
|
||||
class="flex justify-center text-left h-full py-8 px-4 flex flex-col"
|
||||
>
|
||||
<h2 class="text-3xl font-bold mb-3">About us</h2>
|
||||
<p class="text-lg mb-1">
|
||||
Our aim is not making a profit.
|
||||
<i class="text-xs">At least not yet.</i>
|
||||
</p>
|
||||
<p class="text-lg">
|
||||
Instead we hope we can spread the love to the world and make
|
||||
everyone enjoy the fun of the Internet and the world.
|
||||
</p>
|
||||
</div>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<div class="flex h-full justify-center flex-col text-right">
|
||||
<h2 class="text-3xl font-bold mb-3">Team members</h2>
|
||||
<p class="text-lg">
|
||||
Say hi to our lovely members... uh, seems there is only me.
|
||||
</p>
|
||||
<div class="flex justify-end gap-4 my-4">
|
||||
<div class="flex flex-col items-end text-right">
|
||||
<n-avatar
|
||||
src="https://fs.solian.app/api/files/200ee92546244ed1a6a02202f5ca9cc9"
|
||||
:size="100"
|
||||
class="mb-2"
|
||||
/>
|
||||
<div class="flex gap-1">
|
||||
<p>LittleSheep</p>
|
||||
<n-button
|
||||
text
|
||||
tag="a"
|
||||
size="small"
|
||||
href="https://id.solian.app/@littlesheep"
|
||||
target="_blank"
|
||||
class="mt-0.5"
|
||||
>
|
||||
<n-icon>
|
||||
<info-outlined />
|
||||
</n-icon>
|
||||
</n-button>
|
||||
</div>
|
||||
<p class="text-xs opacity-75 max-w-sm">
|
||||
Founder, CEO, CTO, Senior Developer, Marketing Engineer,
|
||||
Customer Service Engineer, DevOps, Database Administrator,
|
||||
Product Manager, UI/UX Designer, QA Engineer, Mobile
|
||||
Developer, Security Engineer, Technical Writer, Project
|
||||
Manager, Community Manager, Software Architect
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="absolute bottom-0 left-0 right-0 p-6">
|
||||
<div class="flex items-center gap-3 mb-2">
|
||||
<nuxt-img
|
||||
:src="product.icon"
|
||||
class="w-10 h-10 rounded-lg shadow-sm"
|
||||
/>
|
||||
<h3 class="text-xl font-bold text-white">
|
||||
{{ product.name }}
|
||||
</h3>
|
||||
</div>
|
||||
<p class="text-gray-200 text-sm line-clamp-2">
|
||||
{{ product.description }}
|
||||
</p>
|
||||
</div>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
</client-only>
|
||||
</div>
|
||||
</n-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- About Teaser Section -->
|
||||
<div class="py-16">
|
||||
<n-card
|
||||
class="bg-linear-to-r from-primary/10 to-secondary/10 border-0 overflow-hidden relative"
|
||||
>
|
||||
<div
|
||||
class="absolute top-0 right-0 w-64 h-64 bg-primary/20 rounded-full blur-[80px] -translate-y-1/2 translate-x-1/2"
|
||||
></div>
|
||||
<div
|
||||
class="flex flex-col md:flex-row items-center gap-12 relative z-10 p-8"
|
||||
>
|
||||
<div class="flex-1">
|
||||
<h2 class="text-3xl font-bold mb-4">More Than Just Code</h2>
|
||||
<p class="text-lg opacity-80 mb-6 leading-relaxed">
|
||||
We are a community-driven team focused on creating meaningful
|
||||
experiences. Our mission goes beyond software—it's about
|
||||
connection, innovation, and fun.
|
||||
</p>
|
||||
<n-button type="primary" ghost size="large" tag="a" href="/about">
|
||||
Read Our Story
|
||||
<template #icon>
|
||||
<n-icon :component="ChevronRightOutlined"></n-icon>
|
||||
</template>
|
||||
</n-button>
|
||||
</div>
|
||||
<div class="flex-1 flex justify-center">
|
||||
<!-- Abstract representation or team collage could go here -->
|
||||
<div class="grid grid-cols-2 gap-4 opacity-80">
|
||||
<div
|
||||
class="w-32 h-32 rounded-2xl bg-primary/20 animate-pulse"
|
||||
></div>
|
||||
<div
|
||||
class="w-32 h-32 rounded-2xl bg-secondary/20 animate-pulse delay-75"
|
||||
></div>
|
||||
<div
|
||||
class="w-32 h-32 rounded-2xl bg-info/20 animate-pulse delay-150"
|
||||
></div>
|
||||
<div
|
||||
class="w-32 h-32 rounded-2xl bg-success/20 animate-pulse delay-300"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</n-card>
|
||||
</div>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { NSpace, NButton, NIcon, NCard } from "naive-ui";
|
||||
import {
|
||||
NSpace,
|
||||
NButton,
|
||||
NGrid,
|
||||
NGi,
|
||||
NCarousel,
|
||||
NCarouselItem,
|
||||
NIcon,
|
||||
NAvatar,
|
||||
useThemeVars,
|
||||
} from "naive-ui";
|
||||
import { LaunchRound, CodeRound, InfoOutlined } from "@vicons/material";
|
||||
LaunchRound,
|
||||
CodeRound,
|
||||
ChevronRightOutlined,
|
||||
ArrowDownwardOutlined,
|
||||
} from "@vicons/material";
|
||||
import Typed from "typed.js";
|
||||
|
||||
const route = useRoute();
|
||||
const themeVar = useThemeVars();
|
||||
const typedElement = ref(null);
|
||||
const typed = shallowRef(null);
|
||||
|
||||
useHead({
|
||||
title: "Solsynth - Creating Experiences",
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
if (typedElement.value) {
|
||||
if (typed.value) {
|
||||
typed.value.destroy();
|
||||
}
|
||||
typed.value = new Typed(typedElement.value, {
|
||||
strings: [
|
||||
"make software",
|
||||
"make hardware",
|
||||
"craft experiences",
|
||||
"write stories",
|
||||
"are Solsynth",
|
||||
],
|
||||
typeSpeed: 50,
|
||||
backDelay: 1500,
|
||||
backSpeed: 30,
|
||||
smartBackspace: true,
|
||||
loop: true,
|
||||
showCursor: true,
|
||||
cursorChar: "|",
|
||||
autoInsertCss: true,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (typed.value) {
|
||||
typed.value.destroy();
|
||||
typed.value = null;
|
||||
}
|
||||
});
|
||||
|
||||
const { data: products } = await useAsyncData(route.path, () => {
|
||||
return queryCollection("products").all();
|
||||
});
|
||||
|
||||
useHead({
|
||||
title: "Solsynth",
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
new Typed("#who-are-we", {
|
||||
strings: [
|
||||
"make software",
|
||||
"make hardware",
|
||||
"make experience",
|
||||
"write stories",
|
||||
"are Solsynth^3000",
|
||||
],
|
||||
typeSpeed: 40,
|
||||
backDelay: 1000,
|
||||
backSpeed: 40,
|
||||
smartBackspace: true,
|
||||
loop: true,
|
||||
showCursor: false,
|
||||
autoInsertCss: false,
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.animate-float {
|
||||
animation: float 6s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes float {
|
||||
0% {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-20px);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
}
|
||||
|
||||
.product-card {
|
||||
height: 100%;
|
||||
transform: translateY(0);
|
||||
transition: all 0.3s ease-in-out;
|
||||
overflow: hidden;
|
||||
border: none;
|
||||
background-color: rgba(
|
||||
255,
|
||||
255,
|
||||
255,
|
||||
0.5
|
||||
); /* Example, adjust base color as needed */
|
||||
backdrop-filter: blur(4px); /* For backdrop-blur-sm */
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-0.5rem); /* For -translate-y-2 */
|
||||
box-shadow:
|
||||
0 20px 25px -5px rgba(0, 0, 0, 0.1),
|
||||
0 10px 10px -5px rgba(0, 0, 0, 0.04); /* For shadow-xl */
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
54
app/pages/products/index.vue
Normal file
54
app/pages/products/index.vue
Normal file
@@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<div class="container max-w-xl mx-auto my-16 px-8">
|
||||
<h1 class="text-4xl font-bold mb-8">Our Products</h1>
|
||||
|
||||
<nuxt-link
|
||||
v-for="product in products"
|
||||
:key="product.url"
|
||||
:to="product.url"
|
||||
class="no-underline block mb-4"
|
||||
>
|
||||
<n-card hoverable>
|
||||
<template #cover>
|
||||
<div class="h-48 overflow-hidden relative">
|
||||
<img :src="product.background" class="w-full h-full object-cover" />
|
||||
<div
|
||||
class="absolute bottom-0 left-0 p-4 bg-linear-to-t from-black/80 to-transparent w-full flex items-center gap-3"
|
||||
>
|
||||
<img
|
||||
:src="product.icon"
|
||||
class="aspect-square h-10 rounded-full bg-white/10 p-1"
|
||||
style="width: auto"
|
||||
/>
|
||||
<span class="text-white font-bold text-lg grow">{{
|
||||
product.name
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<p class="line-clamp-3 pt-4">{{ product.description }}</p>
|
||||
<template #footer>
|
||||
<div class="flex justify-between items-center text-xs opacity-75">
|
||||
<span>v{{ product.version }}</span>
|
||||
<span>
|
||||
Released:
|
||||
{{ new Date(product.releasedDate ?? "").toLocaleDateString() }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</n-card>
|
||||
</nuxt-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { NCard } from "naive-ui";
|
||||
|
||||
const { data: products } = await useAsyncData("products", () =>
|
||||
queryCollection("products").all()
|
||||
);
|
||||
|
||||
useHead({
|
||||
title: "Products",
|
||||
});
|
||||
</script>
|
||||
@@ -1,3 +0,0 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@@ -15,6 +15,7 @@ export default defineContentConfig({
|
||||
releasedDate: z.date().optional(),
|
||||
version: z.string().optional(),
|
||||
updatedDate: z.date().optional(),
|
||||
hasPage: z.boolean().optional(),
|
||||
}),
|
||||
}),
|
||||
terms: defineCollection({
|
||||
|
||||
@@ -7,5 +7,6 @@
|
||||
"repo": "https://github.com/littlesheep2code/groovy-box",
|
||||
"releasedDate": "2025-08-14T08:00:00.000Z",
|
||||
"version": "1.0.0.0",
|
||||
"updatedDate": "2025-08-14T08:00:00.000Z"
|
||||
"updatedDate": "2025-08-14T08:00:00.000Z",
|
||||
"hasPage": true
|
||||
}
|
||||
|
||||
@@ -7,5 +7,6 @@
|
||||
"repo": "https://github.com/Solsynth/Solian",
|
||||
"releasedDate": "2024-01-27T08:00:00.000Z",
|
||||
"version": "3.1.0",
|
||||
"updatedDate": "2025-07-28T08:00:00.000Z"
|
||||
"updatedDate": "2025-07-28T08:00:00.000Z",
|
||||
"hasPage": true
|
||||
}
|
||||
|
||||
100
nuxt.config.ts
100
nuxt.config.ts
@@ -1,52 +1,86 @@
|
||||
import tailwindcss from "@tailwindcss/vite";
|
||||
import AutoImport from "unplugin-auto-import/vite";
|
||||
import Components from "unplugin-vue-components/vite";
|
||||
import { NaiveUiResolver } from "unplugin-vue-components/resolvers";
|
||||
import { generateTailwindColorThemes } from "@bg-dev/nuxt-naiveui/utils";
|
||||
|
||||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||
export default defineNuxtConfig({
|
||||
compatibilityDate: "2025-07-15",
|
||||
devtools: { enabled: true },
|
||||
ssr: false,
|
||||
css: ["~/assets/css/main.css"],
|
||||
app: {
|
||||
pageTransition: { name: "page", mode: "out-in" },
|
||||
head: {
|
||||
title: "Solsynth",
|
||||
titleTemplate: "%s - Solsynth",
|
||||
link: [{ rel: "icon", type: "image/png", href: "/favicon.png" }],
|
||||
},
|
||||
},
|
||||
scripts: {
|
||||
globals: {
|
||||
umami: {
|
||||
src: "https://cloud.umami.is/script.js",
|
||||
"data-website-id": "eef151fb-07e2-461b-8b7f-2547aab735d4",
|
||||
defer: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
nitro: {
|
||||
preset: "cloudflare_module",
|
||||
cloudflare: {
|
||||
deployConfig: true,
|
||||
wrangler: {
|
||||
d1_databases: [
|
||||
{
|
||||
binding: "DB",
|
||||
database_name: "capital-content",
|
||||
database_id: "73d65123-3c42-4dc9-b540-8e89678962a2",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
content: {
|
||||
database: {
|
||||
type: "d1",
|
||||
bindingName: "DB",
|
||||
},
|
||||
},
|
||||
nitro: {},
|
||||
modules: [
|
||||
"@nuxt/content",
|
||||
"@nuxt/eslint",
|
||||
"@nuxt/image",
|
||||
"@nuxt/scripts",
|
||||
"@nuxtjs/tailwindcss",
|
||||
"nuxtjs-naive-ui",
|
||||
"@vueuse/nuxt",
|
||||
"@eschricht/nuxt-color-mode",
|
||||
"@bg-dev/nuxt-naiveui",
|
||||
],
|
||||
vite: {
|
||||
plugins: [
|
||||
tailwindcss(),
|
||||
AutoImport({
|
||||
imports: [
|
||||
{
|
||||
"naive-ui": [
|
||||
"useDialog",
|
||||
"useMessage",
|
||||
"useNotification",
|
||||
"useLoadingBar",
|
||||
],
|
||||
},
|
||||
],
|
||||
}),
|
||||
Components({
|
||||
resolvers: [NaiveUiResolver()],
|
||||
}),
|
||||
],
|
||||
},
|
||||
naiveui: {
|
||||
colorModePreference: "system",
|
||||
colorModePreferenceCookieName: "fi-ColorMode",
|
||||
themeConfig: {
|
||||
...generateTailwindColorThemes(),
|
||||
shared: {
|
||||
common: {
|
||||
fontFamily:
|
||||
"Nunito Variable, v-sans, ui-system, -apple-system, sans-serif",
|
||||
primaryColor: "#3F51B5FF",
|
||||
primaryColorHover: "#5767C1FF",
|
||||
primaryColorPressed: "#3546A4FF",
|
||||
primaryColorSuppl: "#4C5EC5FF",
|
||||
borderRadius: "16px",
|
||||
borderRadiusSmall: "8px",
|
||||
},
|
||||
Input: {
|
||||
borderRadius: "8px",
|
||||
},
|
||||
Select: {
|
||||
borderRadius: "8px",
|
||||
},
|
||||
Dropdown: {
|
||||
borderRadius: "8px",
|
||||
},
|
||||
Button: {
|
||||
borderRadius: "8px",
|
||||
borderRadiusLarge: "12px",
|
||||
borderRadiusMedium: "8px",
|
||||
borderRadiusSmall: "4px",
|
||||
},
|
||||
},
|
||||
light: {},
|
||||
dark: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
31
package.json
31
package.json
@@ -10,28 +10,31 @@
|
||||
"postinstall": "nuxt prepare"
|
||||
},
|
||||
"dependencies": {
|
||||
"@eschricht/nuxt-color-mode": "1.2.0",
|
||||
"@fontsource-variable/nunito": "^5.2.6",
|
||||
"@bg-dev/nuxt-naiveui": "^2.0.0",
|
||||
"@fontsource-variable/nunito": "^5.2.7",
|
||||
"@nuxt/content": "3.6.3",
|
||||
"@nuxt/eslint": "1.7.1",
|
||||
"@nuxt/image": "1.10.0",
|
||||
"@nuxt/scripts": "0.11.10",
|
||||
"@nuxtjs/tailwindcss": "6.14.0",
|
||||
"@octokit/rest": "^22.0.0",
|
||||
"@unhead/vue": "^2.0.3",
|
||||
"@vueuse/core": "^13.6.0",
|
||||
"@octokit/rest": "^22.0.1",
|
||||
"@unhead/vue": "^2.0.19",
|
||||
"@vueuse/core": "^13.9.0",
|
||||
"@vueuse/nuxt": "13.6.0",
|
||||
"better-sqlite3": "^12.2.0",
|
||||
"eslint": "^9.0.0",
|
||||
"nuxt": "^4.0.1",
|
||||
"better-sqlite3": "^12.5.0",
|
||||
"eslint": "^9.39.1",
|
||||
"nuxt": "^4.2.1",
|
||||
"nuxtjs-naive-ui": "1.0.2",
|
||||
"typed.js": "^2.1.0",
|
||||
"vue": "^3.5.18",
|
||||
"vue-router": "^4.5.1",
|
||||
"wrangler": "^4.26.1"
|
||||
"vue": "^3.5.25",
|
||||
"vue-router": "^4.6.3",
|
||||
"wrangler": "^4.51.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"@vicons/material": "^0.13.0"
|
||||
"@tailwindcss/typography": "^0.5.19",
|
||||
"@vicons/material": "^0.13.0",
|
||||
"daisyui": "^5.5.5",
|
||||
"naive-ui": "^2.43.2",
|
||||
"unplugin-auto-import": "^20.3.0",
|
||||
"unplugin-vue-components": "^30.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user