diff --git a/.github/workflows/opencode-review.yml b/.github/workflows/opencode-review.yml index d8913c4..b5cbdba 100644 --- a/.github/workflows/opencode-review.yml +++ b/.github/workflows/opencode-review.yml @@ -26,4 +26,7 @@ jobs: - Check for code quality issues - Look for potential bugs - Suggest improvements + - Praise good practices + - Chastise especially bad practices, in a teasing manner + - At the end, add a collapsible section with a copiable prompt (code block) to be given to an AI coding agent to fix the issues found. Write this in a normal tone. - ${{ secrets.CUSTOM_REVIEW_INSTRUCTIONS || '' }} \ No newline at end of file diff --git a/bun.lock b/bun.lock index 76d64de..5b4d976 100644 --- a/bun.lock +++ b/bun.lock @@ -1,5 +1,6 @@ { "lockfileVersion": 1, + "configVersion": 0, "workspaces": { "": { "name": "mikn-dev", @@ -7,9 +8,10 @@ "@c15t/nextjs": "^1.7.1", "@c15t/scripts": "^1.0.0", "@gsap/react": "^2.1.2", + "@icons-pack/react-simple-icons": "^13.8.0", "@pixiv/three-vrm": "^3.3.4", "@pixiv/three-vrm-animation": "^3.3.4", - "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-slot": "^1.2.4", "@react-three/drei": "^10.7.6", "@react-three/fiber": "^9.4.0", "@swetrix/nextjs": "^1.0.1", @@ -187,6 +189,8 @@ "@hono/node-server": ["@hono/node-server@1.19.7", "", { "peerDependencies": { "hono": "^4" } }, "sha512-vUcD0uauS7EU2caukW8z5lJKtoGMokxNbJtBiwHgpqxEXokaHCBkQUmCHhjFB1VUTWdqj25QoMkMKzgjq+uhrw=="], + "@icons-pack/react-simple-icons": ["@icons-pack/react-simple-icons@13.8.0", "", { "peerDependencies": { "react": "^16.13 || ^17 || ^18 || ^19" } }, "sha512-iZrhL1fSklfCCVn68IYHaAoKfcby3RakUTn2tRPyHBkhr2tkYqeQbjJWf+NizIYBzKBn2IarDJXmTdXd6CuEfw=="], + "@img/colour": ["@img/colour@1.0.0", "", {}, "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw=="], "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.0.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ=="], @@ -529,7 +533,7 @@ "@radix-ui/react-slider": ["@radix-ui/react-slider@1.3.6", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw=="], - "@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], + "@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.4", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA=="], "@radix-ui/react-switch": ["@radix-ui/react-switch@1.2.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ=="], @@ -1761,6 +1765,22 @@ "@pixiv/types-vrmc-vrm-animation-1.0/@pixiv/types-vrmc-vrm-1.0": ["@pixiv/types-vrmc-vrm-1.0@2.0.3", "", {}, "sha512-RMP34Bk1qLFQv/CRB1Zqvn2qMFfWQfP2Hms5QrrfoBsW9XroZdEe0zPLNbGmUPYh4F7VtBb+B7+RCuymRtpehA=="], + "@radix-ui/react-alert-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], + + "@radix-ui/react-collection/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], + + "@radix-ui/react-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], + + "@radix-ui/react-menu/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], + + "@radix-ui/react-popover/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], + + "@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], + + "@radix-ui/react-select/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], + + "@radix-ui/react-tooltip/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], + "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.6.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-zq/ay+9fNIJJtJiZxdTnXS20PllcYMX3OE23ESc4HK/bdYu3cOWYVhsOhVnXALfU/uqJIxn5NBPd9z4v+SfoSg=="], "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.6.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA=="], @@ -1807,6 +1827,8 @@ "prompts/kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="], + "radix-ui/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], + "react-dom/scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], "restore-cursor/onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="], diff --git a/package.json b/package.json index 8387b95..6e3fdd3 100644 --- a/package.json +++ b/package.json @@ -13,9 +13,10 @@ "@c15t/nextjs": "^1.7.1", "@c15t/scripts": "^1.0.0", "@gsap/react": "^2.1.2", + "@icons-pack/react-simple-icons": "^13.8.0", "@pixiv/three-vrm": "^3.3.4", "@pixiv/three-vrm-animation": "^3.3.4", - "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-slot": "^1.2.4", "@react-three/drei": "^10.7.6", "@react-three/fiber": "^9.4.0", "@swetrix/nextjs": "^1.0.1", diff --git a/src/app/[locale]/(homepage)/page.tsx b/src/app/[locale]/(homepage)/page.tsx index 4a7f56a..2c891da 100644 --- a/src/app/[locale]/(homepage)/page.tsx +++ b/src/app/[locale]/(homepage)/page.tsx @@ -23,6 +23,7 @@ import KaraSnapIcon from "@/assets/img/karasnap.png"; export default function IndexPage() { const t = useTranslations("home"); + const tSolutions = useTranslations("solutions"); const [showCircularText, setShowCircularText] = useState(false); return ( @@ -102,18 +103,20 @@ export default function IndexPage() {
diff --git a/src/app/[locale]/(pages)/contact/page.tsx b/src/app/[locale]/(pages)/contact/page.tsx index 1819ea8..b7b3c18 100644 --- a/src/app/[locale]/(pages)/contact/page.tsx +++ b/src/app/[locale]/(pages)/contact/page.tsx @@ -1,4 +1,3 @@ -import Link from "next/link"; import { useTranslations } from "next-intl"; import { Mail, @@ -9,80 +8,70 @@ import { Gamepad2, } from "lucide-react"; -import { Card, CardContent } from "@/components/ui/card"; -import { Button } from "@/components/animate-ui/components/buttons/button"; +import { ContactCard } from "@/components/ContactCard"; export default function ContactPage() { const t = useTranslations("contact"); + const contactCards = [ + { + icon: Mail, + title: t("mail"), + contactItems: [ + { + icon: Headset, + text: "hello@mikn.dev", + title: t("general-support"), + href: "mailto:hello@mikn.dev", + }, + { + icon: CreditCard, + text: "billing@mikn.dev", + title: t("billing-support"), + href: "mailto:billing@mikn.dev", + }, + { + icon: AlertTriangle, + text: "abuse@mikn.dev", + title: t("abuse-reports"), + href: "mailto:abuse@mikn.dev", + }, + ], + }, + { + icon: Phone, + title: t("phone"), + description: t("phone-disclaimer"), + contactItems: [ + { + icon: Phone, + text: "+81 090-9276-3628", + }, + ], + }, + { + icon: Gamepad2, + title: t("discord"), + contactItems: [], + actionButton: { + href: "https://discord.gg/2892hjFQn8", + label: t("join"), + }, + }, + ]; + return ( -
-
-

+
+
+

{t("title")}

- - -
- -

{t("mail")}

-
-
-
- -

hello@mikn.dev

-
-
- -

billing@mikn.dev

-
-
- -

abuse@mikn.dev

-
-
-
-
- - - -
- -

{t("phone")}

-
-
-

+81 090-9276-3628

-
-
-
- - - -
- -

{t("discord")}

-
-
- - - -
-
-
- -

{t("phone-disclaimer")}

+
+ {contactCards.map((card, index) => ( + + ))} +
); diff --git a/src/app/[locale]/(pages)/solutions/page.tsx b/src/app/[locale]/(pages)/solutions/page.tsx new file mode 100644 index 0000000..66e3d2b --- /dev/null +++ b/src/app/[locale]/(pages)/solutions/page.tsx @@ -0,0 +1,121 @@ +import { useTranslations } from "next-intl"; +import DecryptedText from "@/components/DecryptedText"; +import { OSSProductCard } from "@/components/OSSProductCard"; +import KaraSnapIcon from "@/assets/img/karasnap.png"; +import MikanBotIcon from "@/assets/img/mikanbot.png"; +import { IdCard, Rss, MessageSquare, Image, Gamepad } from "lucide-react"; +import { SiDiscord } from "@icons-pack/react-simple-icons"; + +export default function SolutionsPage() { + const t = useTranslations("solutions"); + + const sections = [ + { + key: "main", + products: [ + { + key: "karaSnap", + icon: KaraSnapIcon.src, + repoUrl: "https://github.com/mikndotdev/karasnap", + websiteUrl: "https://karasnap.mikn.dev", + tagKeys: ["fun", "ai"], + }, + { + key: "nextDiscordAuth", + icon: IdCard, + repoUrl: "https://github.com/mikndotdev/next-discord-auth", + websiteUrl: "https://npm.im/@mikandev/next-discord-auth", + tagKeys: ["dev", "lib"], + }, + { + key: "rssfetch", + icon: Rss, + repoUrl: "https://github.com/mikndotdev/rssfetch", + websiteUrl: "https://rssfetch.vercel.app", + tagKeys: ["dev", "api"], + }, + { + key: "mikanbot", + icon: MikanBotIcon.src, + repoUrl: "https://github.com/mikndotdev/mikanbot-project", + websiteUrl: "/solutions/mikanbot", + tagKeys: ["fun", "bot"], + }, + { + key: "customrp", + icon: SiDiscord, + repoUrl: "https://github.com/mikndotdev/customrp", + websiteUrl: "https://customrp.mikn.dev", + tagKeys: ["fun"], + }, + { + key: "enkabadges", + icon: Gamepad, + repoUrl: "https://github.com/mikndotdev/enkabadges", + websiteUrl: "https://enkabadges.mikn.dev", + tagKeys: ["fun"], + }, + ], + }, + { + key: "legacy", + products: [ + { + key: "chat", + icon: MessageSquare, + repoUrl: "https://github.com/mikndotdev/chat", + tagKeys: ["ai"], + }, + { + key: "sukushocloud", + icon: Image, + repoUrl: "https://github.com/mikndotdev/sukushocloud-web", + tagKeys: ["api", "fun"], + }, + ], + }, + ]; + + return ( +
+
+ {sections.map((section, sectionIndex) => ( +
+
+ +
+

+ {t(`${section.key}.description`)} +

+
+ {section.products.map((product, productIndex) => ( + t(`tags.${tagKey}`))} + /> + ))} +
+
+ ))} +
+
+ ); +} diff --git a/src/assets/img/MiknCursor.png b/src/assets/img/MiknCursor.png new file mode 100644 index 0000000..bf797a8 Binary files /dev/null and b/src/assets/img/MiknCursor.png differ diff --git a/src/assets/img/mikanbot.png b/src/assets/img/mikanbot.png new file mode 100644 index 0000000..84e519f Binary files /dev/null and b/src/assets/img/mikanbot.png differ diff --git a/src/components/ContactCard.tsx b/src/components/ContactCard.tsx new file mode 100644 index 0000000..42683d5 --- /dev/null +++ b/src/components/ContactCard.tsx @@ -0,0 +1,85 @@ +import { LucideIcon } from "lucide-react"; +import { + Card, + CardContent, + CardHeader, + CardTitle, + CardFooter, +} from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import Link from "next/link"; + +export interface IContactCardProps { + icon: LucideIcon; + title: string; + description?: string; + contactItems: IContactItem[]; + actionButton?: { + href: string; + label: string; + }; +} + +export interface IContactItem { + icon: LucideIcon; + text: string; + title?: string; + href?: string; +} + +export function ContactCard({ + icon: Icon, + title, + description, + contactItems, + actionButton, +}: IContactCardProps) { + return ( + + +
+ +
+
+ + + {title} + + {description && ( +

+ {description} +

+ )} +
+ {contactItems.map((item, index) => ( +
+ + {item.href ? ( + + {item.text} + + ) : ( + {item.text} + )} +
+ ))} +
+
+ {actionButton && ( + + + + + + )} +
+ ); +} diff --git a/src/components/CustomCursor.tsx b/src/components/CustomCursor.tsx index c70ef6d..c6226b2 100644 --- a/src/components/CustomCursor.tsx +++ b/src/components/CustomCursor.tsx @@ -1,6 +1,6 @@ "use client"; import { useEffect, useRef } from "react"; -import Mikan from "@/assets/img/mikan.png"; +import MikanCursor from "@/assets/img/MiknCursor.png"; import Image from "next/image"; export default function CustomCursor() { @@ -49,9 +49,9 @@ export default function CustomCursor() { }} > Custom Cursor {description}

+ {tags && ( +
+ {tags.map((tag) => ( + + {tag} + + ))} +
+ )} @@ -62,7 +76,7 @@ export function OSSProductCard({ variant="ghost" className="w-full justify-start gap-2 h-auto py-2 hover:bg-primary/10 hover:text-primary" > - + {t("viewRepo")} diff --git a/src/components/SettingsController.tsx b/src/components/SettingsController.tsx index 501dc67..d4ad833 100644 --- a/src/components/SettingsController.tsx +++ b/src/components/SettingsController.tsx @@ -80,7 +80,7 @@ export default function SettingsController({ children }: AccButtonProps) { disabled={selectedToy === "custom"} onClick={() => setSelectedToy("custom")} > - Custom Cursor + mamomamo

diff --git a/src/components/ui/badge.tsx b/src/components/ui/badge.tsx new file mode 100644 index 0000000..f795980 --- /dev/null +++ b/src/components/ui/badge.tsx @@ -0,0 +1,36 @@ +import * as React from "react"; +import { cva, type VariantProps } from "class-variance-authority"; + +import { cn } from "@/lib/utils"; + +const badgeVariants = cva( + "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", + { + variants: { + variant: { + default: + "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80", + secondary: + "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", + destructive: + "border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80", + outline: "text-foreground", + }, + }, + defaultVariants: { + variant: "default", + }, + }, +); + +export interface BadgeProps + extends React.HTMLAttributes, + VariantProps {} + +function Badge({ className, variant, ...props }: BadgeProps) { + return ( +
+ ); +} + +export { Badge, badgeVariants }; diff --git a/src/components/vrm.tsx b/src/components/vrm.tsx index 576ffc9..e5976ad 100644 --- a/src/components/vrm.tsx +++ b/src/components/vrm.tsx @@ -188,7 +188,7 @@ export function VRM() {
{!isLoaded ? (
- +
) : ( diff --git a/src/messages/en.json b/src/messages/en.json index 62304e5..b2118c6 100644 --- a/src/messages/en.json +++ b/src/messages/en.json @@ -27,17 +27,7 @@ "OpenSourceBlurb": "We believe in freedom and openness. Every single one of our projects and services are open source and available for anyone to use, modify, and distribute. Check out our GitHub to see what we're working on!", "WorkWithBest": "Working with the best", "WorkWithBestBlurb": "We partner with other cool organizations and help get their cool stuff out there. We're all about the community :3", - "workWithMe": "Work with us!", - "ossProducts": { - "karaSnap": { - "title": "KaraSnap", - "description": "The easiest karaoke logging app ever, powered by AI" - }, - "nextDiscordAuth": { - "title": "Next Discord Auth", - "description": "Simple, no-nonsense Discord OAuth for your Next.js apps" - } - } + "workWithMe": "Work with us!" }, "contact": { "title": "Contact Us", @@ -53,5 +43,57 @@ "ossProducts": { "viewRepo": "View Repository", "visitSite": "Visit Website" + }, + "solutions": { + "tags": { + "dev": "Developer Tools", + "lib": "Libraries", + "fun": "Fun Stuff", + "ai": "AI Powered", + "legacy": "Legacy", + "beta": "Beta", + "api": "APIs", + "bot": "Bots" + }, + "main": { + "title": "Our solutions", + "description": "Open source projects and tools made to make your life easier :3" + }, + "legacy": { + "title": "Legacy Projects", + "description": "These are projects that are no longer actively maintained or hosted by us, but are still available for use." + }, + "karaSnap": { + "title": "KaraSnap", + "description": "The easiest karaoke logging app ever, powered by AI" + }, + "nextDiscordAuth": { + "title": "Next Discord Auth", + "description": "Simple, no-nonsense Discord OAuth for your Next.js apps" + }, + "rssfetch": { + "title": "RSSFetch", + "description": "Simple API for fetching and parsing RSS feeds" + }, + "mikanbot": { + "title": "MikanBot", + "description": "A multifunctional Discord bot with a bunch of cool features, all free to use!" + }, + "customrp": { + "title": "CustomRP Web", + "description": "Custom Discord Rich Presence, no software download required!" + }, + "enkabadges": { + "title": "EnkaBadges", + "description": "Display gacha game stats on your GitHub profile!" + }, + "chat": { + "title": "MD Chat", + "description": "The GPT wrapper for your AI" + }, + "sukushocloud": { + "title": "sukusho.cloud", + "description": "A versatile screenshot hosting service with an easy-to-use API" + } } } diff --git a/src/messages/ja.json b/src/messages/ja.json index 525eb5e..fcdfd4e 100644 --- a/src/messages/ja.json +++ b/src/messages/ja.json @@ -1,4 +1,19 @@ { + "layout": { + "resources": "リソース", + "solutions": "ソリューション", + "accountCenter": "アカウントセンター", + "support": "サポート", + "contact": "お問い合わせ", + "legal": "法的条約", + "terms": "利用規約", + "privacy": "プライバシーポリシー", + "refunds": "返金ポリシー", + "jp-payments": "特定商取引法に基づく表記", + "home": "ホーム", + "vision": "私たちのビジョン", + "opensource": "オープンソース" + }, "home": { "hero": { "blurb1": "生活を豊かにする", @@ -46,5 +61,57 @@ "ossProducts": { "viewRepo": "リポジトリを見る", "visitSite": "ウェブサイトを見る" + }, + "solutions": { + "tags": { + "dev": "開発ツール", + "lib": "ライブラリ", + "fun": "面白いもの", + "ai": "AI搭載", + "legacy": "レガシー", + "beta": "ベータ版", + "api": "API", + "bot": "ボット" + }, + "main": { + "title": "私たちの製品たち", + "description": "あなたの生活をより良くするためのプロジェクトとツールたちです!" + }, + "legacy": { + "title": "レガシープロジェクト", + "description": "これらは現在アクティブに保守されていないプロジェクトですが、引き続き使用可能です。" + }, + "karaSnap": { + "title": "KaraSnap", + "description": "AIを搭載した、最も簡単なカラオケ記録アプリ" + }, + "nextDiscordAuth": { + "title": "Next Discord Auth", + "description": "Next.jsアプリのためのシンプルで使いやすいDiscord OAuth" + }, + "rssfetch": { + "title": "RSSFetch", + "description": "RSSフィードの取得と解析のためのシンプルなAPI" + }, + "mikanbot": { + "title": "MikanBot", + "description": "完全無料で使用可能な色んな機能を備えた多機能Discordボット" + }, + "customrp": { + "title": "CustomRP Web", + "description": "ソフトウェアのダウンロード不要!カスタムDiscord Rich Presenceを実現させるアプリ" + }, + "enkabadges": { + "title": "EnkaBadges", + "description": "ソシャゲーのステータスをGitHubプロフィールに表示しよう!" + }, + "chat": { + "title": "MD Chat", + "description": "自分のAIを利用できるチャットアプリ" + }, + "sukushocloud": { + "title": "sukusho.cloud", + "description": "使いやすいAPIを備えた多機能なスクリーンショットホスティングサービス" + } } }