Skip to content

Commit 56219fc

Browse files
authored
Merge pull request #200 from ut-code/new-title
トップページをいい感じにする2
2 parents 13c9538 + d6b2da6 commit 56219fc

File tree

13 files changed

+467
-133
lines changed

13 files changed

+467
-133
lines changed

app/(docs)/@chat/chat/[chatId]/chatArea.tsx

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -20,42 +20,49 @@ export function ChatAreaContainer(props: {
2020
<aside
2121
className={clsx(
2222
// モバイルでは全画面表示する
23-
"fixed inset-0 pt-20 bg-base-100",
23+
"fixed inset-0 bg-base-100",
2424
// PCではスクロールで動かない右サイドバー
25-
"has-chat-1:sticky has-chat-1:top-16 has-sidebar:top-0 has-chat-1:pt-4",
25+
// 左にサイドバーがない=navvarがある とき、navbar分のスペースをあける(top-16, h-[100vh-4rem])
26+
"has-chat-1:sticky has-chat-1:top-16 has-sidebar:top-0",
2627
"has-chat-1:basis-2/5 has-chat-1:max-w-chat-area has-chat-1:h-[calc(100vh-4rem)] has-sidebar:h-screen",
2728
"has-chat-1:shadow-md has-chat-1:bg-base-200",
2829
// navbar(z-40)よりは下、ChatListForSectionのdropdown(デフォルトでz-999だがz-30に変えている)よりも上
29-
"z-35",
30-
"p-4",
31-
"flex flex-col",
32-
"overflow-y-auto"
30+
"z-35"
3331
)}
3432
>
35-
<ChatAreaStateUpdater chatId={props.chatId} />
36-
<div className="flex flex-row items-center">
37-
<span className="flex-1 text-base font-bold opacity-40">
38-
AIへの質問
39-
</span>
40-
<Link className="btn btn-ghost" href="/chat" scroll={false}>
41-
<svg
42-
className="w-8 h-8 -scale-x-100"
43-
viewBox="0 0 24 24"
44-
fill="none"
45-
xmlns="http://www.w3.org/2000/svg"
46-
>
47-
<path
48-
d="M18 17L13 12L18 7M11 17L6 12L11 7"
49-
stroke="currentColor"
50-
strokeWidth="1.5"
51-
strokeLinecap="round"
52-
strokeLinejoin="round"
53-
/>
54-
</svg>
55-
<span className="text-lg">閉じる</span>
56-
</Link>
33+
<div className="absolute inset-x-0 bottom-0 h-16 bg-linear-to-t from-base-200 to-base-200/0 z-1" />
34+
<div
35+
className={clsx(
36+
"p-4 pb-16",
37+
"pt-20 has-chat-1:pt-4",
38+
"h-full flex flex-col overflow-y-auto"
39+
)}
40+
>
41+
<ChatAreaStateUpdater chatId={props.chatId} />
42+
<div className="flex flex-row items-center">
43+
<span className="flex-1 text-base font-bold opacity-40">
44+
AIへの質問
45+
</span>
46+
<Link className="btn btn-ghost" href="/chat" scroll={false}>
47+
<svg
48+
className="w-8 h-8 -scale-x-100"
49+
viewBox="0 0 24 24"
50+
fill="none"
51+
xmlns="http://www.w3.org/2000/svg"
52+
>
53+
<path
54+
d="M18 17L13 12L18 7M11 17L6 12L11 7"
55+
stroke="currentColor"
56+
strokeWidth="1.5"
57+
strokeLinecap="round"
58+
strokeLinejoin="round"
59+
/>
60+
</svg>
61+
<span className="text-lg">閉じる</span>
62+
</Link>
63+
</div>
64+
{props.children}
5765
</div>
58-
{props.children}
5966
</aside>
6067
);
6168
}

app/(docs)/@docs/[lang]/[pageId]/pageContent.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ export function PageContent(props: PageContentProps) {
146146
const [isFormVisible, setIsFormVisible] = useState(false);
147147

148148
return (
149-
<div className="flex-1 p-4 flex flex-col">
149+
<div className="flex-1 p-4 pb-16 flex flex-col">
150150
<div
151151
className="max-w-full mx-auto grid"
152152
style={{

app/featureCard.tsx

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
"use client";
2+
3+
import clsx from "clsx";
4+
import { ReactNode } from "react";
5+
import { StyledMarkdown } from "./markdown/markdown";
6+
import { Heading } from "./markdown/heading";
7+
import {
8+
ChatAreaStateProvider,
9+
ChatAreaStateUpdater,
10+
} from "./(docs)/chatAreaState";
11+
12+
export function FeatureCard(props: {
13+
reversed?: boolean;
14+
icon: ReactNode;
15+
title: ReactNode;
16+
children: ReactNode;
17+
iconColor: string;
18+
image: ReactNode;
19+
}) {
20+
return (
21+
<div
22+
className={clsx(
23+
"flex flex-col items-center gap-4 md:gap-8",
24+
props.reversed ? "md:flex-row-reverse" : "md:flex-row"
25+
)}
26+
>
27+
<div className="flex-1 space-y-4 lg:space-y-8">
28+
<div className="flex flex-row gap-2 items-center">
29+
<span className={clsx("p-3 rounded-xl text-2xl", props.iconColor)}>
30+
{props.icon}
31+
</span>
32+
<h3 className="text-2xl/8 md:text-3xl/10 font-bold">{props.title}</h3>
33+
</div>
34+
<p className="opacity-70 leading-relaxed text-lg">{props.children}</p>
35+
</div>
36+
<div className="w-80 max-w-full md:min-w-3/7 md:max-w-1/2">
37+
<figure
38+
className={clsx(
39+
"aspect-video bg-base-200 rounded-xl border border-base-300 shadow-sm",
40+
"relative overflow-hidden select-none"
41+
)}
42+
>
43+
{props.image}
44+
</figure>
45+
</div>
46+
</div>
47+
);
48+
}
49+
50+
export function RuntimeImage() {
51+
// public/docs/python/1-basics/2-2-str.md より
52+
return (
53+
<div className="absolute left-2 w-200 -inset-y-100 h-max my-auto scale-70 md:scale-85 origin-left">
54+
<StyledMarkdown
55+
content={`### 文字列(str)
56+
57+
文字列はシングルクォート (\`'\`) またはダブルクォート (\`"\`) で囲んで作成します。
58+
59+
文字列の連結は \`+\` 演算子、繰り返しは \`*\` 演算子を使います。
60+
`}
61+
/>
62+
<pre
63+
className={clsx(
64+
"bg-base-300 border-2 border-accent rounded-box shadow-md m-2 h-max",
65+
"p-4 font-mono"
66+
)}
67+
>
68+
&gt;&gt;&gt; name <HOperator>=</HOperator>{" "}
69+
<HString>&quot;Guido&quot;</HString>
70+
{"\n"}
71+
&gt;&gt;&gt; greeting <HOperator>=</HOperator>{" "}
72+
<HString>&apos;Hello&apos;</HString>
73+
{"\n"}
74+
&gt;&gt;&gt; full_greeting <HOperator>=</HOperator> greeting{" "}
75+
<HOperator>+</HOperator> <HString>&quot;, &quot;</HString>{" "}
76+
<HOperator>+</HOperator> name <HOperator>+</HOperator>{" "}
77+
<HString>&quot;!&quot;</HString>
78+
{"\n"}
79+
&gt;&gt;&gt; <Cursor />
80+
</pre>
81+
</div>
82+
);
83+
}
84+
85+
export function PracticeImage() {
86+
// public/docs/python/1-basics/2-2-str.md より
87+
return (
88+
<div className="absolute left-2 w-200 top-0 scale-70 md:scale-85 origin-top-left">
89+
<StyledMarkdown
90+
content={`### 練習問題1
91+
92+
\`item_name\` という変数に商品名(文字列)、\`price\` という変数に価格(整数)、\`stock\` という変数に在庫数(整数)をそれぞれ代入してください。その後、f-stringを使って「商品: [商品名], 価格: [価格]円, 在庫: [在庫数]個」という形式の文字列にし、 \`print()\` で出力するコードを書いてみましょう。
93+
`}
94+
/>
95+
<div
96+
className={clsx(
97+
"bg-base-300 border-2 border-accent rounded-box shadow-md m-2",
98+
"h-60 overflow-hidden"
99+
)}
100+
>
101+
<div className="flex flex-row items-center bg-base-200">
102+
<span className="mt-2 mb-1 ml-3 mr-2 text-sm text-left">
103+
<span>ファイルを編集:</span>
104+
<span className="font-mono ml-2">practice2-1.py</span>
105+
</span>
106+
<div className="flex-1" />
107+
</div>
108+
<pre className="px-4 py-2">
109+
item_name = <HString>&quot;高性能マウス&quot;</HString>
110+
{"\n"}
111+
price = <HNumber>4500</HNumber>
112+
</pre>
113+
</div>
114+
</div>
115+
);
116+
}
117+
118+
export function ChatImage() {
119+
// public/docs/python/1-basics/2-1-str.md より
120+
return (
121+
<>
122+
<div className="absolute right-2/5 w-[85%] md:w-[70%] top-0 scale-70 md:scale-85 origin-top-right pointer-events-none">
123+
{/*ここでChatAreaStateProviderのインスタンス作りダミーの値をセットすることで、
124+
StyledMarkdownが呼び出すMultiHighlightに現在このチャットを開いていると認識させる
125+
*/}
126+
<ChatAreaStateProvider>
127+
<ChatAreaStateUpdater chatId="sample" />
128+
<StyledMarkdown
129+
content={`### 数値(int, float)
130+
131+
Pythonは整数 (\`int\`) と浮動小数点数 (\`float\`) を区別します。
132+
浮動小数点数 (\`float\`) は、他の言語の double 型に相当する倍精度浮動小数点数です。
133+
`}
134+
replacedRange={[{ start: 64, end: 120, id: "sample" }]}
135+
/>
136+
</ChatAreaStateProvider>
137+
<pre
138+
className={clsx(
139+
"bg-base-300 border-2 border-accent rounded-box shadow-md m-2 h-max",
140+
"p-4 font-mono"
141+
)}
142+
>
143+
&gt;&gt;&gt; <HDim># 整数 (int)</HDim>
144+
{"\n"}
145+
&gt;&gt;&gt; a <HOperator>=</HOperator> <HNumber>10</HNumber>
146+
{"\n"}
147+
&gt;&gt;&gt; <HFunc>type</HFunc>
148+
<HDim>(</HDim>a<HDim>)</HDim>
149+
{"\n"}
150+
<HOperator>
151+
&lt;class <HString>&apos;int&apos;</HString>&gt;
152+
</HOperator>
153+
{"\n"}
154+
&gt;&gt;&gt; <HDim># 浮動小数点数 (float)</HDim>
155+
{"\n"}
156+
&gt;&gt;&gt; b <HOperator>=</HOperator> <HNumber>3.14</HNumber>
157+
{"\n"}
158+
&gt;&gt;&gt; <HFunc>type</HFunc>
159+
<HDim>(</HDim>b<HDim>)</HDim>
160+
{"\n"}
161+
<HOperator>
162+
&lt;class <HString>&apos;float&apos;</HString>&gt;
163+
</HOperator>
164+
</pre>
165+
</div>
166+
<aside
167+
className={clsx(
168+
"absolute left-3/5 md:w-80 top-0 scale-70 md:scale-85 origin-top-left",
169+
"bg-base-300 shadow-md p-3 flex flex-col"
170+
)}
171+
>
172+
<span className="flex-1 text-base font-bold opacity-40">
173+
AIへの質問
174+
</span>
175+
<Heading level={2} className="mt-1! mb-1! text-nowrap">
176+
Pythonのdouble型について
177+
</Heading>
178+
<div className="divider my-0" />
179+
<div className="chat chat-end place-items-start ml-3">
180+
<div
181+
className="chat-bubble p-0! bg-secondary/30"
182+
style={{ maxWidth: "100%", wordBreak: "break-word" }}
183+
>
184+
<StyledMarkdown content="double型はありますか?" />
185+
</div>
186+
</div>
187+
<StyledMarkdown
188+
content={`Pythonには「double型」は存在しません。他の言語(C++、Java、C#など)でおなじみのdouble型に相当するのは、Pythonの**float型**です。
189+
190+
Pythonのfloat型は**倍精度浮動小数点数(double-precision floating point)** を表し、他の言語のdouble型と同じ桁数の精度(通常15〜17桁)を提供します。そのため、Pythonでは単一のfloat型だけで十分です。`}
191+
/>
192+
</aside>
193+
</>
194+
);
195+
}
196+
197+
function HString(props: { children: ReactNode }) {
198+
return <span className="text-green-700">{props.children}</span>;
199+
}
200+
function HOperator(props: { children: ReactNode }) {
201+
return <span className="text-fuchsia-500">{props.children}</span>;
202+
}
203+
function HNumber(props: { children: ReactNode }) {
204+
return <span className="text-yellow-700">{props.children}</span>;
205+
}
206+
function HFunc(props: { children: ReactNode }) {
207+
return <span className="text-cyan-600">{props.children}</span>;
208+
}
209+
function HDim(props: { children: ReactNode }) {
210+
return <span className="opacity-50">{props.children}</span>;
211+
}
212+
function Cursor() {
213+
return (
214+
<span
215+
ref={(el) => {
216+
// カーソルの点滅アニメーション
217+
el?.animate([{ opacity: "1" }, { opacity: "0" }, { opacity: "1" }], {
218+
duration: 1000,
219+
iterations: Infinity,
220+
easing: "steps(2, end)",
221+
});
222+
}}
223+
style={{
224+
display: "inline-block",
225+
boxShadow: `2px 0 0 var(--color-primary) inset`,
226+
verticalAlign: "top",
227+
}}
228+
>
229+
{" "}
230+
</span>
231+
);
232+
}

app/footer.tsx

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
export function Footer() {
2+
return (
3+
<footer className="footer sm:footer-horizontal bg-neutral text-neutral-content p-10 z-30">
4+
<aside>
5+
<h6 className="flex gap-2 items-center">
6+
<img src="/icon.svg" alt="my.code(); Logo" className="w-12 h-12" />
7+
<span className="text-3xl font-semibold font-mono drop-shadow-sm">
8+
my.code();
9+
</span>
10+
</h6>
11+
<p className="text-lg">環境構築不要、その場で実践。</p>
12+
<a
13+
className="link link-hover"
14+
href="https://github.com/ut-code/my-code"
15+
target="_blank"
16+
>
17+
{/*<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->*/}
18+
<svg
19+
fill="currentColor"
20+
className="inline-block w-4 h-4 mr-1"
21+
viewBox="0 0 24 24"
22+
>
23+
<path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" />
24+
</svg>
25+
ut-code / my-code
26+
</a>
27+
<p>Copyright © 2026 ut.code();</p>
28+
</aside>
29+
<nav>
30+
<h6 className="footer-title normal-case">ut.code(); について</h6>
31+
<a
32+
className="link link-hover"
33+
href="https://utcode.net/"
34+
target="_blank"
35+
>
36+
公式ウェブサイト
37+
</a>
38+
<a
39+
className="link link-hover"
40+
href="https://twitter.com/utokyo_code"
41+
target="_blank"
42+
>
43+
公式 𝕏 アカウント
44+
</a>
45+
</nav>
46+
</footer>
47+
);
48+
}

app/layout.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { AutoAnonymousLogin } from "./accountMenu";
1313
import { SidebarMdProvider } from "./sidebar";
1414
import { RuntimeProvider } from "@my-code/runtime/context";
1515
import { getPagesList } from "@/lib/docs";
16+
import { Footer } from "./footer";
1617

1718
export const metadata: Metadata = {
1819
title: {
@@ -53,6 +54,7 @@ export default async function RootLayout({
5354
</div>
5455
</div>
5556
</SidebarMdProvider>
57+
<Footer />
5658
</body>
5759
</html>
5860
);

0 commit comments

Comments
 (0)