- {renderTitle()}
- {subLabel &&
}
+
+
+ {label}
+
+ {subLabel && !isEnglish &&
+
+ {subLabel}
+
+ }
);
}
\ No newline at end of file
diff --git a/app/i18n/config.ts b/app/i18n/config.ts
index 63002a5..330acf7 100644
--- a/app/i18n/config.ts
+++ b/app/i18n/config.ts
@@ -11,7 +11,7 @@ const resources = {
en: {
translation: translation_en
}
- };
+ } as const;
i18n
.use(initReactI18next)
diff --git a/app/i18n/en.json b/app/i18n/en.json
index 403b68d..42ae8ff 100644
--- a/app/i18n/en.json
+++ b/app/i18n/en.json
@@ -1,10 +1,19 @@
{
"common": {
"button": "Button",
+ "subtitle": "Brighter Futures for Students",
+ "detail": "Detail",
+ "list": "List",
"tags": {
"hackathon": "Hackathon",
"recruitment": "Recruitment",
"urgent": "Urgent"
+ },
+ "roles": {
+ "owner": "Owner",
+ "coowner": "Co-Owner",
+ "backend": "Backend",
+ "frontend": "Frontend"
}
},
"card": {
diff --git a/app/i18n/ja.json b/app/i18n/ja.json
index 796d608..635f028 100644
--- a/app/i18n/ja.json
+++ b/app/i18n/ja.json
@@ -1,13 +1,19 @@
{
- "language": "JP",
"common": {
"button": "ボタン",
"detail": "詳細",
"list": "一覧",
+ "subtitle": "学生の未来をもっと「明るく」",
"tags": {
"hackathon": "ハッカソン",
"recruitment": "募集",
"urgent": "緊急"
+ },
+ "roles": {
+ "owner": "代表",
+ "coowner": "副代表",
+ "backend": "バックエンド",
+ "frontend": "フロントエンド"
}
},
"card": {
diff --git a/app/root.tsx b/app/root.tsx
index a0df061..7971c08 100644
--- a/app/root.tsx
+++ b/app/root.tsx
@@ -19,6 +19,10 @@ export const links: Route.LinksFunction = () => [
href: "https://fonts.gstatic.com",
crossOrigin: "anonymous",
},
+ {
+ rel: "stylesheet",
+ href: "https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@100..900&display=swap"
+ },
{
rel: "stylesheet",
href: "https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap",
@@ -27,7 +31,7 @@ export const links: Route.LinksFunction = () => [
export function Layout({ children }: { children: React.ReactNode }) {
return (
-
+
diff --git a/app/routes.ts b/app/routes.ts
index 102b402..dd551c7 100644
--- a/app/routes.ts
+++ b/app/routes.ts
@@ -1,3 +1,8 @@
import { type RouteConfig, index } from "@react-router/dev/routes";
-export default [index("routes/home.tsx")] satisfies RouteConfig;
+export default [
+ index("routes/home.tsx"),
+ {
+ path: "blog",
+ file: "routes/blog/index.tsx" }
+] satisfies RouteConfig;
diff --git a/app/routes/blog/index.module.css b/app/routes/blog/index.module.css
new file mode 100644
index 0000000..d059682
--- /dev/null
+++ b/app/routes/blog/index.module.css
@@ -0,0 +1,7 @@
+.container {
+ width: 100vw;
+ height: 100vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
\ No newline at end of file
diff --git a/app/routes/blog/index.tsx b/app/routes/blog/index.tsx
new file mode 100644
index 0000000..40ba22d
--- /dev/null
+++ b/app/routes/blog/index.tsx
@@ -0,0 +1,14 @@
+import type { JSX } from "react";
+import { Header } from "~/components/Header/Header";
+import styles from "./index.module.css";
+
+export default function Blog(): JSX.Element {
+ return (
+
+ )
+}
\ No newline at end of file
diff --git a/app/routes/home.css b/app/routes/home.css
new file mode 100644
index 0000000..8b3bc33
--- /dev/null
+++ b/app/routes/home.css
@@ -0,0 +1,117 @@
+.home-main-container {
+ background-color: var(--based-color);
+ width: 100vw;
+}
+
+section {
+ padding: 120px 0;
+}
+
+.sub-title {
+ color: #9D9F9F;
+ font-weight: 900;
+}
+
+.home-sub-title {
+ height: 36px;
+ font-size: 30px;
+ font-weight: 400;
+}
+
+.t-highlight {
+ color: #1E89E0;
+}
+
+.title-container {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+}
+
+
+.home-title-container {
+ height: 100vh;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.home-notice {
+ justify-content: center;
+ flex-direction: column;
+ align-items: center;
+ display: flex;
+ gap: 30px;
+}
+
+.home-notice-divider {
+ border: none;
+ border-top: 1px solid #555;
+ margin: 50px auto;
+ width: 80%;
+ max-width: 1300px;
+ border-width: 3px;
+}
+
+.home-member {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 30px;
+ max-width: 800px;
+}
+
+.home-member-card-layout {
+ display: flex;
+ justify-content: center;
+ margin-top: 8rem;
+}
+
+.home-product-card-layout {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ margin-top: 8rem;
+}
+
+.home-product {
+ display: flex;
+ gap: 8rem;
+}
+
+.home-section-left {
+ margin-left: 13rem;
+}
+
+.home-section-right {
+ margin-right: 13rem;
+}
+
+.home-about-title h1 {
+ margin: 3rem 13rem 3rem;
+ color: var(--accent-color);
+ font-size: 64px;
+ font-weight: bold;
+ border-left: 15px solid dodgerblue;
+ padding-left: 2rem;
+}
+
+.home-about-content {
+ margin: 2rem 13rem;
+ font-size: 40px;
+ color: var(--accent-color);
+}
+
+.home-activity-card-layout {
+ display: flex;
+ justify-content: center;
+ margin-top: 8rem;
+}
+
+.home-activity {
+ justify-content: center;
+ flex-direction: column;
+ align-items: center;
+ display: flex;
+ gap: 30px;
+}
+
diff --git a/app/routes/home.tsx b/app/routes/home.tsx
index 398e47c..f45f36e 100644
--- a/app/routes/home.tsx
+++ b/app/routes/home.tsx
@@ -1,13 +1,133 @@
+import { useTranslation } from "react-i18next";
+import { ActivityCard, type ActivityCardProps } from "~/components/ActivityCard/ActivityCard";
+import { Footer } from "~/components/Footer/Footer";
+import { Header } from "~/components/Header/Header";
+import { MemberCard, type MemberCardProps } from "~/components/MemberCard/MemberCard";
+import { NoticeCard, type NoticeCardProps } from "~/components/NoticeCard/NoticeCard";
+import { ProductCard, type ProductCardProps } from "~/components/ProductCard/ProductCard";
+import { Title } from "../components/Title/Title";
import type { Route } from "./+types/home";
-import { Welcome } from "../welcome/welcome";
+import "./home.css";
-export function meta({}: Route.MetaArgs) {
+export function meta({ }: Route.MetaArgs) {
return [
- { title: "New React Router App" },
- { name: "description", content: "Welcome to React Router!" },
+ { title: "団体公式ホームページ | Object
" },
+ { name: "description", content: "学生団体「Object」の公式ホームページです。" },
+ { property: "og:site_name", content: "Object"},
+ { property: "og:title", content: "団体公式ホームページ | Object" },
+ { property: "og:type", content: "website" },
+ { property: "og:url", content: "https://object-t.com" },
+ { property: "og:image", content: "https://object-t.com/assets/images/ogp_image.jpg" },
+ { property: "og:description", content: "学生団体「Object」の公式ホームページです。" },
];
}
+const members: MemberCardProps[] = [
+ { name: "Naoto Kido", role: "owner", description: "よわよわプログラマー", stacks: ['Kubernetes', 'AWS', 'Java', 'Go-wordmark', 'Flutter'], headerImage: "https://pbs.twimg.com/profile_banners/1846395762277826560/1737992837/1500x500", iconImage: "https://avatars.githubusercontent.com/u/54303857", githubName: "naoido" },
+ { name: "Miura Naoki", role: "coowner", description: "ねこねこプログラマー", stacks: ['Go-wordmark', 'Javascript', 'Rust', 'Python', 'Neovim'], headerImage: "https://cdn.discordapp.com/attachments/1325818102960623729/1350589227477504051/IMG_0649.jpg?ex=67edb33c&is=67ec61bc&hm=52b978d0b55914eef3fb9015748e4b496f4bb16d207d648bdc97a28a05a82bc8&", iconImage: "https://avatars.githubusercontent.com/u/114989748", githubName: "thirdlf03" },
+ { name: "Takumi Matsubara", role: "frontend", description: "うまうまプログラマー", stacks: ['Typescript', 'Swift', 'React'], headerImage: "https://cdn.discordapp.com/attachments/1325818102960623729/1350615961505366016/IMG_7620.jpg?ex=67edcc22&is=67ec7aa2&hm=7aaf0e07ab67d2484cb9c54fa09ebb329082606cad3218443a3985c4f2aac415&", iconImage: "https://avatars.githubusercontent.com/u/152017354", githubName: "AnnkoATAMA" },
+ { name: "Kentaro Doi", role: "backend", description: "メンズコーチ", stacks: ['Javascript', 'Python', 'Php', 'Laravel', 'Typescript'], headerImage: "https://cdn.discordapp.com/attachments/1325818102960623729/1350718393178656799/jpg.jpg?ex=67ee2b88&is=67ecda08&hm=54e2abad70d172d4ec551a3a47fd89b2deefc2ee738f0debbe9f4a0543453bee&", iconImage: "https://avatars.githubusercontent.com/u/148222450", githubName: "kenta-afk" },
+]
+
+const notices: NoticeCardProps[] = [
+ { date: "開催日: 2025年5月12日(月)", title: "学内ハッカソン開催", description: "今回は学内のスキルアップを目指して学内ハッカソンを開催することになりました!詳細ページはこちらをクリック!", tags: ["hackathon", "recruitment"], imageUrl: "/app/components/assets/logo.webp" },
+ { date: "開催日: 2025年8月32日(月)", title: "LT会", description: "勉強したことをアウトプットするために、LT会を開催することにしました", tags: ["hackathon", "recruitment"], imageUrl: "https://avatars.githubusercontent.com/u/54303857" }
+]
+
+const products: ProductCardProps[] = [
+ { headerImage: "https://pbs.twimg.com/profile_banners/1846395762277826560/1737992837/1500x500", title: "ねこbot", stacks: ["Go-wordmark", "ArgoCD"], description: "ねこbotは団体discordで運用しているbotです。団体内での情報共有や、AIによる質問返答、グループ管理の役割を担っています。", stars: 1, commits: 142, pullRequests: 75, linkedButtons: [{ label: "Github", url: "https://github.com/naoido/neko-bot" }] },
+ { headerImage: "https://pbs.twimg.com/profile_banners/1846395762277826560/1737992837/1500x500", title: "団体公式サイト", stacks: ["Cloudflare", "React", "Cloudflareworkers", "Storybook"], description: "団体公式のウェブサイトです。Reactで構成されており、Cloudfalre Workers使用し記事の更新などを行い、Cloudflare Pagesにデプロイしています。", stars: 2, commits: 86, pullRequests: 54, linkedButtons: [{ label: "Github", url: "https://github.com/object-t/object-t-website" }, { label: "Figma", url: "https://www.figma.com/design/YWBtX9qhd0QKOTY4a2SEWx" }] }
+]
+
+const activities: ActivityCardProps[] = [
+ { headerImage: "https://pbs.twimg.com/media/GmZOyaFacAA4vCx?format=jpg&name=large", title: "複数名でのハッカソン参加", from: new Date("2025-03-17T12:00:00.000Z"), to: new Date("2025-03-19T12:00:00.000Z"), description: "今回は、メンバー5人でのハッカソンに参加をしました!1人のチームと、スキルアップを目指している4人の計2グループでの参加です!", url: "https://x.com/Hackz_team/status/1902294529446965727" },
+ { headerImage: "https://pbs.twimg.com/media/GkyBWsiaoAA0nwH?format=jpg&name=medium", title: "2度目のハッカソン優勝", from: new Date("2025-02-26T12:00:00.000Z"), to: new Date("2024-02-27T12:00:00.000Z"), description: "今回も株式会社ハックツ様のハッカソンに参加してきました!株式会社ヌーラボ様のオフィスをお借りしてのハッカソン、そして年1回の野良ハッカソンだったのでとても楽しかったです!そして副代表のthirld03が優勝しました!!", url: "https://x.com/Hackz_team/status/1895031776290185529" },
+ { headerImage: "https://pbs.twimg.com/media/Ge1P7h9bkAARNb9?format=jpg&name=medium", title: "ハックツハッカソン初優勝", from: new Date("2024-03-01T12:00:00.000Z"), to: new Date("2024-03-02T12:00:00.000Z"), description: "株式会社ハックツ様主催のハッカソン「アンキロカップ」にて最優秀賞を獲得しました!2日間のハッカソン期間中徹夜で仕上げ、気持ちを込めた作品だったので優勝できてとても嬉しかったです!!", url: "https://x.com/Hackz_team/status/1868237310086770791" },
+ { headerImage: "/app/components/assets/logo.webp", title: "学生団体Object結成", from: new Date("2024-03-01T12:00:00.000Z"), description: "念願の学生団体Objectを結成しました!これからたくさんの学生のスキルアップなどを目指した学生団体を目指し、この学生団体に入ってよかったと思っていただけるような団体を目指しがんばります!", url: "https://github.com/object-t/object-t-website" }
+]
export default function Home() {
- return ;
+ const { t } = useTranslation();
+
+ return (
+
+
+
+
+
+ Object<T>
+
+
+ {t("common.subtitle")}
+
+
+
+
+
+
+
+
+
+
+
+ {notices.map((notice, index) => (
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+
「Object」のような
全ての出発地点になることを目指す
+
+
+
昨今、小学校でのプログラミング教育の義務化や、共通テストで「情報」という科目が追加されるなど、プログラミングを触れる機会が増えてきています。しかし、プログラミングの”楽しさ”や”魅力”というのは深く知る機会がないと思います。
そこで私たちは、活動を通してプログラミングでしか得ることができない楽しみや感動を知ってもらい、プログラマーの第一歩を踏み出すきっかけになってもらうことを目指します。
+
+
+
+
+
+
+
+
+
+ {members.map((member, index) => (
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+ {products.map((product, index) => (
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+ {activities.map((activity, index) => (
+
+ ))}
+
+
+
+
+
+ );
}
diff --git a/public/assets/images/ogp_image.jpg b/public/assets/images/ogp_image.jpg
new file mode 100644
index 0000000..ad31ef6
Binary files /dev/null and b/public/assets/images/ogp_image.jpg differ
diff --git a/public/favicon.ico b/public/favicon.ico
index 5dbdfcd..b0223d0 100644
Binary files a/public/favicon.ico and b/public/favicon.ico differ
diff --git a/react-router.config.ts b/react-router.config.ts
index 6ff16f9..b8b143a 100644
--- a/react-router.config.ts
+++ b/react-router.config.ts
@@ -3,5 +3,5 @@ import type { Config } from "@react-router/dev/config";
export default {
// Config options...
// Server-side render by default, to enable SPA mode set this to `false`
- ssr: true,
+ ssr: false,
} satisfies Config;
diff --git a/tsconfig.json b/tsconfig.json
index dc391a4..e838dc9 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -3,7 +3,7 @@
"**/*",
"**/.server/**/*",
"**/.client/**/*",
- ".react-router/types/**/*"
+ ".react-router/types/**/*",
],
"compilerOptions": {
"lib": ["DOM", "DOM.Iterable", "ES2022"],
diff --git a/vite.config.ts b/vite.config.ts
index b706ce8..584b67a 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -6,7 +6,7 @@ import tsconfigPaths from "vite-tsconfig-paths";
export default defineConfig({
plugins: [
tailwindcss(),
- !process.env.VITEST && reactRouter(),
+ !process.env.VITEST && [reactRouter()],
tsconfigPaths()
],
});
\ No newline at end of file