Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
11 changes: 7 additions & 4 deletions src/app/[locale]/(homepage)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down Expand Up @@ -102,18 +103,20 @@ export default function IndexPage() {
</h3>
<div className={"grid grid-cols-1 md:grid-cols-2 w-full mt-5 gap-4"}>
<OSSProductCard
name={t("ossProducts.karaSnap.title")}
description={t("ossProducts.karaSnap.description")}
name={tSolutions("karaSnap.title")}
description={tSolutions("karaSnap.description")}
icon={KaraSnapIcon.src}
repoUrl="https://github.com/mikndotdev/karasnap"
websiteUrl="https://karasnap.mikn.dev"
tags={[tSolutions("tags.fun"), tSolutions("tags.ai")]}
/>
<OSSProductCard
name={t("ossProducts.nextDiscordAuth.title")}
description={t("ossProducts.nextDiscordAuth.description")}
name={tSolutions("nextDiscordAuth.title")}
description={tSolutions("nextDiscordAuth.description")}
icon={IdCard}
repoUrl="https://github.com/mikndotdev/next-discord-auth"
websiteUrl="https://npm.im/@mikandev/next-discord-auth"
tags={[tSolutions("tags.dev"), tSolutions("tags.lib")]}
/>
</div>
</div>
Expand Down
123 changes: 56 additions & 67 deletions src/app/[locale]/(pages)/contact/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import Link from "next/link";
import { useTranslations } from "next-intl";
import {
Mail,
Expand All @@ -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 (
<main>
<div className="flex flex-col space-y-5 justify-center items-center mt-10">
<h1 className="text-4xl lg:text-6xl text-white font-bold">
<main className="flex flex-col items-center justify-center w-full overflow-x-hidden">
<div className="flex flex-col justify-center items-center pb-24 px-4 w-full max-w-7xl mx-auto gap-8 mt-10">
<h1 className="text-4xl lg:text-6xl text-white font-bold text-center">
{t("title")}
</h1>

<Card className="w-full min-h-20 bg-inherit border-primary border-4 mt-5">
<CardContent className="flex flex-col items-center justify-center p-6 text-center text-gray-400 space-y-4">
<div className="flex flex-row justify-center items-center space-x-5">
<Mail className="w-12 h-12 text-primary" />
<h3 className="text-3xl text-white">{t("mail")}</h3>
</div>
<div className="flex flex-col lg:flex-row justify-center items-center lg:space-x-8 space-y-3 lg:space-y-0">
<div
className="flex flex-row justify-center items-center space-x-3 cursor-help"
title={t("general-support")}
>
<Headset className="w-6 h-6 text-primary" />
<h3 className="text-xl">hello@mikn.dev</h3>
</div>
<div
className="flex flex-row justify-center items-center space-x-3 cursor-help"
title={t("billing-support")}
>
<CreditCard className="w-6 h-6 text-primary" />
<h3 className="text-xl">billing@mikn.dev</h3>
</div>
<div
className="flex flex-row justify-center items-center space-x-3 cursor-help"
title={t("abuse-reports")}
>
<AlertTriangle className="w-6 h-6 text-primary" />
<h3 className="text-xl">abuse@mikn.dev</h3>
</div>
</div>
</CardContent>
</Card>

<Card className="w-full min-h-20 bg-inherit border-primary border-4">
<CardContent className="flex flex-col items-center justify-center p-6 text-center text-gray-400 space-y-4">
<div className="flex flex-row justify-center items-center space-x-5">
<Phone className="w-12 h-12 text-primary" />
<h3 className="text-3xl text-white">{t("phone")}</h3>
</div>
<div className="flex flex-row justify-center items-center space-x-5">
<h3 className="text-xl">+81 090-9276-3628</h3>
</div>
</CardContent>
</Card>

<Card className="w-full min-h-20 bg-inherit border-primary border-4">
<CardContent className="flex flex-col items-center justify-center p-6 text-center text-gray-400 space-y-4">
<div className="flex flex-row justify-center items-center space-x-5">
<Gamepad2 className="w-12 h-12 text-primary" />
<h3 className="text-3xl text-white">{t("discord")}</h3>
</div>
<div className="flex flex-row justify-center items-center space-x-5">
<Link href="https://discord.gg/2892hjFQn8">
<Button variant="default" size="lg">
{t("join")}
</Button>
</Link>
</div>
</CardContent>
</Card>

<h1 className="text-gray-400 text-center">{t("phone-disclaimer")}</h1>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 w-full gap-6">
{contactCards.map((card, index) => (
<ContactCard key={index} {...card} />
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using the array index as a key is not recommended as it can lead to unpredictable behavior if the array is sorted or items are added/removed. It's better to use a stable, unique identifier. In this case, card.title would be a great candidate for the key since the titles are unique.

Suggested change
<ContactCard key={index} {...card} />
<ContactCard key={card.title} {...card} />

))}
</div>
</div>
</main>
);
Expand Down
118 changes: 118 additions & 0 deletions src/app/[locale]/(pages)/solutions/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
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 (
<main className="flex flex-col items-center justify-center w-full overflow-x-hidden">
<div className="flex flex-col justify-center items-center pb-24 px-4 w-full max-w-7xl mx-auto gap-12 md:gap-24">
{sections.map((section, sectionIndex) => (
<div key={sectionIndex} className="flex flex-col justify-center items-center w-full gap-4">
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

It's best to avoid using array indices for keys in React lists. Since the section object has a unique key property, you should use that instead for a stable identity. This helps React efficiently update the DOM and prevents potential state-related bugs when the list changes.

Suggested change
<div key={sectionIndex} className="flex flex-col justify-center items-center w-full gap-4">
<div key={section.key} className="flex flex-col justify-center items-center w-full gap-4">

<div className="text-center font-bold mt-3">
<DecryptedText
text={t(`${section.key}.title`)}
animateOn="view"
revealDirection="center"
speed={50}
maxIterations={20}
useOriginalCharsOnly
sequential
className="text-3xl md:text-4xl font-bold"
parentClassName="text-3xl md:text-4xl font-bold"
/>
</div>
<h3 className="text-lg md:text-xl text-gray-400 text-center w-full md:w-11/12">
{t(`${section.key}.description`)}
</h3>
<div className="grid grid-cols-1 md:grid-cols-2 w-full mt-5 gap-4">
{section.products.map((product, productIndex) => (
<OSSProductCard
key={productIndex}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similar to the outer loop, using the product's index as a key is not ideal. The product object has a unique key property which should be used to ensure a stable identity for each component.

Suggested change
key={productIndex}
key={product.key}

name={t(`${product.key}.title`)}
description={t(`${product.key}.description`)}
icon={product.icon}
repoUrl={product.repoUrl}
websiteUrl={product.websiteUrl}
tags={product.tagKeys.map((tagKey) => t(`tags.${tagKey}`))}
/>
))}
</div>
</div>
))}
</div>
</main>
);
}
Binary file added src/assets/img/mikanbot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading