0
0
mirror of https://github.com/yude-jp/yude.jp synced 2024-12-22 20:20:09 +09:00

Compare commits

..

37 Commits

Author SHA1 Message Date
ea617dd8dc
Fix 404 page @ minecraft/players/[uuid] 2021-09-26 13:36:23 +09:00
5276456ac2
Fix title during page loading 2021-09-26 13:24:10 +09:00
2b6ca4354d
Fix: loading implementation 2021-09-26 12:52:37 +09:00
7e7066317c
Remove console.log() for debug 2021-09-26 12:27:35 +09:00
3afef82031
Add yude.keys 2021-09-25 23:09:23 +09:00
4d0b82dee3
Update [uuid].js 2021-09-25 22:14:02 +09:00
c19e797fa4
Replace "class" to "className" 2021-09-25 21:53:57 +09:00
365559158d
Add group badge @ /minecraft/players/[uuid] 2021-09-25 21:51:35 +09:00
967c0f77af
Add biography on minecraft/players/[uuid] 2021-09-25 07:51:13 +09:00
85c649ddca
Update ja.md 2021-09-24 19:24:18 +09:00
3898a6951d
Avoid using toString() 2021-09-24 19:08:39 +09:00
7ad04ba8ef
Update export default name 2021-09-24 19:07:48 +09:00
e3e4cc5a5e
Fix page title @ /minecraft/players/[uuid] 2021-09-24 19:06:26 +09:00
a4982c7ef3
Fix: error handling on 404 2021-09-24 17:43:07 +09:00
c957d791a6
Update return format 2021-09-24 17:25:26 +09:00
971be8ab25
Replace "class" to "className" 2021-09-24 16:49:49 +09:00
eb46a60119
Remove weird comments 2021-09-24 16:49:07 +09:00
7629eb6c49
Implement basic user page for Minecraft server 2021-09-24 16:47:45 +09:00
f8357e2068
Add crafatar.com to trusted source of images 2021-09-24 16:47:27 +09:00
ee913461f1
Using next.config.js rewrite for UUID validation 2021-09-24 10:08:30 +09:00
b95c6b4cd5
[/minecraft/players/] Add basic function to retrieve player's data 2021-09-24 09:15:03 +09:00
b0b900cc10
Update comment 2021-09-24 08:10:26 +09:00
296e4d6298
Add redirects to Amazon wishlist, Scrapbox (via Next.js) 2021-09-22 08:23:29 +09:00
2c0bc0f5f6
Add unmet dependencies 2021-09-22 07:51:08 +09:00
73d159c1a6
Update packages 2021-09-22 07:46:38 +09:00
34df66d050
Fix: Do not pass children as props. 2021-09-22 07:43:10 +09:00
0258de61b0
Fix unused val, Add comments 2021-09-22 07:24:00 +09:00
958e9803fb
Fix typo 2021-09-22 07:19:34 +09:00
7ee5d348dd
Fix: avoid doing export default and val declare at the same time 2021-09-22 07:19:12 +09:00
24cf758cad
Add alt to images 2021-09-22 07:13:49 +09:00
a8186fb801
Enable Next.js lint 2021-09-22 07:13:44 +09:00
65fbb55a33
Add redirects to wishlist, Scrapbox 2021-09-22 07:09:49 +09:00
b59a6b6926
Add .vercel to .gitignore 2021-09-22 07:07:59 +09:00
623db08e1a
Merge pull request #10 from yudejp/dependabot/npm_and_yarn/nth-check-2.0.1
Bump nth-check from 2.0.0 to 2.0.1
2021-09-21 13:18:04 +09:00
dependabot[bot]
3a947d2932
Bump nth-check from 2.0.0 to 2.0.1
Bumps [nth-check](https://github.com/fb55/nth-check) from 2.0.0 to 2.0.1.
- [Release notes](https://github.com/fb55/nth-check/releases)
- [Commits](https://github.com/fb55/nth-check/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: nth-check
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-21 04:17:03 +00:00
yude
8f6953df10 Add server status for "saika" host 2021-09-21 13:16:09 +09:00
yude
3c7d783a9c Add link to my Amazon wishlist 2021-09-21 13:12:56 +09:00
35 changed files with 3118 additions and 1004 deletions

3
.eslintrc.json Normal file
View File

@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}

2
.gitignore vendored
View File

@ -11,3 +11,5 @@ yarn-error.log
.vimrc~
..vimrc.un~
.env.local
.vercel

View File

@ -1,13 +1,12 @@
このアカウントは**非公式**アカウントです。また、内容を保証するものではありません。
# 管理者
# 連絡先
広島市立大学 情報科学部 2年の [yude](https://yude.jp/profile) が管理しています。このアカウントについての連絡は下記までお願いします。
## 連絡先
* 電子メール: [admin@yude.jp](mailto:admin@yude.jp)
* Twitter: [@yude_jp](https://twitter.com/yude_jp)
# 稼働方法
Microsoft Power Automate によって広島市立大学WebページのRSSフィードを取得し、新しい記事が投稿されている場合にツイートします。\
# 仕組み
Microsoft Power Automate によって広島市立大学 Web ページの RSS フィードを取得し、新しい記事が投稿されている場合にツイートします。\
次の URL を監視しています。
* [お知らせ|広島市立大学](https://www.hiroshima-cu.ac.jp/news/)
* [お知らせ(在学生・保護者の方へ)|広島市立大学](https://www.hiroshima-cu.ac.jp/news_student/)

View File

@ -19,5 +19,6 @@
"fingerprint": "Digital fingerprint",
"view": "View",
"device": "Devices",
"account": "Accounts"
"account": "Accounts",
"wishlist": "Amazon Wishlist"
}

View File

@ -19,5 +19,6 @@
"fingerprint": "電子指紋",
"view": "閲覧",
"device": "デバイス",
"account": "アカウント"
"account": "アカウント",
"wishlist": "Amazon ほしいものリスト"
}

View File

@ -1,12 +1,25 @@
const nextTranslate = require('next-translate')
const rewrites = async () => {
return [
{
source: '/minecraft/players/:uuid(\[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})',
destination: '/minecraft/players/:uuid'
},
{
source: '/minecraft/players/:uuid',
destination: '/404'
}
]
}
module.exports = nextTranslate({
i18n: {
locales: ['ja', 'en'],
defaultLocale: 'ja',
},
images: {
domains: ['mackerel.io', 'mc-heads.net'],
domains: ['mackerel.io', 'mc-heads.net', 'crafatar.com'],
},
webpack: function (config) {
config.module.rules.push({
@ -15,4 +28,19 @@ module.exports = nextTranslate({
})
return config
},
async redirects() {
return [
{
source: '/wishlist',
destination: 'https://www.amazon.jp/hz/wishlist/ls/8WTKCPWKOJ2N?ref_=wl_share',
permanent: true,
},
{
source: '/scrapbox',
destination: 'https://scrapbox.io/yude',
permanent: true,
}
]
},
rewrites,
})

View File

@ -7,7 +7,8 @@
"dev": "next",
"build": "next build",
"start": "next start",
"export": "next export"
"export": "next export",
"lint": "next lint"
},
"repository": {
"type": "git",
@ -21,39 +22,43 @@
},
"homepage": "https://github.com/yudemoe/yude.jp#readme",
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.35",
"@fortawesome/free-brands-svg-icons": "^5.15.3",
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@fortawesome/react-fontawesome": "^0.1.14",
"@babel/core": "^7.15.5",
"@fortawesome/fontawesome-svg-core": "^1.2.36",
"@fortawesome/free-brands-svg-icons": "^5.15.4",
"@fortawesome/free-solid-svg-icons": "^5.15.4",
"@fortawesome/react-fontawesome": "^0.1.15",
"@tailwindcss/typography": "^0.4.0",
"autoprefixer": "^10.2.5",
"axios": "^0.21.1",
"autoprefixer": "^10.3.4",
"axios": "^0.21.4",
"microcms-js-sdk": "^1.2.0",
"moment": "^2.29.1",
"next": "^11.1.1",
"next-seo": "^4.26.0",
"next-themes": "^0.0.14",
"next-translate": "^1.0.7",
"next": "^11.1.2",
"next-seo": "^4.28.1",
"next-themes": "^0.0.15",
"next-translate": "^1.1.0",
"popper.js": "^1.16.1",
"postcss": "^8.3.0",
"postcss": "^8.3.6",
"prop-types": "^15.7.2",
"querystring": "^0.2.1",
"raw-loader": "^4.0.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-markdown": "^6.0.2",
"react-markdown": "^7.0.1",
"react-moment": "^1.1.1",
"react-switch": "^6.0.0",
"remark-gfm": "^1.0.0",
"swr": "^0.5.6",
"tailwindcss": "^2.1.4",
"remark-gfm": "^2.0.0",
"swr": "^1.0.1",
"tailwindcss": "^2.2.15",
"tailwindcss-filters": "^3.0.0",
"tailwindcss-responsive-embed": "^1.0.0",
"webpack": "^5.37.1"
"webpack": "^5.53.0"
},
"devDependencies": {
"@types/node": "^15.6.0",
"@types/react": "^17.0.6",
"@types/node": "^16.9.6",
"@types/react": "^17.0.24",
"babel-plugin-inline-react-svg": "^2.0.1",
"typescript": "^4.2.4"
"eslint": "7.32.0",
"eslint-config-next": "11.1.2",
"typescript": "^4.4.3"
}
}

View File

@ -0,0 +1,23 @@
// React
import React, { useState, useEffect } from 'react';
import axios from 'axios';
export const getName = async (props) => {
const uuid = props;
return fetch('https://api.ashcon.app/mojang/v2/user/' + uuid);
};
const RawPlayerName = async (req, res) => {
const { uuid } = req.query
const response = await getName(uuid);
const data = await response.json();
if (response.status === 204 || response.status > 400) {
return res.status(200).send("404");
}
const username = data.username;
return res.status(200).json({
username,
});
};
export default RawPlayerName

View File

@ -36,7 +36,7 @@ export const getNowPlaying = async () => {
});
};
export default async (_, res) => {
const Spotify = async (_, res) => {
const response = await getNowPlaying();
if (response.status === 204 || response.status > 400) {
@ -56,3 +56,5 @@ export default async (_, res) => {
title,
});
};
export default Spotify

View File

@ -27,7 +27,7 @@ function App (){
const yes_playing = t('yes_playing', {playing: data.members[0].game.name})
return <p>{yes_playing}</p>
}else{
return <p></p>
return <></>
}
}
};

View File

@ -10,6 +10,7 @@ const happybusy = (props) => {
src="/images/brstrip.gif"
width={150}
height={41}
alt="EFF Blue Ribbon Campaign"
/>
</a>
</Link>

View File

@ -10,6 +10,7 @@ const HappyBusy = (props) => {
src="/images/busy_banner.png"
width={200}
height={42}
alt="時間のないサイト運営者リング"
/>
</a>
</Link>

View File

@ -54,7 +54,7 @@ export default function Minecraft(props) {
url.push('https://mc-heads.net/avatar/' + data.players.list[i])
}
for (var i in url){
list.push(<Image src={url[i]} key={i} className="inline" height="50" width="50" />)
list.push(<Image src={url[i]} key={i} className="inline" height="50" width="50" alt={i}/>)
}
return <div>{list}</div>
}

View File

@ -0,0 +1,33 @@
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App (props) {
const uuid = props;
const [data, setData] = useState({ hits: [] });
useEffect(() => {
const fetchData = async () => {
const result = await axios(
'https://playersbio.yude.jp/' + uuid.uuid,
);
setData(result.data);
};
fetchData();
}, []);
if (data === undefined){
console.log("[Minecraft: PlayersBio] データの取得に失敗しました。 / Failed to retrieve data.")
return <p></p>
}else {
if (data.toString() == "[object Object]"){
return <p>読み込み中...</p>
} else {
if (data.toString() == "") {
return <p>ひとことは設定されていません...</p>
} else {
return <p>ひとこと: <span className="italic">{data.toString()}</span></p>
}
}
};
}
export default App;

View File

@ -0,0 +1,30 @@
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { useRouter } from 'next/router'
function App (props) {
const uuid = props;
const [data, setData] = useState({ hits: [] });
useEffect(() => {
const fetchData = async () => {
const result = await axios(
'https://minecraft.yude.jp/group/' + uuid.uuid,
);
setData(result.data);
};
fetchData();
}, []);
if (data === undefined || data === null){
return <p></p>
}else {
if (data.toString() == "staff") {
return <span className="inline-flex items-center justify-center px-3 py-2 text-base font-bold leading-none text-indigo-100 bg-indigo-700 rounded ml-3">Staff</span>
} else {
return <></>
}
};
}
export default App;

View File

@ -0,0 +1,16 @@
import React, { useState, useEffect } from 'react';
import Image from 'next/image'
function App (props) {
const uuid = props;
return (
<Image
src={"https://crafatar.com/renders/body/" + uuid.uuid}
width={110}
height={250}
/>
)
}
export default App;

View File

@ -0,0 +1,65 @@
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App (props) {
const uuid = props;
const [data, setData] = useState({ hits: [] });
const timeAgo = (prevDate) => {
const diff = Number(new Date()) - prevDate;
const minute = 60 * 1000;
const hour = minute * 60;
const day = hour * 24;
const month = day * 30;
const year = day * 365;
switch (true) {
case diff < minute:
const seconds = Math.round(diff / 1000);
return `${seconds} 秒前`
case diff < hour:
return Math.round(diff / minute) + ' 分前';
case diff < day:
return Math.round(diff / hour) + ' 時間前';
case diff < month:
return Math.round(diff / day) + ' 日前';
case diff < year:
return Math.round(diff / month) + ' ヶ月前';
case diff > year:
return Math.round(diff / year) + ' 年前';
default:
return "";
}
};
useEffect(() => {
const fetchData = async () => {
const result = await axios(
'https://minecraft.yude.jp/last/' + uuid.uuid,
);
setData(result.data);
};
fetchData();
}, []);
if (data === undefined){
console.log("[Minecraft: 最終プレイ日時] データの取得に失敗しました。 / Failed to retrieve data.")
return <p></p>
}else {
if (data.toString() == "[object Object]") {
return <p>取得中です...</p>
} else {
if (data.toString() == "not_found") {
return <></>
} else {
let dateTime = new Date(parseInt(data.toString()) * 1000);
return (
<div className='has-tooltip'>
<span className='tooltip rounded shadow-lg p-1 bg-gray-100 text-red-500 -mt-8'>{dateTime.toLocaleDateString() + " " + dateTime.toLocaleTimeString()}</span>
最終ログイン: {timeAgo(dateTime)}
</div>
)
}
}
};
}
export default App;

View File

@ -0,0 +1,39 @@
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import useTranslation from 'next-translate/useTranslation'
import { useRouter } from 'next/router'
import LastPlayed from './LastPlayed'
function App (props) {
const uuid = props;
const router = useRouter()
const { locale, locales, defaultLocale, pathname } = router
const { t, lang } = useTranslation("common")
const [data, setData] = useState({ hits: [] });
useEffect(() => {
const fetchData = async () => {
const result = await axios(
'https://minecraft.yude.jp/online/' + uuid.uuid,
);
setData(result.data);
};
fetchData();
}, []);
if (data === undefined){
console.log("[Minecraft: オンライン状況] データの取得に失敗しました。 / Failed to retrieve data.")
return <p></p>
}else {
if (data.toString() == "false") {
return <LastPlayed uuid={uuid.uuid} />
} else {
if (data.toString() == "true") {
return <p>オンライン</p>
} else {
return <p>取得中...</p>
}
}
};
}
export default App;

View File

@ -0,0 +1,35 @@
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App (props) {
const uuid = props;
const [data, setData] = useState({ hits: [] });
useEffect(() => {
const fetchData = async () => {
let result = null;
try {
result = await axios('https://api.ashcon.app/mojang/v2/user/' + uuid.uuid);
setData(result.data);
} catch (err) {
result = 404;
setData(result);
}
};
fetchData();
}, []);
if (data === undefined){
console.log("[Minecraft: UUID to player's name] データの取得に失敗しました。 / Failed to retrieve data.")
return <>取得中...</>
}else {
if (data === 404) {
return <>404</>
} else {
return (
<>{data.username}</>
)
}
};
}
export default App;

View File

@ -0,0 +1,39 @@
// Component
import Group from './Group';
// Data fetching
import useSwr from 'swr'
const fetcher = (url) => fetch(url).then((res) => res.json())
function App (props) {
const uuid = props;
const { data, error } = useSwr(
uuid.uuid ? `/api/PlayerName/${uuid.uuid}` : null,
fetcher
)
if (error) {
return (
<>エラーが発生しました</>
)
} else {
if (!data) {
return (
<>読み込み中...</>
)
} else {
return (
<>
<div className='has-tooltip'>
<span className='tooltip rounded shadow-lg p-1 bg-gray-100 text-red-500 -mt-8 font-mono text-sm'>UUID: {uuid.uuid}</span>
<p className="text-2xl inline">{data.username}</p>
<Group uuid={uuid.uuid} />
</div>
</>
)
}
}
}
export default App;

View File

@ -0,0 +1,25 @@
// Components
import Online from './Online'
import Head from './Head'
import PlayerNameHolder from './PlayerNameHolder'
import Biography from './Biography'
function App (props) {
const uuid = props;
return (
<div className="w-full flex flex-wrap">
<div>
<Head uuid={uuid.uuid} />
</div>
<div className="w-5"></div>
<div>
<p className="text-2xl text-mono"><PlayerNameHolder uuid={uuid.uuid} /></p>
<p><Online uuid={uuid.uuid} /></p>
<p><Biography uuid={uuid.uuid} /></p>
</div>
</div>
)
}
export default App;

View File

@ -0,0 +1,9 @@
function App (props) {
return (
<div className="text-center">
<h2>入力された UUID に該当するプレイヤーが見つかりませんでした</h2>
</div>
)
}
export default App;

View File

@ -25,7 +25,7 @@ function App () {
const status = data.artist + ' / ' + data.title
return <p>{t('listening', {listening: status})}</p>
}else{
return <p></p>
return <></>
}
};
}

View File

@ -1,15 +1,17 @@
// Base layout
import Layout from "./components/Layout"
// React, i18n
import useTranslation from 'next-translate/useTranslation'
import { useRouter } from 'next/router'
import React from "react"
import ReactMarkdown from "react-markdown"
// Markdown
import gfm from 'remark-gfm';
import ja from '../docs/hcunews/ja.md'
import en from '../docs/hcunews/en.md'
export default function Tos(props) {
const router = useRouter()
const { locale, locales, defaultLocale, pathname } = router
export default function HcuNews() {
const { t, lang } = useTranslation("hcunews")
return(
@ -17,9 +19,13 @@ export default function Tos(props) {
<div>
<h1>{t('hcunews')}</h1>
{lang === 'ja' ? (
<ReactMarkdown plugins={[gfm]} children={ja} />
<ReactMarkdown plugins={[gfm]}>
{ja}
</ReactMarkdown>
) : (
<ReactMarkdown plugins={[gfm]} children={en} />
<ReactMarkdown plugins={[gfm]}>
{en}
</ReactMarkdown>
)}
</div>
</Layout>

View File

@ -11,7 +11,7 @@ export default function About(props) {
<Layout title={t('house')}>
<div>
<p className="my-2 text-3xl text-center">{t('house')}</p>
<iframe className="w-full h-96" src="https://mackerel.io/embed/public/embed/4mVIU29WCRVZgHUxQPzWsfXo953uxiAegbjDb83hTQ7szesCunwdpVkBIzhnLc9i?period=1d" frameborder="0" scrolling="no"></iframe>
<iframe className="w-full h-96" src="https://mackerel.io/embed/public/embed/4mVIU29WCRVZgHUxQPzWsfXo953uxiAegbjDb83hTQ7szesCunwdpVkBIzhnLc9i?period=1d" frameBorder="0" scrolling="no"></iframe>
</div>
</Layout>
)

View File

@ -1,4 +1,4 @@
// Load base layout
// Base layout
import Layout from "./components/Layout"
// Menu

View File

@ -53,8 +53,7 @@ export default function About(props) {
<div className="w-full">
<Image
src = "/images/dynmap.png"
alt = "Dynmap Header"
unoptimized = {true}
alt = "Minecraft brief world map generated by Dynmap"
width = {1354}
height = {619}
/>
@ -88,11 +87,14 @@ export default function About(props) {
{/* Load markdown contents */}
{lang === 'ja' ? (
<ReactMarkdown plugins={[gfm]} children={ja} />
<ReactMarkdown plugins={[gfm]}>
{ja}
</ReactMarkdown>
) : (
<ReactMarkdown plugins={[gfm]} children={en} />
<ReactMarkdown plugins={[gfm]}>
{en}
</ReactMarkdown>
)}
</div>
</Layout>
</>

View File

@ -0,0 +1,59 @@
// Base layout
import Layout from "../../components/Layout"
// React
import { useRouter } from 'next/router'
// Data fetching
import Players from '../../components/Minecraft/Players'
import useSwr from 'swr'
const fetcher = (url) => fetch(url).then((res) => res.json())
// Components
import WrongUUID from '../../components/Minecraft/WrongUUID'
export default function UUID() {
const router = useRouter()
const { uuid } = router.query
const { data, error } = useSwr(
uuid ? `/api/PlayerName/${uuid}` : null,
fetcher
)
if (error) {
return (
<>
<Layout title="エラー - プレイヤー情報">
<p className="text-2xl">エラーが発生しました</p>
</Layout>
</>
)
} else {
if (!data) {
return (
<>
<Layout title="読み込み中... - プレイヤー情報">
<Players uuid={uuid} />
</Layout>
</>
)
} else {
if (!data.username) {
return (
<>
<Layout title="404 - プレイヤー情報">
<WrongUUID />
</Layout>
</>
)
} else {
return (
<>
<Layout title={data.username + " - " + "プレイヤー情報"}>
<Players uuid={uuid} />
</Layout>
</>
)
}
}
}
}

View File

@ -30,9 +30,13 @@ export default function Tos(props) {
<Layout title={t('common:mutual')}>
<div>
{lang === 'ja' ? (
<ReactMarkdown plugins={[gfm]} children={ja} />
<ReactMarkdown plugins={[gfm]}>
{ja}
</ReactMarkdown>
) : (
<ReactMarkdown plugins={[gfm]} children={en} />
<ReactMarkdown plugins={[gfm]}>
{en}
</ReactMarkdown>
)}
</div>
</Layout>

View File

@ -5,7 +5,7 @@ import Layout from "./components/Layout"
import useTranslation from 'next-translate/useTranslation'
// Font Awesome
import { faDiscord, faTwitter, faGithub, faKeybase, faInstagram, faMastodon, faSteam } from '@fortawesome/free-brands-svg-icons'
import { faDiscord, faTwitter, faGithub, faKeybase, faInstagram, faMastodon, faSteam, faAmazon } from '@fortawesome/free-brands-svg-icons'
import { faEnvelope, faBirthdayCake, faMapPin, faSchool, faPhone, faInfo, faLink, faMobile } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
@ -116,6 +116,7 @@ export default function Profile(props) {
<PublicKeys />
<Button dest="https://scrapbox.io/yude/%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88" icon={faLink} caption={t('account')}/>
<Button dest="https://scrapbox.io/yude/%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9" icon={faMobile} caption={t('device')}/>
<Button dest="https://www.amazon.jp/hz/wishlist/ls/8WTKCPWKOJ2N?ref_=wl_share" icon={faAmazon} caption={t('wishlist')}/>
</div>
</div>

View File

@ -43,6 +43,18 @@ export default function Server(props) {
</div>
<iframe className="w-full h-96" src="https://mackerel.io/embed/public/embed/heHnGhDanoIDlf7jjxUe9yPVrsG3deeH5ptD8suErrq5w46crWEIYdLfzLoukzfF?period=24h" height="400" frameBorder="0" scrolling="no"></iframe>
{
// saika
}
<h2 className="text-2xl text-left font-bold leading-7 sm:text-3xl sm:truncate">saika</h2>
<div className="flex xl:w-2/3 text-center">
<div className="flex-1"><p className="font-bold">CPU </p>i5-6500</div>
<div className="flex-1"><p className="font-bold">RAM </p>DDR4 8GB</div>
<div className="flex-1"><p className="font-bold">OS </p>Ubuntu Server 20.04.3 LTS</div>
<div className="flex-1"><p className="font-bold">{t('location')} </p>{t('hiroshima')}</div>
</div>
<iframe className="w-full h-96" src="https://mackerel.io/embed/public/embed/QCRK3wZxG7ufgunJ5iuIs9cIEJ490swAmlYMF50nNLmJw6gASXyVlzhrybiE2A1G?period=24h" height="400" frameBorder="0" scrolling="no"></iframe>
{
// yukino
}

View File

@ -15,9 +15,13 @@ export default function Tos(props) {
<Layout title={t('tos')}>
<div>
{lang === 'ja' ? (
<ReactMarkdown plugins={[gfm]} children={ja} />
<ReactMarkdown plugins={[gfm]}>
{ja}
</ReactMarkdown>
) : (
<ReactMarkdown plugins={[gfm]} children={en} />
<ReactMarkdown plugins={[gfm]}>
{en}
</ReactMarkdown>
)}
</div>
</Layout>

1
public/yude.keys Normal file
View File

@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDfEH46roc6pn97+Bi0UxWaeogvN38U5/7W+s2TWAQfpE8gv7ibFwZ5FVvHguT8BbCkK8YuXW7Oug1n8S6o3ABhUQD/zGIuEBLVKO6BTUYNDpYNxmmXKZ+dbB1nz++bvson8pYv/MdkeeeRrmqVgmrZzDifgBqYicGep+LKobhXvgCX6Qb9cHC9MCx+3mUzT0RhwwxEL/AsBm6f5oPJZdnF3agnOi61KA+wrK7RPU5v88HY5jHb87irFjNbc2xvyoLJmx+ILyKIcdsaADiTdy2JX5fqsO4S3WFELK+utw1MgBnGt0ENaev2Tce9r2QuUZQYNpa1+vAcdsc0qcR2W9wV

6
vercel.json Normal file
View File

@ -0,0 +1,6 @@
{
"redirects": [
{ "source": "/wishlist", "destination": "https://www.amazon.jp/hz/wishlist/ls/8WTKCPWKOJ2N?ref_=wl_share" },
{ "source": "/scrapbox", "destination": "https://scrapbox.io/yude" }
]
}

3554
yarn.lock

File diff suppressed because it is too large Load Diff