mirror of
https://github.com/yudejp/yude.jp.git
synced 2025-05-11 14:38:41 +00:00
Support light mode
This commit is contained in:
parent
40fbbbe46f
commit
768b4a1aba
62
src/App.tsx
62
src/App.tsx
@ -6,6 +6,7 @@ import VerticalMenu from "./components/VerticalMenu"
|
||||
import HorizontalMenu from "./components/HorizontalMenu"
|
||||
import ContentRenderer from "./components/ContentRenderer"
|
||||
import Footer from "./components/Footer"
|
||||
import { ThemeProvider, ThemeSwitcher } from "./components/Theme"
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
@ -58,36 +59,43 @@ export default function App() {
|
||||
|
||||
return (
|
||||
<RecoilRoot>
|
||||
<div id="mutuals">
|
||||
<Mutuals />
|
||||
</div>
|
||||
<div>
|
||||
<div className={`sticky h-screen absolute`} style={{ opacity: cardOpacity, marginTop: `${document.getElementById("mutuals")?.offsetHeight}px` }}>
|
||||
<div id="card" className="fixed bg-neutral-900 py-5 -mt-20" style={{ top: `${cardY}px` }}>
|
||||
<Card />
|
||||
<ThemeProvider>
|
||||
<>
|
||||
<div id="mutuals">
|
||||
<Mutuals />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center">
|
||||
<div id="content" className="absolute text-white" style={{ top: `${contentY}px`}}>
|
||||
<div className="grid grid-container md:grid-cols-5 gap-2 min-h-[70vh] w-3xl">
|
||||
<div className="hidden md:block md:col-span-1">
|
||||
<VerticalMenu />
|
||||
<div>
|
||||
<div className={`sticky h-screen absolute`} style={{ opacity: cardOpacity, marginTop: `${document.getElementById("mutuals")?.offsetHeight}px` }}>
|
||||
<div id="card" className="fixed py-5 -mt-20" style={{ top: `${cardY}px` }}>
|
||||
<Card />
|
||||
</div>
|
||||
</div>
|
||||
<div className="block md:hidden">
|
||||
<HorizontalMenu />
|
||||
</div>
|
||||
<div className="w-full px-5 md:col-span-4 md:px-0">
|
||||
<ContentRenderer />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid justify-items-center">
|
||||
<div id="content" className="absolute dark:text-white sm:min-w-[565px]" style={{ top: `${contentY}px`}}>
|
||||
<div className="grid grid-container md:grid-cols-5 gap-2 min-h-[70vh] w-3xl">
|
||||
<div className="hidden md:block md:col-span-1">
|
||||
<VerticalMenu />
|
||||
</div>
|
||||
<div className="block md:hidden">
|
||||
<HorizontalMenu />
|
||||
</div>
|
||||
<div className="px-5 md:col-span-4 md:px-0">
|
||||
<ContentRenderer />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mb-5" id="test">
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-5 mt-5" id="test">
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="fixed top-5 right-5 text-3xl dark:text-white">
|
||||
<ThemeSwitcher />
|
||||
</div>
|
||||
</>
|
||||
</ThemeProvider>
|
||||
</RecoilRoot>
|
||||
)
|
||||
}
|
||||
|
@ -54,41 +54,41 @@ export default function Card() {
|
||||
</div>
|
||||
<div className="mx-2 text-left h-full inline-block">
|
||||
<Logo />
|
||||
<p className="text-white mt-2 -mb-1">
|
||||
<p className="dark:text-white mt-2 -mb-1">
|
||||
{np && np.isPlaying &&
|
||||
<div className="flex flex-row">
|
||||
<div className="w-5 text-gray-300">
|
||||
<div className="w-5 text-gray-900 dark:text-gray-300">
|
||||
<FontAwesomeIcon icon={faMusic} />
|
||||
</div>
|
||||
<div className="text-left max-w-xs">
|
||||
<span className="text-gray-300">{np.artist}</span>
|
||||
<span className="text-gray-900 dark:text-gray-300">{np.artist}</span>
|
||||
<p className="text-lg">{np.title}</p>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</p>
|
||||
<div className="text-white mt-2">
|
||||
<div className="dark:text-white mt-2">
|
||||
<p className="font-mono left-0.5 relative">
|
||||
<FontAwesomeIcon icon={faEnvelope} className="text-gray-300" />{" "}
|
||||
<FontAwesomeIcon icon={faEnvelope} className="dark:text-gray-300" />{" "}
|
||||
i@yude.jp
|
||||
</p>
|
||||
<p className="font-mono left-0.5 relative">
|
||||
<FontAwesomeIcon icon={faPhone} className="text-gray-300" />{" "}
|
||||
<FontAwesomeIcon icon={faPhone} className="dark:text-gray-300" />{" "}
|
||||
+81 70-8909-1949
|
||||
</p>
|
||||
<p className="font-mono left-0.5 relative">
|
||||
<a href="https://x.com/yude_jp">
|
||||
<FontAwesomeIcon icon={faXTwitter} className="text-gray-300" />{" "}
|
||||
<FontAwesomeIcon icon={faXTwitter} className="dark:text-gray-300" />{" "}
|
||||
@yude_jp
|
||||
</a>
|
||||
</p>
|
||||
<p className="font-mono left-0.5 relative">
|
||||
<FontAwesomeIcon icon={faDiscord} className="text-gray-300" />{" "}
|
||||
<FontAwesomeIcon icon={faDiscord} className="dark:text-gray-300" />{" "}
|
||||
<span className="-ml-1">yude</span>
|
||||
</p>
|
||||
<p className="font-mono left-0.5 relative">
|
||||
<a href="https://github.com/yude">
|
||||
<FontAwesomeIcon icon={faGithub} className="text-gray-300" />{" "}
|
||||
<FontAwesomeIcon icon={faGithub} className="dark:text-gray-300" />{" "}
|
||||
yude
|
||||
</a>
|
||||
</p>
|
||||
|
@ -91,23 +91,23 @@ export default function Chat() {
|
||||
</div>
|
||||
<div className="text-wrap max-w-xl">
|
||||
<div className="mb-5">
|
||||
<label className="block mb-2 text-sm font-medium text-white">
|
||||
<label className="block mb-2 text-sm font-medium dark:text-white">
|
||||
名前{" "}
|
||||
<span className="text-orange-400">*</span>
|
||||
</label>
|
||||
<input type="text" id="name" className="w-full block p-4 border rounded-lg text-base bg-gray-700 border-gray-600 placeholder-gray-400 text-white focus:ring-blue-500 focus:border-blue-500" value={name} onChange={updateName} placeholder="Hatsune Mike" />
|
||||
<input type="text" id="name" className="w-full block p-4 border rounded-lg text-base dark:bg-neutral-900 border-gray-600 dark:placeholder-gray-400 dark:text-white focus:ring-blue-500 focus:border-blue-500" value={name} onChange={updateName} placeholder="Hatsune Mike" />
|
||||
</div>
|
||||
<div className="mb-5">
|
||||
<label className="block mb-2 text-sm font-medium text-white">
|
||||
<label className="block mb-2 text-sm font-medium dark:text-white">
|
||||
本文{" "}
|
||||
<span className="text-orange-400">*</span>
|
||||
</label>
|
||||
<textarea id="body" rows={4} className="font-serif text-2xl w-full block p-2.5 rounded-lg border bg-gray-700 border-gray-600 placeholder-gray-400 text-white focus:ring-blue-500 focus:border-blue-500" placeholder="言い残したいことは?" value={body} onChange={updateBody}></textarea>
|
||||
<textarea id="body" rows={4} className="font-serif text-2xl w-full block p-2.5 rounded-lg border dark:bg-neutral-900 border-gray-600 dark:placeholder-gray-400 dark:text-white focus:ring-blue-500 focus:border-blue-500" placeholder="言い残したいことは?" value={body} onChange={updateBody}></textarea>
|
||||
</div>
|
||||
<button
|
||||
onClick={submit}
|
||||
type="button"
|
||||
className={`w-full text-xl text-white focus:ring-4 focus:outline-none font-medium rounded-lg text-sm px-5 py-2.5 text-center bg-blue-600 hover:bg-blue-700 focus:ring-blue-800${ name === "" || body === "" ? " opacity-20" : ""}`}
|
||||
className={`w-full text-xl dark:text-white hover:text-white focus:ring-4 focus:outline-none font-medium rounded-lg text-sm px-5 py-2.5 text-center border border-2 border-blue-600 hover:bg-blue-700 focus:ring-blue-800${ name === "" || body === "" ? " opacity-20" : ""}`}
|
||||
disabled={name === "" || body === ""}
|
||||
>
|
||||
<FontAwesomeIcon icon={faPaperPlane} />{" "}送信
|
||||
@ -119,7 +119,7 @@ export default function Chat() {
|
||||
messages &&
|
||||
messages.map((message, index) => {
|
||||
return (
|
||||
<div key={index} className="p-6 border border-gray-200 rounded-lg shadow bg-gray-800 border-gray-700 mb-2">
|
||||
<div key={index} className="p-6 border border-gray-200 rounded-lg shadow border-gray-700 mb-2">
|
||||
<p className="font-medium opacity-80">
|
||||
{message.name} さん,{" "}
|
||||
{
|
||||
@ -134,7 +134,7 @@ export default function Chat() {
|
||||
{message.body.replace(/\$\$/g, "")}
|
||||
</InlineMath>
|
||||
:
|
||||
<Markdown className="prose prose-xl prose-invert">
|
||||
<Markdown className="prose prose-xl dark:prose-invert">
|
||||
{message.body}
|
||||
</Markdown>
|
||||
}
|
||||
|
@ -12,36 +12,37 @@ export const currentPage = atom({
|
||||
|
||||
export default function HorizontalMenu() {
|
||||
const [page, setPage] = useRecoilState(currentPage);
|
||||
const activeColor = " bg-slate-700 text-white"
|
||||
|
||||
return (
|
||||
<RecoilRoot>
|
||||
<div className="text-lg font-medium text-center hover:cursor-pointer grid grid-cols-5 grid-flow-col">
|
||||
<div
|
||||
className={`self-start py-3 rounded-lg ${page === Pages.Profile ? "bg-slate-700" : ""}`}
|
||||
className={`self-start py-3 rounded-lg${page === Pages.Profile ? activeColor : ""}`}
|
||||
onClick={() => {setPage(Pages.Profile)}}
|
||||
>
|
||||
<FontAwesomeIcon icon={faUser} />{" "}
|
||||
</div>
|
||||
<div
|
||||
className={`self-start py-3 rounded-lg ${page === Pages.Links ? "bg-slate-700" : ""}`}
|
||||
className={`self-start py-3 rounded-lg${page === Pages.Links ? activeColor : ""}`}
|
||||
onClick={() => {setPage(Pages.Links)}}
|
||||
>
|
||||
<FontAwesomeIcon icon={faLink} />{" "}
|
||||
</div>
|
||||
<div
|
||||
className={`self-start py-3 rounded-lg ${page === Pages.Keys ? "bg-slate-700" : ""}`}
|
||||
className={`self-start py-3 rounded-lg${page === Pages.Keys ? activeColor : ""}`}
|
||||
onClick={() => {setPage(Pages.Keys)}}
|
||||
>
|
||||
<FontAwesomeIcon icon={faKey} />{" "}
|
||||
</div>
|
||||
<div
|
||||
className={`self-start py-3 rounded-lg ${page === Pages.Services ? "bg-slate-700" : ""}`}
|
||||
className={`self-start py-3 rounded-lg${page === Pages.Services ? activeColor : ""}`}
|
||||
onClick={() => {setPage(Pages.Services)}}
|
||||
>
|
||||
<FontAwesomeIcon icon={faStar} />{" "}
|
||||
</div>
|
||||
<div
|
||||
className={`self-start py-3 rounded-lg ${page === Pages.Chat ? "bg-slate-700" : ""}`}
|
||||
className={`self-start py-3 rounded-lg${page === Pages.Chat ? activeColor : ""}`}
|
||||
onClick={() => {setPage(Pages.Chat)}}
|
||||
>
|
||||
<FontAwesomeIcon icon={faComments} />{" "}
|
||||
|
@ -5,8 +5,8 @@ export default function Keys() {
|
||||
return (
|
||||
<>
|
||||
<div className="rounded-lg w-full">
|
||||
<h2 className="text-xl font-semibold text-gray-200 mt-2 mb-1 ml-1">GNU Privacy Guard</h2>
|
||||
<ul className="max-w-md space-y-1 list-disc list-inside text-gray-300 ml-5">
|
||||
<h2 className="text-xl font-semibold dark:text-gray-200 mt-2 mb-1 ml-1">GNU Privacy Guard</h2>
|
||||
<ul className="max-w-md space-y-1 list-disc list-inside dark:text-gray-300 ml-5">
|
||||
<li>
|
||||
<a className="underline" href="https://github.com/yude.gpg">GitHub</a> <FontAwesomeIcon icon={faArrowUpRightFromSquare} /> から入手できます。
|
||||
</li>
|
||||
@ -15,8 +15,8 @@ export default function Keys() {
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 className="text-xl font-semibold text-gray-200 mt-2 mb-1 ml-1">The Secure Shell (RFC 4716)</h2>
|
||||
<ul className="max-w-md space-y-1 list-disc list-inside text-gray-300 ml-5">
|
||||
<h2 className="text-xl font-semibold dark:text-gray-200 mt-2 mb-1 ml-1">The Secure Shell (RFC 4716)</h2>
|
||||
<ul className="max-w-md space-y-1 list-disc list-inside dark:text-gray-300 ml-5">
|
||||
<li>
|
||||
<a className="underline" href="https://github.com/yude.keys">GitHub</a> <FontAwesomeIcon icon={faArrowUpRightFromSquare} /> から入手できます。
|
||||
</li>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,78 +1,69 @@
|
||||
export default function Mutuals() {
|
||||
const noImageBanner = `border border-4 inline-block border-lime-300 bg-slate-200 pt-1.5 w-fit px-3 text-black h-12 font-extrabold`
|
||||
const globalBanner = `h-12 inline`
|
||||
|
||||
return (
|
||||
<div className="text-center text-gray-500 mb-5">
|
||||
<a href="https://arkw.net">
|
||||
<img src="./mutual-links/arkwnet.png" className="h-12 inline" />
|
||||
<img src="./mutual-links/arkwnet.png" className={`${globalBanner}`} />
|
||||
</a>
|
||||
<a href="https://exout.net/~kirby3ds/">
|
||||
<img src="./mutual-links/kirby3ds.png" className="h-12 inline" />
|
||||
<img src="./mutual-links/kirby3ds.png" className={`${globalBanner}`} />
|
||||
</a>
|
||||
<a href="https://kris.fail">
|
||||
<img src="./mutual-links/kris_fail.png" className="h-12 inline" />
|
||||
<img src="./mutual-links/kris_fail.png" className={`${globalBanner}`} />
|
||||
</a>
|
||||
<a href="https://kusaremkn.com">
|
||||
<img src="./mutual-links/kusaremkn.webp" className="h-12 inline" />
|
||||
<img src="./mutual-links/kusaremkn.webp" className={`${globalBanner}`} />
|
||||
</a>
|
||||
<a href="https://nona-takahara.github.io/">
|
||||
<img src="./mutual-links/nona-takahara.png" className="h-12 inline" />
|
||||
<img src="./mutual-links/nona-takahara.png" className={`${globalBanner}`} />
|
||||
</a>
|
||||
<a href="https://www.pepepper.net">
|
||||
<img src="./mutual-links/pepepper.png" className="h-12 inline" />
|
||||
<img src="./mutual-links/pepepper.png" className={`${globalBanner}`} />
|
||||
</a>
|
||||
<a href="https://qqey.net">
|
||||
<img src="./mutual-links/qqeynet.png" className="h-12 inline" />
|
||||
<img src="./mutual-links/qqeynet.png" className={`${globalBanner}`} />
|
||||
</a>
|
||||
<a href="https://sasakulab.com">
|
||||
<img src="./mutual-links/sasakulab.png" className="h-12 inline" />
|
||||
<img src="./mutual-links/sasakulab.png" className={`${globalBanner}`} />
|
||||
</a>
|
||||
<a href="https://nullc.at/">
|
||||
<img src="./mutual-links/nullcat.png" className="h-12 inline" />
|
||||
<img src="./mutual-links/nullcat.png" className={`${globalBanner}`} />
|
||||
</a>
|
||||
<a href="https://yank-nvim.com/">
|
||||
<img src="./mutual-links/yank-nvim.png" className="h-12 inline" />
|
||||
<img src="./mutual-links/yank-nvim.png" className={`${globalBanner}`} />
|
||||
</a>
|
||||
<a href="https://zopfco.de/">
|
||||
<span
|
||||
className="w-32 h-12 bg-gray-500 text-black inline-block"
|
||||
style={{ paddingTop: `10px`}}>
|
||||
<span className={`${noImageBanner}`}>
|
||||
Zopfcode
|
||||
</span>
|
||||
</a>
|
||||
<a href="https://aoirint.com/">
|
||||
<span
|
||||
className="w-32 h-12 bg-gray-500 text-black inline-block"
|
||||
style={{ paddingTop: `10px`}}>
|
||||
<span className={`${noImageBanner}`}>
|
||||
aoirint
|
||||
</span>
|
||||
</a>
|
||||
<a href="https://fuku.day/">
|
||||
<span
|
||||
className="w-32 h-12 bg-gray-500 text-black inline-block"
|
||||
style={{ paddingTop: `10px`}}>
|
||||
<span className={`${noImageBanner}`}>
|
||||
Aumy
|
||||
</span>
|
||||
</a>
|
||||
<a href="https://haxibami.net">
|
||||
<span
|
||||
className="w-32 h-12 bg-gray-500 text-black inline-block"
|
||||
style={{ paddingTop: `10px`}}>
|
||||
<span className={`${noImageBanner}`}>
|
||||
mythfinder
|
||||
</span>
|
||||
</a>
|
||||
<a href="https://donabe8898.dev">
|
||||
<span
|
||||
className="w-32 h-12 bg-gray-500 text-black inline-block"
|
||||
style={{ paddingTop: `10px`}}>
|
||||
<span className={`${noImageBanner}`}>
|
||||
donabe8898.dev
|
||||
</span>
|
||||
</a>
|
||||
<a href="https://hieri.vercel.app">
|
||||
<img src="./mutual-links/hieri.png" className="h-12 inline" />
|
||||
<img src="./mutual-links/hieri.png" className={`${globalBanner}`} />
|
||||
</a>
|
||||
<a href="https://rz7.dev">
|
||||
<span
|
||||
className="w-32 h-12 bg-gray-500 text-black inline-block"
|
||||
style={{ paddingTop: `10px`}}>
|
||||
<span className={`${noImageBanner}`}>
|
||||
rz7.dev
|
||||
</span>
|
||||
</a>
|
||||
|
@ -5,35 +5,35 @@ export default function Profile() {
|
||||
return (
|
||||
<>
|
||||
<div className="rounded-lg w-full">
|
||||
<h2 className="text-xl font-semibold text-gray-200 mt-2 mb-1 ml-1">所属</h2>
|
||||
<h2 className="text-xl font-semibold dark:text-gray-200 mt-2 mb-1 ml-1">所属</h2>
|
||||
|
||||
<ol className="relative border-s border-gray-700 left-2">
|
||||
<li className="mb-2 ms-4">
|
||||
<div className="absolute w-3 h-3 bg-gray-200 rounded-full mt-1.5 -start-1.5 border border-gray-900 bg-gray-700"></div>
|
||||
<time className="mb-1 text-sm font-normal leading-none text-gray-400">
|
||||
<time className="mb-1 text-sm font-normal leading-none dark:text-gray-400">
|
||||
2020 年 4 月 – 現在
|
||||
</time>
|
||||
<h3 className="text-lg font-semibold text-white">
|
||||
<h3 className="text-lg font-semibold dark:text-white">
|
||||
<a href="https://www.hiroshima-cu.ac.jp">
|
||||
広島市立大学
|
||||
</a>
|
||||
</h3>
|
||||
<p className="text-base font-normal text-gray-400">
|
||||
<p className="text-base font-normal dark:text-gray-400">
|
||||
<a href="https://net.info.hiroshima-cu.ac.jp">
|
||||
情報ネットワーク研究室
|
||||
</a>
|
||||
</p>
|
||||
<p className="text-base font-normal text-gray-400">
|
||||
<p className="text-base font-normal dark:text-gray-400">
|
||||
<a href="https://funahcu.github.io/funalab">
|
||||
センシング講座, ネットワークソフトウェア研究グループ
|
||||
</a>
|
||||
</p>
|
||||
<p className="text-base font-normal text-gray-400">
|
||||
<p className="text-base font-normal dark:text-gray-400">
|
||||
<a href="http://www.cne.info.hiroshima-cu.ac.jp/">
|
||||
情報工学科
|
||||
</a>
|
||||
</p>
|
||||
<p className="text-base font-normal text-gray-400">
|
||||
<p className="text-base font-normal dark:text-gray-400">
|
||||
<a href="https://www2.info.hiroshima-cu.ac.jp/">
|
||||
情報科学部
|
||||
</a>
|
||||
@ -47,19 +47,20 @@ export default function Profile() {
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<h2 className="text-xl font-semibold text-gray-200 mt-2 mb-1 ml-1">基本情報</h2>
|
||||
<h2 className="text-xl font-semibold dark:text-gray-200 mt-2 mb-1 ml-1">基本情報</h2>
|
||||
|
||||
<ul className="space-y-1 list-inside mt-2 ml-5">
|
||||
<li className="items-center">
|
||||
<span className="text-gray-300"><FontAwesomeIcon icon={faCake} /> <span className="text-gray-50">2001 年 11 月 19 日</span> 生まれ (22 歳)</span>
|
||||
<span className="dark:text-gray-300"><FontAwesomeIcon icon={faCake} />
|
||||
<span className="dark:text-gray-50">2001 年 11 月 19 日</span> 生まれ (22 歳)</span>
|
||||
</li>
|
||||
<li className="items-center">
|
||||
<span className="text-gray-300"><FontAwesomeIcon icon={faMapPin} /> <span className="text-gray-50">広島県 広島市</span> 在住</span>
|
||||
<span className="dark:text-gray-300"><FontAwesomeIcon icon={faMapPin} /> <span className="dark:text-gray-50">広島県 広島市</span> 在住</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 className="text-xl font-semibold text-gray-200 mt-2 mb-1 ml-1">資格, 免許</h2>
|
||||
<ul className="max-w-md space-y-1 ml-5 list-disc list-inside text-gray-400">
|
||||
<h2 className="text-xl font-semibold dark:text-gray-200 mt-2 mb-1 ml-1">資格, 免許</h2>
|
||||
<ul className="max-w-md space-y-1 ml-5 list-disc list-inside dark:text-gray-400">
|
||||
<li>
|
||||
プロジェクトセカイ カラフルステージ! feat. 初音ミク フルコンボ楽曲 (MASTER) 200 曲 (2023 年 6 月)
|
||||
</li>
|
||||
|
@ -5,10 +5,10 @@ export default function Services() {
|
||||
return (
|
||||
<>
|
||||
<div className="rounded-lg w-full">
|
||||
<h2 className="text-xl font-semibold text-gray-200 mt-2 mb-1 ml-1">
|
||||
<h2 className="text-xl font-semibold dark:text-gray-200 mt-2 mb-1 ml-1">
|
||||
サービス
|
||||
</h2>
|
||||
<ul className="max-w-md space-y-1 ml-5 mt-3 list-disc list-inside text-gray-400">
|
||||
<ul className="max-w-md space-y-1 ml-5 mt-3 list-disc list-inside dark:text-gray-400">
|
||||
<li>
|
||||
<a className="hover:underline" href="https://soine.site">
|
||||
soine.site <FontAwesomeIcon icon={faArrowUpRightFromSquare} />
|
||||
@ -41,11 +41,11 @@ export default function Services() {
|
||||
<span>TeamSpeak 3 サーバ @ <code>yude.jp</code></span>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 className="text-xl font-semibold text-gray-200 mt-2 mb-1 ml-1">
|
||||
<h2 className="text-xl font-semibold dark:text-gray-200 mt-2 mb-1 ml-1">
|
||||
接続性
|
||||
</h2>
|
||||
<p className="text-gray-200 ml-3 -mb-1">閲覧にはそれぞれのプロトコルに対応したソフトウェアが必要です。</p>
|
||||
<ul className="max-w-md space-y-1 ml-5 mt-3 list-disc list-inside text-gray-400">
|
||||
<p className="dark:text-gray-200 ml-3 -mb-1">閲覧にはそれぞれのプロトコルに対応したソフトウェアが必要です。</p>
|
||||
<ul className="max-w-md space-y-1 ml-5 mt-3 list-disc list-inside dark:text-gray-400">
|
||||
<li>
|
||||
<a className="hover:underline" href="http://yudejpwxp2cziclocqjfd55ucw2dh6ncswopluh7exwusjlfkvkwhwqd.onion/">
|
||||
The Onion Router <FontAwesomeIcon icon={faArrowUpRightFromSquare} />
|
||||
|
@ -2,7 +2,7 @@ export default function Spotify() {
|
||||
return (
|
||||
<>
|
||||
<div className="rounded-lg w-full">
|
||||
<img alt="Spotify Recently Played" src="https://spotify-recently-played-readme.vercel.app/api?user=yude1119&width=400" width="563" height="495" />
|
||||
<img alt="Spotify Recently Played" src="https://spotify-recently-played-readme.vercel.app/api?user=yude1119&width=400" width="540" height="495" />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
79
src/components/Theme.tsx
Normal file
79
src/components/Theme.tsx
Normal file
@ -0,0 +1,79 @@
|
||||
import { atom, useRecoilState, useSetRecoilState } from "recoil";
|
||||
import { useEffect } from "react";
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import { faSun, faMoon } from '@fortawesome/free-solid-svg-icons'
|
||||
|
||||
export type Theme = "light" | "dark";
|
||||
|
||||
const themeState = atom<Theme>({
|
||||
key: "themeState",
|
||||
default: "light",
|
||||
});
|
||||
|
||||
export const useSetTheme = () => useSetRecoilState(themeState);
|
||||
|
||||
export const useTheme = () => {
|
||||
const [theme, setTheme] = useRecoilState(themeState);
|
||||
|
||||
const toggleTheme = () => {
|
||||
const newTheme = theme === "light" ? "dark" : "light";
|
||||
setTheme(newTheme);
|
||||
window.localStorage.setItem("theme", newTheme);
|
||||
const root = window.document.documentElement;
|
||||
root.setAttribute("data-theme", newTheme);
|
||||
root.setAttribute("data-bs-theme", newTheme);
|
||||
};
|
||||
|
||||
return { theme, toggleTheme };
|
||||
};
|
||||
|
||||
type Props = {
|
||||
children: JSX.Element;
|
||||
};
|
||||
|
||||
export const ThemeSwitcher = () => {
|
||||
const {theme, toggleTheme} = useTheme();
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-secondary"
|
||||
onClick={toggleTheme}
|
||||
>
|
||||
{theme === "light" ? (
|
||||
<FontAwesomeIcon icon={faMoon} />
|
||||
) : (
|
||||
<FontAwesomeIcon icon={faSun} />
|
||||
)}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
export const ThemeProvider = ({ children }: Props): JSX.Element => {
|
||||
const setTheme = useSetTheme();
|
||||
|
||||
useEffect(() => {
|
||||
const root = window.document.documentElement;
|
||||
|
||||
if (window.localStorage.getItem("theme")) {
|
||||
root.setAttribute("data-theme", window.localStorage.getItem("theme") || (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? "dark" : "light"));
|
||||
setTheme(window.localStorage.getItem("theme") as Theme);
|
||||
} else {
|
||||
const initialColorValue = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? "dark" : "light";
|
||||
root.setAttribute("data-theme", initialColorValue);
|
||||
setTheme(initialColorValue as Theme);
|
||||
window.localStorage.setItem("theme", initialColorValue);
|
||||
}
|
||||
}, [setTheme]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `!function(){let e;const t=window.localStorage.getItem("theme");if(null!==t)e=t;else{e=window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}document.documentElement.setAttribute("data-theme",e);document.documentElement.setAttribute("data-bs-theme",e)}();`,
|
||||
}}
|
||||
/>
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
};
|
@ -21,40 +21,41 @@ export const currentPage = atom({
|
||||
|
||||
export default function VerticalMenu() {
|
||||
const [page, setPage] = useRecoilState(currentPage);
|
||||
const activeColor = " bg-slate-700 text-white"
|
||||
|
||||
return (
|
||||
<RecoilRoot>
|
||||
<ul className="w-full text-lg font-medium text-center hover:cursor-pointer">
|
||||
<li
|
||||
className={`w-full px-4 py-2 rounded-lg${page === Pages.Profile ? " bg-slate-700" : ""}`}
|
||||
className={`w-full px-4 py-2 rounded-lg${page === Pages.Profile ? activeColor : ""}`}
|
||||
onClick={() => {setPage(Pages.Profile)}}
|
||||
>
|
||||
<FontAwesomeIcon icon={faUser} />{" "}
|
||||
<p>プロフィール</p>
|
||||
</li>
|
||||
<li
|
||||
className={`w-full px-4 py-2 rounded-lg${page === Pages.Links ? " bg-slate-700" : ""}`}
|
||||
className={`w-full px-4 py-2 rounded-lg${page === Pages.Links ? activeColor : ""}`}
|
||||
onClick={() => {setPage(Pages.Links)}}
|
||||
>
|
||||
<FontAwesomeIcon icon={faLink} />{" "}
|
||||
<p>リンク</p>
|
||||
</li>
|
||||
<li
|
||||
className={`w-full px-4 py-2 rounded-lg${page === Pages.Keys ? " bg-slate-700" : ""}`}
|
||||
className={`w-full px-4 py-2 rounded-lg${page === Pages.Keys ? activeColor : ""}`}
|
||||
onClick={() => {setPage(Pages.Keys)}}
|
||||
>
|
||||
<FontAwesomeIcon icon={faKey} />{" "}
|
||||
<p>公開鍵</p>
|
||||
</li>
|
||||
<li
|
||||
className={`w-full px-4 py-2 rounded-lg${page === Pages.Services ? " bg-slate-700" : ""}`}
|
||||
className={`w-full px-4 py-2 rounded-lg${page === Pages.Services ? activeColor : ""}`}
|
||||
onClick={() => {setPage(Pages.Services)}}
|
||||
>
|
||||
<FontAwesomeIcon icon={faStar} />{" "}
|
||||
<p>サービス</p>
|
||||
</li>
|
||||
<li
|
||||
className={`w-full px-4 py-2 rounded-lg${page === Pages.Chat ? " bg-slate-700" : ""}`}
|
||||
className={`w-full px-4 py-2 rounded-lg${page === Pages.Chat ? activeColor : ""}`}
|
||||
onClick={() => {setPage(Pages.Chat)}}
|
||||
>
|
||||
<FontAwesomeIcon icon={faComments} />{" "}
|
||||
|
@ -2,8 +2,11 @@
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
body {
|
||||
background-color: rgb(23 23 23);
|
||||
@layer base {
|
||||
body {
|
||||
@apply bg-zinc-200;
|
||||
@apply dark:bg-neutral-900;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes color-fill-anime {
|
||||
|
@ -1,5 +1,6 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
darkMode: ['class', '[data-theme="dark"]'],
|
||||
content: [
|
||||
"./index.html",
|
||||
"./src/**/*.{js,ts,jsx,tsx}",
|
||||
|
Loading…
x
Reference in New Issue
Block a user