0
0
mirror of https://github.com/yude-jp/yude.jp synced 2025-10-17 05:38:36 +09:00

59 Commits

Author SHA1 Message Date
dependabot[bot]
8e1e6a6b4e Bump json5 from 1.0.1 to 1.0.2
Bumps [json5](https://github.com/json5/json5) from 1.0.1 to 1.0.2.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v1.0.1...v1.0.2)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-08 01:28:11 +00:00
79246ee600 Merge pull request #21 from yudejp/dependabot/npm_and_yarn/minimatch-3.1.2
Bump minimatch from 3.0.4 to 3.1.2
2023-03-08 10:27:47 +09:00
98ad910a9b Merge pull request #22 from yudejp/dependabot/npm_and_yarn/loader-utils-2.0.4
Bump loader-utils from 2.0.0 to 2.0.4
2023-03-08 10:27:38 +09:00
fc90f87285 Merge pull request #19 from yudejp/dependabot/npm_and_yarn/terser-5.14.2
Bump terser from 5.9.0 to 5.14.2
2023-03-08 10:27:27 +09:00
b07d6412ff Merge pull request #18 from yudejp/dependabot/npm_and_yarn/moment-2.29.4
Bump moment from 2.29.1 to 2.29.4
2023-03-08 10:27:14 +09:00
dependabot[bot]
6d6365c240 Bump loader-utils from 2.0.0 to 2.0.4
Bumps [loader-utils](https://github.com/webpack/loader-utils) from 2.0.0 to 2.0.4.
- [Release notes](https://github.com/webpack/loader-utils/releases)
- [Changelog](https://github.com/webpack/loader-utils/blob/v2.0.4/CHANGELOG.md)
- [Commits](https://github.com/webpack/loader-utils/compare/v2.0.0...v2.0.4)

---
updated-dependencies:
- dependency-name: loader-utils
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-16 03:22:55 +00:00
dependabot[bot]
1dd86ac2c8 Bump minimatch from 3.0.4 to 3.1.2
Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2.
- [Release notes](https://github.com/isaacs/minimatch/releases)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-10 18:24:43 +00:00
dependabot[bot]
496fe5ee4b Bump terser from 5.9.0 to 5.14.2
Bumps [terser](https://github.com/terser/terser) from 5.9.0 to 5.14.2.
- [Release notes](https://github.com/terser/terser/releases)
- [Changelog](https://github.com/terser/terser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/terser/terser/commits)

---
updated-dependencies:
- dependency-name: terser
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-20 04:01:00 +00:00
dependabot[bot]
cdcce3a39b Bump moment from 2.29.1 to 2.29.4
Bumps [moment](https://github.com/moment/moment) from 2.29.1 to 2.29.4.
- [Release notes](https://github.com/moment/moment/releases)
- [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/moment/moment/compare/2.29.1...2.29.4)

---
updated-dependencies:
- dependency-name: moment
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-08 09:16:19 +00:00
7f3a8f8230 Merge pull request #15 from yudejp/dependabot/npm_and_yarn/next-12.1.0
Bump next from 11.1.3 to 12.1.0
2022-02-19 14:50:46 +09:00
dependabot[bot]
fae52872f1 Bump next from 11.1.3 to 12.1.0
Bumps [next](https://github.com/vercel/next.js) from 11.1.3 to 12.1.0.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v11.1.3...v12.1.0)

---
updated-dependencies:
- dependency-name: next
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-17 21:07:17 +00:00
1c8bf364dd Merge pull request #14 from yudejp/dependabot/npm_and_yarn/follow-redirects-1.14.8
Bump follow-redirects from 1.14.7 to 1.14.8
2022-02-17 11:54:04 +09:00
dependabot[bot]
ef653ed749 Bump follow-redirects from 1.14.7 to 1.14.8
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.7 to 1.14.8.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.7...v1.14.8)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-15 12:14:34 +00:00
8deac1fede Merge pull request #12 from yudejp/dependabot/npm_and_yarn/follow-redirects-1.14.7
Bump follow-redirects from 1.14.4 to 1.14.7
2022-02-06 17:02:06 +09:00
3fb52ddcfa Merge pull request #13 from yudejp/dependabot/npm_and_yarn/nanoid-3.2.0
Bump nanoid from 3.1.25 to 3.2.0
2022-02-06 17:01:57 +09:00
dependabot[bot]
a36785dded Bump nanoid from 3.1.25 to 3.2.0
Bumps [nanoid](https://github.com/ai/nanoid) from 3.1.25 to 3.2.0.
- [Release notes](https://github.com/ai/nanoid/releases)
- [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ai/nanoid/compare/3.1.25...3.2.0)

---
updated-dependencies:
- dependency-name: nanoid
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-22 02:29:26 +00:00
c60270c1c6 Fix link to hidden services 2022-01-17 13:17:06 +09:00
1b7319617b Add link to metrics.torproject.org 2022-01-17 13:15:30 +09:00
dependabot[bot]
aa6f4417e7 Bump follow-redirects from 1.14.4 to 1.14.7
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.4 to 1.14.7.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.4...v1.14.7)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-15 08:15:43 +00:00
ae6c8aa9c9 Merge branch 'master' of https://github.com/yudejp/yude.jp 2022-01-06 07:56:17 +09:00
9389cc55f7 Add host oracle-a1-1, Replace iframe with img for reducing requests 2022-01-06 07:56:14 +09:00
ba0e41579a Fix close button on WakaTime.js 2022-01-06 07:49:45 +09:00
b35caef45c Fix icon size on LangSelector 2022-01-02 18:34:06 +09:00
7ac1c7199f Merge branch 'master' of https://github.com/yudejp/yude.jp 2022-01-02 18:18:39 +09:00
f697eb9b85 Fix Font Awesome icon size 2022-01-02 18:18:31 +09:00
16bb6398e4 Remove weird space 2022-01-02 18:18:25 +09:00
02b1adcf55 Add "contents" 2021-12-29 06:41:51 +09:00
34e335037c Not passing lang parameters on external links 2021-12-28 05:29:08 +09:00
0cb27e3cda Update Minecraft required version 2021-12-28 05:28:18 +09:00
92459e594f Fix TS3 2021-12-27 06:09:39 +09:00
c30312a46a Update en.md 2021-12-26 11:09:54 +09:00
5531b3a3bf Remove link to Tor & I2P from footer 2021-12-26 10:34:05 +09:00
f0cf3729a0 Merge branch 'master' of https://github.com/yudejp/yude.jp 2021-12-26 07:35:50 +09:00
ec530601b4 Add services/ 2021-12-26 07:35:41 +09:00
30547e3b81 Fix i18n tag 2021-12-26 06:58:15 +09:00
2529afa286 Update README.md 2021-12-23 18:16:55 +09:00
b62f95d483 Add links to Tor, I2P 2021-12-22 06:28:44 +09:00
2bd3b69da1 Update icon size 2021-12-12 07:15:34 +09:00
5a0e87d7d4 Update icon size 2021-12-11 21:40:26 +09:00
b6f427d605 Fix image centering 2021-12-11 21:32:51 +09:00
92bb8b995c Remove FreeSpeech banner 2021-12-11 21:32:42 +09:00
52c8cd8d1c Fix: Discord playing data fetching 2021-12-11 21:13:44 +09:00
22385a42c8 Ignore @next/next/no-img-element, react-hooks/exhaustive-deps 2021-12-11 21:13:29 +09:00
99f776b861 Avoid using next/image 2021-12-11 19:19:50 +09:00
24327251ee Remove .env.local.sample 2021-12-11 19:13:37 +09:00
1f7456db3c Fix misc errors 2021-12-11 19:07:11 +09:00
a8321b6c60 This <Link> does not need query 2021-12-11 19:03:47 +09:00
ff98956a10 Cleanup 2021-12-11 19:01:18 +09:00
db6855fbc6 Remove microCMS 2021-12-11 18:57:22 +09:00
b446a2ebae Prepare for SSG 2021-12-11 18:55:57 +09:00
86844984d2 Add .DS_Store to .gitignore 2021-12-11 18:55:39 +09:00
a72a778a03 WIP 2021-12-11 18:17:20 +09:00
d9559dd072 WIP 2021-12-11 18:07:22 +09:00
c856a34867 Add out to .gitignore 2021-12-11 07:15:52 +09:00
d3283b12b2 https://github.com/vercel/next.js/issues/28596 2021-12-11 07:15:37 +09:00
8513ee795f Cleanup 2021-12-11 06:58:32 +09:00
49bd87b276 Merge branch 'master' of https://github.com/yudejp/yude.jp 2021-12-11 06:47:47 +09:00
a095e20b6b Remove /api/PlayerName 2021-12-11 06:42:23 +09:00
33dbec3339 bye Fitbit 2021-12-11 06:32:00 +09:00
73 changed files with 778 additions and 2240 deletions

View File

@@ -1,5 +0,0 @@
SPOTIFY_CLIENT_ID=
SPOTIFY_CLIENT_SECRET=
SPOTIFY_REFRESH_TOKEN=
MICROCMS_API_KEY=

View File

@@ -1,3 +1,8 @@
{
"extends": "next/core-web-vitals"
"extends": "next/core-web-vitals",
"rules": {
"@next/next/no-document-import-in-page": "off",
"@next/next/no-img-element": "off",
"react-hooks/exhaustive-deps": "off"
}
}

3
.gitignore vendored
View File

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

View File

@@ -3,14 +3,11 @@
<img alt="Next JS" src="https://img.shields.io/badge/nextjs-%23000000.svg?style=for-the-badge&logo=next.js&logoColor=white"/>
<img alt="TailwindCSS" src="https://img.shields.io/badge/tailwindcss-%2338B2AC.svg?style=for-the-badge&logo=tailwind-css&logoColor=white"/>\
Source code of [yude.jp](https://yude.jp).\
Built with [Next.js](https://nextjs.org/) and [Tailwind CSS](https://tailwindcss.com/) and deployed on [Vercel](https://vercel.com).
Built with [Next.js](https://nextjs.org/) and [Tailwind CSS](https://tailwindcss.com/) and deployed to [Cloudflare Pages](https://pages.cloudflare.com/).
## Development
### Setup
1. Run `yarn`.
1. Copy `.env.local.sample` as `.env.local` and set value.
### Preview
* Run `yarn dev`.
1. Run `yarn` to install dependencies.
2. Run `yarn dev` to serve.
## License
This repository is provided under the MIT License.

23
docs/services/en.md Normal file
View File

@@ -0,0 +1,23 @@
# Available services on yude.jp
## Softwares
* [AutoMuteUs](https://github.com/denverquane/automuteus)\
Among Us helper; API: [`galactus.yude.jp`](https://galactus.yude.jp)
* [Nextcloud](https://nc.yude.jp)
* [Mastodon](https://mstdn.yude.jp)
* [Misskey](https://misskey.yude.jp)
* [Pleroma](https//pleroma.yude.jp)
* TeamSpeak 3: `yude.jp`
* [Gitea](https://git.yude.jp)
* [h5ai](https://files.yude.jp)
* [JMusicBot (forked)](https://discord.com/oauth2/authorize?client_id=429638220456656896&scope=bot&permissions=338963472)
* [Owncast](https://live.yude.jp)
* [Minecraft Server](https://yude.jp/minecraft)
## Anonymous communication
### Tor
* Relay: [yudejp](https://metrics.torproject.org/rs.html#details/CF762EF3C86B104C301511894547C72371F952A4)
* Hidden Service: [yude3mzscyufx5u3zup72ium7tgecy3bd67p7t6vqhaywvr7e2gqpcqd.onion](http://yude3mzscyufx5u3zup72ium7tgecy3bd67p7t6vqhaywvr7e2gqpcqd.onion)
### I2P
* Hidden Service: [yudejp.i2p/?i2paddresshelper=55ivoba6mo3mqlwvw5lqz7lchxqew2kh77kwkn5shefrj2dp3coq.b32.i2p](http://yudejp.i2p/?i2paddresshelper=55ivoba6mo3mqlwvw5lqz7lchxqew2kh77kwkn5shefrj2dp3coq.b32.i2p)

23
docs/services/ja.md Normal file
View File

@@ -0,0 +1,23 @@
# yude.jp で運用中のサービス
## ソフトウェア
* [AutoMuteUs](https://github.com/denverquane/automuteus)\
Among Us の自動ミュートボット; API: [`galactus.yude.jp`](https://galactus.yude.jp)
* [Nextcloud](https://nc.yude.jp)
* [Mastodon](https://mstdn.yude.jp)
* [Misskey](https://misskey.yude.jp)
* [Pleroma](https//pleroma.yude.jp)
* TeamSpeak 3: `yude.jp`
* [Gitea](https://git.yude.jp)
* [h5ai](https://files.yude.jp)
* [JMusicBot (フォーク)](https://discord.com/oauth2/authorize?client_id=429638220456656896&scope=bot&permissions=338963472)
* [Owncast](https://live.yude.jp)
* [Minecraft サーバー](https://yude.jp/minecraft)
## 秘匿化ネットワーク
### Tor
* リレー: [yudejp](https://metrics.torproject.org/rs.html#details/CF762EF3C86B104C301511894547C72371F952A4)
* Hidden Service: [yude3mzscyufx5u3zup72ium7tgecy3bd67p7t6vqhaywvr7e2gqpcqd.onion](http://yude3mzscyufx5u3zup72ium7tgecy3bd67p7t6vqhaywvr7e2gqpcqd.onion)
### I2P
* Hidden Service: [yudejp.i2p/?i2paddresshelper=55ivoba6mo3mqlwvw5lqz7lchxqew2kh77kwkn5shefrj2dp3coq.b32.i2p](http://yudejp.i2p/?i2paddresshelper=55ivoba6mo3mqlwvw5lqz7lchxqew2kh77kwkn5shefrj2dp3coq.b32.i2p)

View File

@@ -1,15 +0,0 @@
{
"locales": ["en", "ja"],
"defaultLocale": "ja",
"pages": {
"*": ["common"],
"/": ["index", "minecraft", "common"],
"/profile": ["profile", "common"],
"/server": ["server", "common"],
"/house": ["house", "common"],
"/tos": ["tos", "common"],
"/hcunews": ["hcunews", "common"],
"/minecraft": ["minecraft", "common"],
"/404": ["404", "common"]
}
}

12
i18n/index.js Normal file
View File

@@ -0,0 +1,12 @@
var ja = require('./translations.ja.json');
var en = require('./translations.en.json')
const i18n = {
translations: {
ja: ja,
en: en,
},
defaultLang: 'ja'
}
module.exports = i18n;

67
i18n/translations.en.json Normal file
View File

@@ -0,0 +1,67 @@
{
"caption": "The requested page does not exist on this website.",
"return": "Return to top",
"footer": "This page is provided under the MIT License.",
"source": "Source code",
"tos": "yude.jp Terms of Service",
"yes_playing": "Playing {{playing}}",
"listening": "Listening to {{listening}}",
"close": "Close",
"mutual": "Mutual links",
"status": "Service Status",
"icon_1": "Icon: ",
"icon_2": " ",
"post_list": "Posts listing",
"hcunews": "About @hcunews",
"house": "yude's house",
"home": "Home",
"profile": "yude's profile",
"blog": "yude's blog",
"status": "yude.jp Server Status",
"house": "yude's house",
"discord": "yude.jp Discord Server",
"mastodon": "Mastodon instance",
"title": "Minecraft Multiplayer",
"playing": "{{count}} player(s) online.",
"no_one": "No one is playing.",
"offline": "Server is down.",
"address": "Server address",
"fail": "Failed to retrieve server status.",
"loading": "Retrieving server status...",
"version": "Version",
"about": "About yude",
"desc": "Description",
"school": "Faculty of Information Science, Hiroshima City University.",
"hiroshima": "Hiroshima, Japan",
"location": "Location",
"link": "Links",
"link_all": "To see all of yude's account, please visit ",
"link_all_late": ".",
"here": "here",
"mail": "E-mail",
"birth": "Birthday",
"date": "November the 19th, 2001",
"contact": "Accounts",
"belongs": "Organization",
"grade": "B2",
"keys": "Public keys",
"download": "Download",
"fingerprint": "Digital fingerprint",
"view": "View",
"device": "Devices",
"account": "Accounts",
"wishlist": "Amazon Wishlist",
"status": "Server Status",
"location": "Location",
"tottori": "Tottori, Japan",
"hiroshima": "Hiroshima, Japan",
"model": "Model",
"region": "Region",
"service": "Service",
"shape": "Shape",
"tos": "yude.jp Terms of Service",
"input": "en",
"services": "Services",
"contents": "Contents",
"Blog": "Weblog"
}

67
i18n/translations.ja.json Normal file
View File

@@ -0,0 +1,67 @@
{
"caption": "要求されたページはこのウェブサイト上に存在しません。",
"return": "トップページへ戻る",
"footer": "このページは MIT License のもと提供されています。",
"source": "ソースコード",
"tos": "yude.jp サービス利用規約",
"yes_playing": "{{playing}} をプレイ中",
"listening": "{{listening}} を再生中",
"close": "閉じる",
"mutual": "相互リンク",
"status": "サービスの状態",
"icon_1": "アイコン: ",
"icon_2": "さん",
"post_list": "記事一覧",
"hcunews": "@hcunews について",
"house": "ゆでハウス",
"home": "ホーム",
"profile": "yude のプロフィール",
"blog": "yude のブログ",
"status": "yude.jp サーバー情報",
"house": "ゆでハウス",
"discord": "yude.jp Discord サーバー",
"mastodon": "Mastodon インスタンス",
"title": "Minecraft マルチプレイ",
"playing": "{{count}} 人がプレイしています。",
"no_one": "現在、誰もログインしていません。",
"offline": "サーバーがオフラインのようです。",
"address": "サーバー アドレス",
"fail": "サーバーの状態を取得できませんでした。",
"loading": "サーバーの状態を取得しています...",
"version": "バージョン",
"about": "yude について",
"desc": "概要",
"school": "広島市立大学 情報科学部",
"hiroshima": "日本, 広島県",
"location": "所在地",
"link": "リンク",
"link_all": "yude が所持しているすべてのアカウントの一覧は、",
"link_all_late": "にあります。",
"here": "こちら",
"mail": "メール",
"birth": "生年月日",
"date": "2001年11月19日",
"contact": "アカウント",
"belongs": "所属",
"grade": "2年",
"keys": "公開鍵",
"download": "ダウンロード",
"fingerprint": "電子指紋",
"view": "閲覧",
"device": "デバイス",
"account": "アカウント",
"wishlist": "Amazon ほしいものリスト",
"status": "サーバー情報",
"location": "場所",
"tottori": "日本, 鳥取県",
"hiroshima": "日本, 広島県",
"model": "モデル",
"region": "リージョン",
"service": "サービス",
"shape": "シェイプ",
"tos": "yude.jp サービス利用規約",
"input": "ja",
"services": "サービス",
"contents": "コンテンツ",
"blog": "ブログ"
}

View File

@@ -1,6 +0,0 @@
import { createClient } from 'microcms-js-sdk';
export const client = createClient({
serviceDomain: 'yude',
apiKey: process.env.MICROCMS_API_KEY,
});

View File

@@ -1,4 +0,0 @@
{
"caption": "The requested page does not exist on this website.",
"return": "Return to top"
}

View File

@@ -1,13 +0,0 @@
{
"footer": "This page is provided under the MIT License.",
"source": "Source code",
"tos": "yude.jp Terms of Service",
"yes_playing": "Playing {{playing}}",
"listening": "Listening to {{listening}}",
"close": "Close",
"mutual": "Mutual links",
"status": "Service Status",
"icon_1": "Icon: ",
"icon_2": "",
"post_list": "Posts listing"
}

View File

@@ -1,3 +0,0 @@
{
"hcunews": "About @hcunews"
}

View File

@@ -1,3 +0,0 @@
{
"house": "yude's house"
}

View File

@@ -1,9 +0,0 @@
{
"home": "Home",
"profile": "yude's profile",
"blog": "yude's blog",
"status": "yude.jp Server Status",
"house": "yude's house",
"discord": "yude.jp Discord Server",
"mastodon": "Mastodon instance"
}

View File

@@ -1,10 +0,0 @@
{
"title": "Minecraft Multiplayer",
"playing": "{{count}} player(s) online.",
"no_one": "No one is playing.",
"offline": "Server is down.",
"address": "Server address",
"fail": "Failed to retrieve server status.",
"loading": "Retrieving server status...",
"version": "Version"
}

View File

@@ -1,24 +0,0 @@
{
"about": "About yude",
"desc": "Description",
"school": "Faculty of Information Science, Hiroshima City University.",
"hiroshima": "Hiroshima, Japan",
"location": "Location",
"link": "Links",
"link_all": "To see all of yude's account, please visit ",
"link_all_late": ".",
"here": "here",
"mail": "E-mail",
"birth": "Birthday",
"date": "November the 19th, 2001",
"contact": "Accounts",
"belongs": "Organization",
"grade": "B2",
"keys": "Public keys",
"download": "Download",
"fingerprint": "Digital fingerprint",
"view": "View",
"device": "Devices",
"account": "Accounts",
"wishlist": "Amazon Wishlist"
}

View File

@@ -1,10 +0,0 @@
{
"status": "Server Status",
"location": "Location",
"tottori": "Tottori, Japan",
"hiroshima": "Hiroshima, Japan",
"model": "Model",
"region": "Region",
"service": "Service",
"shape": "Shape"
}

View File

@@ -1,4 +0,0 @@
{
"tos": "yude.jp Terms of Service",
"input": "en"
}

View File

@@ -1,4 +0,0 @@
{
"caption": "要求されたページはこのウェブサイト上に存在しません。",
"return": "トップページへ戻る"
}

View File

@@ -1,13 +0,0 @@
{
"footer": "このページは MIT License のもと提供されています。",
"source": "ソースコード",
"tos": "yude.jp サービス利用規約",
"yes_playing": "{{playing}} をプレイ中",
"listening": "{{listening}} を再生中",
"close": "閉じる",
"mutual": "相互リンク",
"status": "サービスの状態",
"icon_1": "アイコン: ",
"icon_2": "さん",
"post_list": "記事一覧"
}

View File

@@ -1,3 +0,0 @@
{
"hcunews": "@hcunews について"
}

View File

@@ -1,3 +0,0 @@
{
"house": "ゆでハウス"
}

View File

@@ -1,9 +0,0 @@
{
"home": "ホーム",
"profile": "yude のプロフィール",
"blog": "yude のブログ",
"status": "yude.jp サーバー情報",
"house": "ゆでハウス",
"discord": "yude.jp Discord サーバー",
"mastodon": "Mastodon インスタンス"
}

View File

@@ -1,10 +0,0 @@
{
"title": "Minecraft マルチプレイ",
"playing": "{{count}} 人がプレイしています。",
"no_one": "現在、誰もログインしていません。",
"offline": "サーバーがオフラインのようです。",
"address": "サーバー アドレス",
"fail": "サーバーの状態を取得できませんでした。",
"loading": "サーバーの状態を取得しています...",
"version": "バージョン"
}

View File

@@ -1,24 +0,0 @@
{
"about": "yude について",
"desc": "概要",
"school": "広島市立大学 情報科学部",
"hiroshima": "日本, 広島県",
"location": "所在地",
"link": "リンク",
"link_all": "yude が所持しているすべてのアカウントの一覧は、",
"link_all_late": "にあります。",
"here": "こちら",
"mail": "メール",
"birth": "生年月日",
"date": "2001年11月19日",
"contact": "アカウント",
"belongs": "所属",
"grade": "2年",
"keys": "公開鍵",
"download": "ダウンロード",
"fingerprint": "電子指紋",
"view": "閲覧",
"device": "デバイス",
"account": "アカウント",
"wishlist": "Amazon ほしいものリスト"
}

View File

@@ -1,10 +0,0 @@
{
"status": "サーバー情報",
"location": "場所",
"tottori": "日本, 鳥取県",
"hiroshima": "日本, 広島県",
"model": "モデル",
"region": "リージョン",
"service": "サービス",
"shape": "シェイプ"
}

View File

@@ -1,4 +0,0 @@
{
"tos": "yude.jp サービス利用規約",
"input": "ja"
}

View File

@@ -1,5 +1,3 @@
const nextTranslate = require('next-translate')
const rewrites = async () => {
return [
{
@@ -13,11 +11,7 @@ const rewrites = async () => {
]
}
module.exports = nextTranslate({
i18n: {
locales: ['ja', 'en'],
defaultLocale: 'ja',
},
module.exports = {
images: {
domains: ['mackerel.io', 'mc-heads.net', 'crafatar.com'],
},
@@ -43,4 +37,4 @@ module.exports = nextTranslate({
]
},
rewrites,
})
}

View File

@@ -31,12 +31,12 @@
"autoprefixer": "^10.3.4",
"axios": "^0.21.4",
"date-fns": "^2.24.0",
"microcms-js-sdk": "^1.2.0",
"moment": "^2.29.1",
"next": "^11.1.3",
"moment": "^2.29.4",
"next": "^12.1.0",
"next-export-i18n": "^1.2.1",
"next-seo": "^4.28.1",
"next-themes": "^0.0.15",
"next-translate": "^1.1.0",
"next-translate": "^1.2.0",
"popper.js": "^1.16.1",
"postcss": "^8.3.6",
"prop-types": "^15.7.2",

View File

@@ -1,29 +0,0 @@
// Base layout
import Layout from "./components/Layout"
// React Router
import { useRouter } from 'next/router'
// Next.js
import Link from 'next/link'
import useTranslation from 'next-translate/useTranslation'
export default function Custom404(props) {
const router = useRouter()
const { locale, locales, defaultLocale, pathname } = router
const { t, lang } = useTranslation("404")
return (
<Layout title="404">
<div className="text-center mb-10 mt-10">
<p className="text-3xl">404</p>
<p className="text-xl">{t('caption')}</p>
<Link href="/">
<a>
<p className="mt-5">{t('return')}</p>
</a>
</Link>
</div>
</Layout>
)
}

View File

@@ -1,44 +0,0 @@
// React
import { format } from 'date-fns'
const {
FITBIT_TOKEN: bearer
} = process.env;
const today = format(new Date(), 'yyyy-MM-dd')
export const getName = async (props) => {
const uuid = props;
return fetch(
'https://api.fitbit.com/1/user/-/activities/heart/date/today/1d/1sec/time/00:00/23:59.json',
{
headers: {
Authorization: `Bearer ${bearer}`,
},
}
);
};
const FitbitHeartrate = 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 heartrate = data.map((item, i) => {
// if (item.dateTime = today) {
// return item
// } else {
// return "Failed to retrieve data."
// }
// }
// )
const array = data["activities-heart-intraday"].dataset
const heartrate = array[array.length - 1]
return res.status(200).json({
heartrate,
});
};
export default FitbitHeartrate

View File

@@ -1,35 +0,0 @@
// React
import { format } from 'date-fns'
const {
FITBIT_TOKEN: bearer
} = process.env;
const today = format(new Date(), 'yyyy-MM-dd')
export const getName = async (props) => {
const uuid = props;
return fetch(
'https://api.fitbit.com/1.2/user/-/sleep/date/' + today + '.json',
{
headers: {
Authorization: `Bearer ${bearer}`,
},
}
);
};
const FitbitSleep = 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 duration = data.summary.totalMinutesAsleep
return res.status(200).json({
duration,
});
};
export default FitbitSleep

View File

@@ -1,23 +0,0 @@
// 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

@@ -1,60 +0,0 @@
import querystring from 'querystring';
const {
SPOTIFY_CLIENT_ID: client_id,
SPOTIFY_CLIENT_SECRET: client_secret,
SPOTIFY_REFRESH_TOKEN: refresh_token,
} = process.env;
const basic = Buffer.from(`${client_id}:${client_secret}`).toString('base64');
const NOW_PLAYING_ENDPOINT = `https://api.spotify.com/v1/me/player/currently-playing`;
const TOKEN_ENDPOINT = `https://accounts.spotify.com/api/token`;
const getAccessToken = async () => {
const response = await fetch(TOKEN_ENDPOINT, {
method: 'POST',
headers: {
Authorization: `Basic ${basic}`,
'Content-Type': 'application/x-www-form-urlencoded',
},
body: querystring.stringify({
grant_type: 'refresh_token',
refresh_token,
}),
});
return response.json();
};
export const getNowPlaying = async () => {
const { access_token } = await getAccessToken();
return fetch(NOW_PLAYING_ENDPOINT, {
headers: {
Authorization: `Bearer ${access_token}`,
},
});
};
const Spotify = async (_, res) => {
const response = await getNowPlaying();
if (response.status === 204 || response.status > 400) {
return res.status(200).json({ isPlaying: false });
}
const song = await response.json();
const isPlaying = song.is_playing;
const title = song.item.name;
const artist = song.item.artists.map((_artist) => _artist.name).join(', ');
const album = song.item.album.name;
return res.status(200).json({
album,
artist,
isPlaying,
title,
});
};
export default Spotify

View File

@@ -1,44 +1,38 @@
// React
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import useTranslation from 'next-translate/useTranslation'
import { useRouter } from 'next/router'
function App (){
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://discord.com/api/guilds/723409709306216498/widget.json',
);
setData(result.data);
};
fetchData();
}, []);
if (data === undefined){
console.log("[Discord API] データの取得に失敗しました。 / Failed to retrieve data.")
return <p></p>
}else{
const str = JSON.stringify(data)
// Data fetching
import useSwr from 'swr'
const fetcher = (url) => fetch(url).then((res) => res.json())
// i18n
import { useTranslation, useLanguageQuery } from 'next-export-i18n';
export default function DiscordPlaying() {
const { t } = useTranslation();
const [query] = useLanguageQuery();
if (str.indexOf("game") !== -1){
const yes_playing = t('yes_playing', {playing: data.members[0].game.name})
return <p>{yes_playing}</p>
}else{
return <></>
}
const { data, error } = useSwr(
`https://discord.com/api/guilds/723409709306216498/widget.json`,
fetcher
)
if (error){
console.log("[Discord API] データの取得に失敗しました。 / Failed to retrieve data.")
return <></>
} else {
if (!data) {
return <p>Loading...</p>
} else {
if (data.members) {
if (data.members[0].game) {
const yes_playing = t('yes_playing', {playing: data.members[0].game.name})
return <p>{yes_playing}</p>
} else {
return <></>
}
} else {
return <></>
}
}
}
};
export async function getServerSideProps() {
// Fetch data from external API
const res = await fetch(url)
const data = await res.json()
// Pass data to the page via props
return { props: { data } }
}
export default App;

View File

@@ -1,4 +1,7 @@
// React
import React, { useState, useEffect } from 'react';
// Data fetching
import axios from 'axios';
const App = () => {

View File

@@ -1,38 +0,0 @@
// Data fetching
import useSwr from 'swr'
// Font Awesome
import { faHeartbeat } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
// Data fetching implements
const fetcher = (url) => fetch(url).then((res) => res.json())
function App (props) {
const { data, error } = useSwr(
'/api/Fitbit/Heartrate',
fetcher
)
if (error) {
return (
<>エラーが発生しました</>
)
} else {
if (!data) {
return (
<>読み込み中...</>
)
} else {
return (
<>
<FontAwesomeIcon icon={faHeartbeat} className="w-5 h-5 inline ml-3"/>
&nbsp;
{data.heartrate.value}
</>
)
}
}
}
export default App;

View File

@@ -1,44 +0,0 @@
// Data fetching
import useSwr from 'swr'
// Font Awesome
import { faBed } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
// Data fetching implements
const fetcher = (url) => fetch(url).then((res) => res.json())
function App (props) {
const { data, error } = useSwr(
'/api/Fitbit/Sleep',
fetcher
)
if (error) {
return (
<>エラーが発生しました</>
)
} else {
if (!data) {
return (
<>読み込み中...</>
)
} else {
const duration = data.duration
const hours = Math.floor(duration / 60)
let minutes = duration % 60
if (minutes <= 9) {
minutes = '0' + minutes
}
return (
<>
<FontAwesomeIcon icon={faBed} className="w-5 h-5 inline"/>
&nbsp;
{hours}:{minutes}
</>
)
}
}
}
export default App;

View File

@@ -1,20 +0,0 @@
// Next.js
import Link from 'next/link'
import Image from 'next/image'
const happybusy = (props) => {
return (
<Link href="https://www.eff.org/pages/blue-ribbon-campaign">
<a>
<Image
src="/images/brstrip.gif"
width={150}
height={41}
alt="EFF Blue Ribbon Campaign"
/>
</a>
</Link>
)
}
export default happybusy

View File

@@ -1,13 +1,15 @@
// Tailwind CSS
import "tailwindcss/tailwind.css";
import Link from 'next/link';
import useTranslation from 'next-translate/useTranslation'
import { useRouter } from 'next/router'
export default function Footer(props) {
const router = useRouter()
const { locale, locales, defaultLocale, pathname } = router
const { t, lang } = useTranslation("common")
// Next.js
import Link from 'next/link';
// i18n
import { useTranslation, useLanguageQuery } from 'next-export-i18n';
export default function Footer(props) {
const { t } = useTranslation();
const [query] = useLanguageQuery();
return (
<>
<div className="container mx-auto px-6">

View File

@@ -1,16 +1,16 @@
// Next.js
import Link from 'next/link'
import Image from 'next/image'
const HappyBusy = (props) => {
return (
<Link href="https://sites.google.com/site/happybusy/">
<a>
<Image
<img
src="/images/busy_banner.png"
width={200}
height={42}
alt="時間のないサイト運営者リング"
className="mx-auto"
/>
</a>
</Link>

View File

@@ -1,14 +1,14 @@
import React from "react";
import Popper from "popper.js";
import { useRouter } from 'next/router'
import Link from 'next/link';
import { faLanguage } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
const Dropdown = ({ color }) => {
const router = useRouter()
const { locale, locales, defaultLocale, pathname } = router
// i18n
import { useTranslation, useLanguageQuery, LanguageSwitcher } from 'next-export-i18n';
const Dropdown = ({ color }) => {
// dropdown props
const [dropdownPopoverShow, setDropdownPopoverShow] = React.useState(false);
const btnDropdownRef = React.createRef();
@@ -31,7 +31,7 @@ const Dropdown = ({ color }) => {
<>
<div className="text-left mr-2 ml-2 my-3 float-right">
<button type="button" className="inline-flex justify-center w-full rounded-md border border-gray-300 dark:border-gray-800 shadow-sm px-2 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50 dark:bg-gray-700 dark:text-white focus:outline-none" id="options-menu" aria-haspopup="true" aria-expanded="true"
<button type="button" className="inline-flex justify-center rounded-md border border-gray-300 dark:border-gray-800 shadow-sm px-2 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50 dark:bg-gray-700 dark:text-white focus:outline-none h-10" id="options-menu" aria-haspopup="true" aria-expanded="true"
style={{ transition: "all .15s ease" }}
ref={btnDropdownRef}
onClick={() => {
@@ -40,20 +40,20 @@ const Dropdown = ({ color }) => {
: openDropdownPopover();
}}
>
<FontAwesomeIcon icon={faLanguage} className="w-12 h-9" />
<FontAwesomeIcon icon={faLanguage} size="3x" />
<svg className="-mr-1 ml-2 h-9 w-3" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path fillRule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clipRule="evenodd" />
</svg>
</button>
<div ref={popoverDropdownRef} className={
(dropdownPopoverShow ? "block " : "hidden ") + "z-10 origin-top-right absolute right-0 mt-2 w-40 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 dark:bg-gray-700"}>
(dropdownPopoverShow ? "block " : "hidden ") + "z-10 origin-top-right absolute right-0 mt-2 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 dark:bg-gray-700"}>
<div className="py-1" role="menu" aria-orientation="vertical" aria-labelledby="options-menu">
<Link href="#" locale="ja">
<a href="#" className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-700 dark:text-white dark:hover:bg-gray-800" role="menuitem">日本語</a>
</Link>
<Link href="#" locale="en">
<a href="#" className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-700 dark:text-white dark:hover:bg-gray-800" role="menuitem">English</a>
</Link>
<LanguageSwitcher lang="ja">
<a href="#" className="block px-4 py-2 text-gray-700 hover:bg-gray-100 hover:text-gray-700 dark:text-white dark:hover:bg-gray-800" role="menuitem">日本語</a>
</LanguageSwitcher>
<LanguageSwitcher lang="en">
<a href="#" className="block px-4 py-2 text-gray-700 hover:bg-gray-100 hover:text-gray-700 dark:text-white dark:hover:bg-gray-800" role="menuitem">English</a>
</LanguageSwitcher>
</div>
</div>
</div>

View File

@@ -1,21 +1,19 @@
// Next.js
import Head from "next/head"
// Tailwind CSS
import "tailwindcss/tailwind.css";
import useTranslation from 'next-translate/useTranslation'
import { useRouter } from 'next/router'
// React
import React, { useEffect, useState } from 'react'
// Components
import Footer from "./Footer/Footer"
import Navbar from "./Navbar"
const Layout = (props) => {
const { title, children } = props
const siteTitle = "yude.jp"
const router = useRouter()
const { locale, locales, defaultLocale, pathname } = router
const { t, lang } = useTranslation("common")
const footer = t('footer')
const source = t('source')
const tos = t('tos')
return (
<div className="page">
<Head>

View File

@@ -5,13 +5,13 @@ import Link from 'next/link'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
const FontAwesomeMenu = (props) => {
const { icon, dest } = props
const { icon, dest, query } = props
return (
<div>
<Link href={`${dest}`}>
<Link href={{ pathname: dest, query: query }}>
<a>
<FontAwesomeIcon icon={icon} className="w-10 h-10 fill-current inline transition duration-200 ease-in-out transform hover:-translate-y-1 hover:scale-110" />
<FontAwesomeIcon icon={icon} size="5x" className="w-9 h-9 fill-current inline transition duration-200 ease-in-out transform hover:-translate-y-1 hover:scale-110" />
</a>
</Link>
</div>

View File

@@ -1,10 +1,15 @@
// Next.js
import Link from 'next/link'
const MinecraftMenu = () => {
const MinecraftMenu = (props) => {
const { query } = props
if (!query) {
return <p>Loading...</p>
} else {
return (
<div>
<Link href="/minecraft">
<Link href={{ pathname: "/minecraft", query: query }}>
<a>
<svg className="fill-current text-black dark:text-white w-10 h-10 inline transition duration-200 ease-in-out transform hover:-translate-y-1 hover:scale-110" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 304.8 304.8">
<path d="M 39.10262 126.138 L 39.16748 12.39574 L 152.7982 12.33506 L 266.4289 12.27438 L 266.4289 126.0773 L 266.4289 239.8803 L 152.7333 239.8803 L 39.03775 239.8803 L 39.10262 126.138 Z M 260.4857 126.0776 L 260.4857 18.55703 L 152.8628 18.55703 L 45.23985 18.55703 L 45.23985 126.0776 L 45.23985 233.5982 L 152.8628 233.5982 L 260.4857 233.5982 L 260.4857 126.0776 Z M 103.8963 162.9245 L 103.8963 126.0776 L 116.1702 126.0776 L 128.4441 126.0776 L 128.4441 113.8758 L 128.4441 101.674 L 152.8628 101.674 L 177.2814 101.674 L 177.2814 113.8758 L 177.2814 126.0776 L 189.3835 126.0776 L 201.4856 126.0776 L 201.6573 150.5415 C 201.7517 163.9967 201.829 180.5779 201.8291 187.3885 L 201.8293 199.7715 L 189.6869 199.7715 L 177.5446 199.7715 L 177.4776 187.5093 L 177.4106 175.2471 L 152.7982 175.1855 L 128.1857 175.1239 L 128.1857 187.4477 L 128.1857 199.7715 L 116.041 199.7715 L 103.8963 199.7715 L 103.8963 162.9245 Z M 79.34843 77.02888 L 79.34843 52.62534 L 103.7671 52.62534 L 128.1857 52.62534 L 128.1857 77.02888 L 128.1857 101.4324 L 103.7671 101.4324 L 79.34843 101.4324 L 79.34843 77.02888 Z M 177.5398 77.02888 L 177.5398 52.62534 L 201.9585 52.62534 L 226.3771 52.62534 L 226.3771 77.02888 L 226.3771 101.4324 L 201.9585 101.4324 L 177.5398 101.4324 L 177.5398 77.02888 Z"/>
@@ -14,5 +19,6 @@ const MinecraftMenu = () => {
</div>
)
}
}
export default MinecraftMenu

View File

@@ -1,15 +1,14 @@
// React
import React, { useState, useEffect } from 'react';
import useTranslation from 'next-translate/useTranslation'
import { useRouter } from 'next/router'
// i18n
import { useTranslation, useLanguageQuery } from 'next-export-i18n';
import axios from 'axios';
import Image from 'next/image'
import { list } from 'postcss';
export default function Minecraft(props) {
const router = useRouter()
const { locale, locales, defaultLocale, pathname } = router
const { t, lang } = useTranslation("minecraft")
const { t } = useTranslation();
const [query] = useLanguageQuery();
const [data, setData] = useState({ hits: [] });
useEffect(() => {
@@ -25,7 +24,7 @@ export default function Minecraft(props) {
if (data === undefined){
console.log("[Minecraft Query] データの取得に失敗しました。 / Failed to retrieve data.")
return (
<p>{t('minecraft:fail')}</p>
<p>{t('fail')}</p>
)
}else{
const status = data.online
@@ -36,13 +35,13 @@ export default function Minecraft(props) {
{(() => {
if (status == true) {
if (player == undefined || player == 0) {
return <span>{t('minecraft:no_one')}</span>
return <span>{t('no_one')}</span>
} else {
return <span>{t('minecraft:playing', {count: player})}</span>
return <span>{t('playing', {count: player})}</span>
}}else if (status == false) {
return <span>{t('minecraft:offline')}</span>
return <span>{t('offline')}</span>
}else {
return <span>{t('minecraft:loading')}</span>
return <span>{t('loading')}</span>
}
})()}
@@ -54,7 +53,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" alt={i}/>)
list.push(<img src={url[i]} key={i} className="inline" height="50" width="50" alt={i}/>)
}
return <div>{list}</div>
}

View File

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

View File

@@ -1,14 +1,19 @@
// React
import React, { useState, useEffect } from 'react';
// Data fetching
import axios from 'axios';
import useTranslation from 'next-translate/useTranslation'
import { useRouter } from 'next/router'
// i18n
import { useTranslation, useLanguageQuery } from 'next-export-i18n';
// Components
import LastPlayed from './LastPlayed'
function App (props) {
const { t } = useTranslation();
const [query] = useLanguageQuery();
const uuid = props;
const router = useRouter()
const { locale, locales, defaultLocale, pathname } = router
const { t, lang } = useTranslation("common")
const [data, setData] = useState({ hits: [] });
useEffect(() => {

View File

@@ -1,4 +1,7 @@
// React
import React, { useState, useEffect } from 'react';
// Data fetching
import axios from 'axios';
function App (props) {

View File

@@ -9,7 +9,7 @@ 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,
uuid.uuid ? `https://api.ashcon.app/mojang/v2/user/${uuid.uuid}` : null,
fetcher
)

View File

@@ -1,13 +1,24 @@
// Tailwind CSS
import "tailwindcss/tailwind.css";
// Next.js
import Link from 'next/link';
// Components
import LangSelector from "./LangSelector"
import ThemeSelector from "./ThemeSelector"
// i18n
import { useTranslation, useLanguageQuery, LanguageSwitcher } from 'next-export-i18n';
const Navbar = () => {
const { t } = useTranslation();
const [query] = useLanguageQuery();
return (
<>
<nav className='flex items-center flex-wrap p-3'>
<Link href='/'>
<Link href={{ pathname: '/', query: query }}>
<a className='inline-flex items-center p-2'>
<span className='text-xl text-black font-bold tracking-wide dark:text-white font-mono animate-heartbeat'>
yude.jp

View File

@@ -7,10 +7,10 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
const Button = (props) => {
const { icon, dest, caption } = props
return (
<Link href={`${dest}`}>
<Link href={{ pathname: dest }}>
<a>
<button
className="bg-pink-600 text-white active:bg-pink-600 mt-3 font-bold text-sm px-6 py-3 rounded shadow hover:shadow-lg outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150"
className="bg-pink-600 text-white active:bg-pink-600 mt-3 font-bold text-sm px-6 py-3 rounded shadow hover:shadow-lg outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150"
type="button"
>
<FontAwesomeIcon icon={icon} className="w-5 h-5 inline"/> {caption}

View File

@@ -8,9 +8,9 @@ const Contact = (props) => {
const { icon, dest, caption } = props
return (
<div className="hover:underline">
<Link href={`${dest}`}>
<Link href={{ pathname: dest }}>
<a>
<FontAwesomeIcon icon={icon} className="w-7 h-7 inline lg:w-10 lg:h-10 md:w-7 md:h-7"/>
<FontAwesomeIcon icon={icon} size="5x" className="w-9 h-9 fill-current inline transition duration-200 ease-in-out transform hover:-translate-y-1 hover:scale-110" />
<p className="font-mono text-xl">{caption}</p>
</a>
</Link>

View File

@@ -1,20 +1,20 @@
// React
import React, { useState, useEffect } from 'react';
import useTranslation from 'next-translate/useTranslation'
// i18n
import { useTranslation, useLanguageQuery } from 'next-export-i18n';
// Font Awesome
import { faKey, faEye, faDownload } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { useRouter } from 'next/router'
// Next.js
import Link from 'next/link'
export default function Modal() {
const [showModal, setShowModal] = React.useState(false);
const router = useRouter()
const { t, lang } = useTranslation("common")
const { locale, locales, defaultLocale, pathname } = router
const close = t('common:close')
const keys = t('profile:keys')
const view = t('profile:view')
const fingerprint = t('profile:fingerprint')
const download = t('profile:download')
const { t } = useTranslation();
const [query] = useLanguageQuery();
return (
<>
@@ -23,7 +23,7 @@ export default function Modal() {
type="button"
onClick={() => setShowModal(true)}
>
<FontAwesomeIcon icon={faKey} className="w-5 h-5 inline"/> {keys}
<FontAwesomeIcon icon={faKey} className="w-5 h-5 inline"/> {t('keys')}
</button>
{showModal ? (
<>
@@ -36,17 +36,17 @@ export default function Modal() {
{/* Modal body */}
<div className="relative p-2 flex-auto text-black text-left">
<p className="text-2xl"><FontAwesomeIcon icon={faKey} className="w-5 h-5 inline"/> {keys}</p>
<p className="text-2xl"><FontAwesomeIcon icon={faKey} className="w-5 h-5 inline"/> {t('keys')}</p>
<ul className="list-disc my-2">
<li>
<span className="font-bold">PGP&nbsp;</span>
<Link href="/yudejp.gpg">
<a className="hover:underline">
<FontAwesomeIcon icon={faDownload} className="w-5 h-5 inline"/>&nbsp;
{download}
{t('download')}
</a>
</Link>
<p>{fingerprint}:</p>
<p>{t('fingerprint')}:</p>
<div className="overflow-x-auto">
<div className="whitespace-nowrap">
<code>3745 F270 DB4E 8975 6B07 62BE EB0F E5D9 25C4 A968</code>
@@ -58,10 +58,10 @@ export default function Modal() {
<Link href="https://github.com/yude.keys">
<a className="hover:underline">
<FontAwesomeIcon icon={faEye} className="w-5 h-5 inline"/>&nbsp;
{view}
{t('view')}
</a>
</Link>
<p>{fingerprint}:</p>
<p>{t('fingerprint')}:</p>
<div className="overflow-x-auto">
<div className="whitespace-nowrap">
<code>2048 SHA256:xwSL4DORWmroWdC6P0GU1m1yZl/cXqjo9rCCWqqO+Dc</code>
@@ -78,7 +78,7 @@ export default function Modal() {
type="button"
onClick={() => setShowModal(false)}
>
{close}
{t('close')}
</button>
</div>
</div>

View File

@@ -1,17 +1,21 @@
// React
import React, { useState, useEffect } from 'react';
// Data fetching
import axios from 'axios';
import useTranslation from 'next-translate/useTranslation'
import { useRouter } from 'next/router'
// i18n
import { useTranslation, useLanguageQuery } from 'next-export-i18n';
function App () {
const router = useRouter()
const { locale, locales, defaultLocale, pathname } = router
const { t, lang } = useTranslation("common")
const { t } = useTranslation();
const [query] = useLanguageQuery();
const [data, setData] = useState({ hits: [] });
useEffect(() => {
const fetchData = async () => {
const result = await axios(
'/api/Spotify',
'https://vercel-spotify-api.vercel.app/api/Spotify',
);
setData(result.data);
};

View File

@@ -1,15 +1,17 @@
import React, { useState, useEffect } from 'react';
import useTranslation from 'next-translate/useTranslation'
// React
import React from 'react';
// Font Awesome
import { faUserClock } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { useRouter } from 'next/router'
// i18n
import { useTranslation } from 'next-export-i18n';
export default function Modal() {
const [showModal, setShowModal] = React.useState(false);
const router = useRouter()
const { locale, locales, defaultLocale, pathname } = router
const { t, lang } = useTranslation("common")
const close = t('common:close')
const { t } = useTranslation();
return (
<>
<button
@@ -38,7 +40,7 @@ export default function Modal() {
type="button"
onClick={() => setShowModal(false)}
>
{close}
{t('close')}
</button>
</div>
</div>

View File

@@ -7,9 +7,6 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
const ThemeSelector = (props) => {
const { title, children } = props
const router = useRouter()
const { locale, locales, defaultLocale, pathname } = router
const [isMounted, setIsMounted] = useState(false);
const { theme, setTheme, getTheme } = useTheme();
useEffect(() => {

View File

@@ -1,8 +1,10 @@
// Base layout
import Layout from "./components/Layout"
// React, i18n
import useTranslation from 'next-translate/useTranslation'
// i18n
import { useTranslation, useLanguageQuery, LanguageSwitcher } from 'next-export-i18n';
// React
import React from "react"
import ReactMarkdown from "react-markdown"
@@ -12,22 +14,27 @@ import ja from '../docs/hcunews/ja.md'
import en from '../docs/hcunews/en.md'
export default function HcuNews() {
const { t, lang } = useTranslation("hcunews")
const { t } = useTranslation();
const [query] = useLanguageQuery();
return(
<Layout title={t('hcunews')}>
<div>
<h1>{t('hcunews')}</h1>
{lang === 'ja' ? (
<ReactMarkdown plugins={[gfm]}>
{ja}
</ReactMarkdown>
) : (
<ReactMarkdown plugins={[gfm]}>
{en}
</ReactMarkdown>
)}
</div>
</Layout>
)
}
if (!query) {
return <p>Loading...</p>
} else {
return (
<Layout title={t('hcunews')}>
<div>
<h1>{t('hcunews')}</h1>
{query["lang"] === 'ja' ? (
<ReactMarkdown plugins={[gfm]}>
{ja}
</ReactMarkdown>
) : (
<ReactMarkdown plugins={[gfm]}>
{en}
</ReactMarkdown>
)}
</div>
</Layout>
)
}
}

View File

@@ -1,12 +1,16 @@
// Base layout
import Layout from "./components/Layout"
import useTranslation from 'next-translate/useTranslation'
// i18n
import { useTranslation, useLanguageQuery, LanguageSwitcher } from 'next-export-i18n';
// Next.js router
import { useRouter } from 'next/router'
export default function About(props) {
const router = useRouter()
const { locale, locales, defaultLocale, pathname } = router
const { t, lang } = useTranslation("house")
const { t } = useTranslation();
const [query] = useLanguageQuery();
return (
<Layout title={t('house')}>
<div>

View File

@@ -5,66 +5,64 @@ import Layout from "./components/Layout"
import FAMenu from "./components/Menu/FontAwesomeMenu"
// Banner
import BlueRibbon from "./components/Footer/BlueRibbon"
import HappyBusy from "./components/Footer/HappyBusy"
// Next.js
import Image from 'next/image'
import Link from 'next/link'
// i18n
import useTranslation from 'next-translate/useTranslation'
import { useTranslation, useLanguageQuery } from 'next-export-i18n';
// React Router
import { useRouter } from 'next/router'
import MinecraftMenu from "./components/Menu/MinecraftMenu"
// Font Awesome
import { faDiscord, faGit, faMastodon, faGithub } from '@fortawesome/free-brands-svg-icons'
import { faBook, faUser, faServer, faHouseUser, faHeart } from '@fortawesome/free-solid-svg-icons'
import { faDiscord, faGit, faGithub } from '@fortawesome/free-brands-svg-icons'
import { faBook, faUser, faServer, faScrewdriver, faHeart } from '@fortawesome/free-solid-svg-icons'
export default function Index(props) {
const router = useRouter()
const { locale, locales, defaultLocale, pathname } = router
const { t, lang } = useTranslation("index")
const { t } = useTranslation();
const [query] = useLanguageQuery();
if (!query) {
return <p>Loading...</p>
} else {
return (
<>
<Layout title={t('home')}>
<div className="my-9 text-center">
<div className="m-10">
<Image
<img
className = "mx-auto"
src = "/images/avatar_riru.png"
alt = "yude's avatar"
width = {200}
height = {200}
unoptimized = {true}
/>
</div>
{/* Index menu */}
<div className="grid grid-cols-3 gap-10">
<FAMenu dest="/profile" icon={faUser} />
<FAMenu dest="/server" icon={faServer} />
<FAMenu dest="/house" icon={faHouseUser} />
<FAMenu dest="https://scrapbox.io/yude" icon={faBook} />
<FAMenu dest="/profile" query={query} icon={faUser} />
<FAMenu dest="/server" query={query} icon={faServer} />
<FAMenu dest="/services" query={query} icon={faScrewdriver} />
<FAMenu dest="https://discord.gg/X6srY7X" icon={faDiscord} />
<FAMenu dest="https://github.com/yudejp" icon={faGithub} />
<FAMenu dest="https://git.yude.jp" icon={faGit} />
<MinecraftMenu />
<FAMenu dest="/mutual" icon={faHeart} />
<MinecraftMenu query={query} />
<FAMenu dest="/mutual" icon={faHeart} query={query} />
</div>
{/* Banner */}
<div className="mx-auto mt-10">
<BlueRibbon />
<HappyBusy />
</div>
{/* Avatar by */}
<p className="mt-3 text-sm font-bold text-gray-900 dark:text-gray-400">{t('common:icon_1')}<Link href="https://twitter.com/R_I_R_U_"><a className="hover:underline">梨留りる {t('common:icon_2')}</a></Link></p>
<p className="mt-3 text-sm font-bold text-gray-900 dark:text-gray-400">{t('icon_1')}<Link href="https://twitter.com/R_I_R_U_"><a className="hover:underline">梨留りる {t('icon_2')}</a></Link></p>
</div>
</Layout>
</>
)
}
}

View File

@@ -6,10 +6,9 @@ import React, { useState, useEffect } from 'react';
import { useRouter } from 'next/router'
// i18n
import useTranslation from 'next-translate/useTranslation'
import { useTranslation, useLanguageQuery, LanguageSwitcher } from 'next-export-i18n';
// Next.js
import Image from 'next/image'
import Link from 'next/link'
// Custom pages
@@ -29,17 +28,17 @@ import en from '../docs/minecraft/en.md'
import { NextSeo } from 'next-seo';
export default function About(props) {
const router = useRouter()
// i18n
const { locale, locales, defaultLocale, pathname } = router
const { t, lang } = useTranslation("minecraft")
const { t } = useTranslation();
const [query] = useLanguageQuery();
// Copy server address to clipboard
const copyText = () => {
navigator.clipboard.writeText("yude.jp");
};
if (!query) {
return <p>Loading...</p>
} else {
return (
<>
<NextSeo
@@ -51,7 +50,7 @@ export default function About(props) {
<div>
<p className="my-2 text-3xl text-center">{t('title')}</p>
<div className="w-full">
<Image
<img
src = "/images/dynmap.png"
alt = "Minecraft brief world map generated by Dynmap"
width = {1354}
@@ -72,7 +71,7 @@ export default function About(props) {
</button>
</p>
<p>{t('version')}: 1.17</p>
<p>{t('version')}: 1.18.1</p>
<Link href="https://bluemap.yude.jp">
<a>
@@ -86,7 +85,7 @@ export default function About(props) {
</div>
{/* Load markdown contents */}
{lang === 'ja' ? (
{query["lang"] === 'ja' ? (
<ReactMarkdown plugins={[gfm]}>
{ja}
</ReactMarkdown>
@@ -99,4 +98,5 @@ export default function About(props) {
</Layout>
</>
)
}
}

View File

@@ -5,7 +5,6 @@
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())

View File

@@ -16,7 +16,7 @@ export default function UUID() {
const router = useRouter()
const { uuid } = router.query
const { data, error } = useSwr(
uuid ? `/api/PlayerName/${uuid}` : null,
uuid ? `https://api.ashcon.app/mojang/v2/user/${uuid}` : null,
fetcher
)
if (error) {

View File

@@ -2,7 +2,7 @@
import Layout from "./components/Layout"
// i18n
import useTranslation from 'next-translate/useTranslation'
import { useTranslation, useLanguageQuery, LanguageSwitcher } from 'next-export-i18n';
// React Router etc.
import { useRouter } from 'next/router'
@@ -18,18 +18,21 @@ import en from '../docs/mutual/en.md'
import { NextSeo } from 'next-seo';
export default function Tos(props) {
const router = useRouter()
const { locale, locales, defaultLocale, pathname } = router
const { t, lang } = useTranslation("common")
const { t } = useTranslation();
const [query] = useLanguageQuery();
if (!query) {
return <p>Loading...</p>
} else {
return(
<>
<NextSeo
title="相互リンク"
description="yude.jp と相互にリンクを貼っている Web サイトの一覧"
/>
<Layout title={t('common:mutual')}>
<Layout title={t('mutual')}>
<div>
{lang === 'ja' ? (
{query["lang"] === 'ja' ? (
<ReactMarkdown plugins={[gfm]}>
{ja}
</ReactMarkdown>
@@ -42,4 +45,5 @@ export default function Tos(props) {
</Layout>
</>
)
}
}

View File

@@ -1,54 +0,0 @@
// Base layout
import Layout from "./components/Layout"
// Next.js
import Link from "next/link";
// i18n
import { useRouter } from 'next/router'
import useTranslation from 'next-translate/useTranslation'
// microCMS library
import { client } from "../libs/client";
// next-seo
import { NextSeo } from 'next-seo';
export default function Home({ blog }) {
const router = useRouter()
const { locale, locales, defaultLocale, pathname } = router
const { t, lang } = useTranslation("common")
return (
<>
<NextSeo
title="記事一覧"
description="yude のブログの記事一覧 / yude's blog posts listing"
/>
<Layout title={t('common:post_list')}>
<div>
<h1 className="text-center">{t('common:post_list')}</h1>
<ul>
{blog.map((blog) => (
<li key={blog.id}>
<Link href={`/posts/${blog.id}`}>
<a>{blog.title}</a>
</Link>
</li>
))}
</ul>
</div>
</Layout>
</>
);
}
// Passing data to template
export const getStaticProps = async () => {
const data = await client.get({ endpoint: "blog" });
return {
props: {
blog: data.contents,
},
};
};

View File

@@ -1,58 +0,0 @@
// Base layout
import Layout from "../components/Layout"
// microCMS library
import { client } from "../../libs/client";
// next-seo
import { NextSeo } from 'next-seo';
// React
import * as React from "react";
// React Moment
import Moment from 'react-moment';
export default function BlogId({ blog }) {
return (
<>
<Layout title={blog.title + " - yude.jp"}>
<NextSeo
title={blog.title + " - yude.jp"}
description={blog.publishedAt + "に更新された「" + blog.title + "」というタイトルの記事です。"}
/>
<h1>{blog.title}</h1>
<p>
<Moment format="YYYY/MM/DD HH:mm">
{blog.updated}
</Moment>
</p>
<div
dangerouslySetInnerHTML={{
__html: `${blog.content}`,
}}
/>
</Layout>
</>
);
}
// Specify path for static generator
export const getStaticPaths = async () => {
const data = await client.get({ endpoint: "blog" });
const paths = data.contents.map((content) => `/posts/${content.id}`);
return { paths, fallback: false };
};
// Passing data to template
export const getStaticProps = async (context) => {
const id = context.params.id;
const data = await client.get({ endpoint: "blog", contentId: id });
return {
props: {
blog: data,
},
};
};

View File

@@ -2,17 +2,15 @@
import Layout from "./components/Layout"
// i18n
import useTranslation from 'next-translate/useTranslation'
import { useTranslation, useLanguageQuery } from 'next-export-i18n';
// Font Awesome
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 { faEnvelope, faBirthdayCake, faMapPin, faSchool, faPhone, faBlog, faBookDead, faInfo, faBookmark, faLink, faMobile } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
// Next.js, React
import Link from 'next/link'
import Image from 'next/image'
import { useRouter } from 'next/router'
// Discord
import DiscordStatus from './components/Discord/DiscordStatus'
@@ -25,16 +23,13 @@ import PublicKeys from './components/Profile/PublicKeys'
import Button from './components/Profile/Button'
import Contact from './components/Profile/Contact'
import NintendoSW from "./components/Profile/NintendoSW"
import FitbitSleep from "./components/Fitbit/Sleep"
import FitbitHeartrate from "./components/Fitbit/Heartrate"
// next-seo
import { NextSeo } from 'next-seo';
export default function Profile(props) {
const router = useRouter()
const { locale, locales, defaultLocale, pathname } = router
const { t, lang } = useTranslation("profile")
const { t } = useTranslation();
const [query] = useLanguageQuery();
return (
<>
@@ -49,7 +44,7 @@ export default function Profile(props) {
}
<div>
<div className="flex mb-10 justify-center">
<Image
<img
className = "rounded-full hover:animate-rumble z-0 p-15"
src = "/images/avatar_mel.png"
alt = "yude's avatar"
@@ -63,8 +58,6 @@ export default function Profile(props) {
<div>
<DiscordPlaying />
<Spotify />
{/* <FitbitSleep />
<FitbitHeartrate /> */}
</div>
</div>
@@ -93,6 +86,19 @@ export default function Profile(props) {
<p className="ml-9">{t('hiroshima')}</p>
</div>
</div>
{
// Contents
}
<div>
<div className="text-left">
<p className="text-2xl"><FontAwesomeIcon icon={faBookDead} className="w-5 h-5 inline"/> {t('contents')}</p>
</div>
<div className="my-2 grid grid-cols-2 lg:grid-cols-5 md:grid-cols-3 sm:grid-cols-2justify-items-center gap-y-6">
<Contact dest="https://blog.yude.jp" icon={faBlog} caption={t('blog')} />
<Contact dest="https://scrapbox.io/yude" icon={faBookmark} caption="Scrapbox" />
</div>
</div>
{
// Contact
@@ -124,7 +130,7 @@ export default function Profile(props) {
</div>
</div>
<p className="mt-3 text-sm font-bold text-gray-900 dark:text-gray-400">{t('common:icon_1')}<Link href="https://twitter.com/xmnts"><a className="hover:underline">Minkasy {t('common:icon_2')}</a></Link></p>
<p className="mt-3 text-sm font-bold text-gray-900 dark:text-gray-400">{t('icon_1')}<Link href="https://twitter.com/xmnts"><a className="hover:underline">Minkasy {t('icon_2')}</a></Link></p>
</div>
</Layout>

View File

@@ -2,18 +2,14 @@
import Layout from "./components/Layout"
// i18n
import useTranslation from 'next-translate/useTranslation'
// React Router
import { useRouter } from 'next/router'
import { useTranslation, useLanguageQuery, LanguageSwitcher } from 'next-export-i18n';
// next-seo
import { NextSeo } from 'next-seo';
export default function Server(props) {
const router = useRouter()
const { locale, locales, defaultLocale, pathname } = router
const { t, lang } = useTranslation("server")
const { t } = useTranslation();
const [query] = useLanguageQuery();
return (
<>
@@ -41,7 +37,7 @@ export default function Server(props) {
<div className="flex-1"><p className="font-bold">OS </p>Arch Linux</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/heHnGhDanoIDlf7jjxUe9yPVrsG3deeH5ptD8suErrq5w46crWEIYdLfzLoukzfF?period=24h" height="400" frameBorder="0" scrolling="no"></iframe>
<a href="https://mackerel.io/orgs/yude/hosts/4dkbQuMQjvo/-/graphs/loadavg#period=10m"><img src="https://mackerel.io/embed/public/embed/heHnGhDanoIDlf7jjxUe9yPVrsG3deeH5ptD8suErrq5w46crWEIYdLfzLoukzfF.png?period=10m" className="w-full" /></a>
{
@@ -55,7 +51,7 @@ export default function Server(props) {
<div className="flex-1"><p className="font-bold">OS </p>Ubuntu 20.04 LTS</div>
<div className="flex-1"><p className="font-bold">{t('region')} </p>Japan Central (Osaka)</div>
</div>
<iframe className="w-full h-96" src="https://mackerel.io/embed/public/embed/vcn6LE4P2hh6GzvtMbIAWxsXpDh6eSoNyAXdhfYaj9yDN6FJwOHIiz9ktqToj1HG?period=24h" height="400" frameBorder="0" scrolling="no"></iframe>
<a href="https://mackerel.io/orgs/yude/hosts/4ftHfeojMCU/-/graphs/loadavg#period=10m"><img src="https://mackerel.io/embed/public/embed/vcn6LE4P2hh6GzvtMbIAWxsXpDh6eSoNyAXdhfYaj9yDN6FJwOHIiz9ktqToj1HG.png?period=10m" className="w-full" /></a>
{
// oracle2
@@ -68,7 +64,20 @@ export default function Server(props) {
<div className="flex-1"><p className="font-bold">OS </p>Ubuntu 20.04 LTS</div>
<div className="flex-1"><p className="font-bold">{t('region')} </p>Japan Central (Osaka)</div>
</div>
<iframe className="w-full h-96" src="https://mackerel.io/embed/public/embed/wgmTz7aTgvwfyU6qVHrJJmQlpOHCUJK6qw0W9sJTX68WOI8TFtc27YvJ7dwkQEGv?period=24h" height="400" frameBorder="0" scrolling="no"></iframe>
<a href="https://mackerel.io/orgs/yude/hosts/4frgQ1QuivJ/-/graphs/loadavg#period=10m"><img src="https://mackerel.io/embed/public/embed/wgmTz7aTgvwfyU6qVHrJJmQlpOHCUJK6qw0W9sJTX68WOI8TFtc27YvJ7dwkQEGv.png?period=10m" className="w-full" /></a>
{
// oracle-a1-1
}
<h2 className="text-2xl text-left font-bold leading-7 sm:text-3xl sm:truncate">oracle-a1-1</h2>
<div className="flex xl:w-2/3 text-center">
<div className="flex-1"><p className="font-bold">{t('service')} </p>Oracle Cloud</div>
<div className="flex-1"><p className="font-bold">{t('shape')} </p>VM.Standard.A1.Flex</div>
<div className="flex-1"><p className="font-bold">RAM </p>6GB</div>
<div className="flex-1"><p className="font-bold">OS </p>Ubuntu 20.04.3 LTS</div>
<div className="flex-1"><p className="font-bold">{t('region')} </p>Japan Central (Osaka)</div>
</div>
<a href="https://mackerel.io/orgs/yude/hosts/4qzeqT6kToQ/-/graphs/loadavg#period=10m"><img src="https://mackerel.io/embed/public/embed/2C7NdtqLgGFGPiO2IctDGuaMdjBwhXyp0i8imkaJT2GFI55syPaxxACEYIRWDHnS.png?period=10m" className="w-full" /></a>
</div>
</Layout>

49
pages/services.js Normal file
View File

@@ -0,0 +1,49 @@
// Base layout
import Layout from "./components/Layout"
// i18n
import { useTranslation, useLanguageQuery, LanguageSwitcher } from 'next-export-i18n';
// React Router etc.
import { useRouter } from 'next/router'
import React from "react"
// React Markdown
import ReactMarkdown from "react-markdown"
import gfm from 'remark-gfm';
import ja from '../docs/services/ja.md'
import en from '../docs/services/en.md'
// next-seo
import { NextSeo } from 'next-seo';
export default function Tos(props) {
const { t } = useTranslation();
const [query] = useLanguageQuery();
if (!query) {
return <p>Loading...</p>
} else {
return(
<>
<NextSeo
title="サービス"
description="yude.jp で運用中のサービス"
/>
<Layout title={t('services')}>
<div>
{query["lang"] === 'ja' ? (
<ReactMarkdown plugins={[gfm]}>
{ja}
</ReactMarkdown>
) : (
<ReactMarkdown plugins={[gfm]}>
{en}
</ReactMarkdown>
)}
</div>
</Layout>
</>
)
}
}

View File

@@ -1,29 +1,40 @@
// Base layout
import Layout from "./components/Layout"
import useTranslation from 'next-translate/useTranslation'
// i18n
import { useTranslation, useLanguageQuery, LanguageSwitcher } from 'next-export-i18n';
// Next.js, React
import { useRouter } from 'next/router'
import React from "react"
// React Markdown
import ReactMarkdown from "react-markdown"
import gfm from 'remark-gfm';
import ja from '../docs/tos/ja.md'
import en from '../docs/tos/en.md'
export default function Tos(props) {
const router = useRouter()
const { locale, locales, defaultLocale, pathname } = router
const { t, lang } = useTranslation("tos")
return(
<Layout title={t('tos')}>
<div>
{lang === 'ja' ? (
<ReactMarkdown plugins={[gfm]}>
{ja}
</ReactMarkdown>
) : (
<ReactMarkdown plugins={[gfm]}>
{en}
</ReactMarkdown>
)}
</div>
</Layout>
)
}
const { t } = useTranslation();
const [query] = useLanguageQuery();
if (!query) {
return <p>Loading...</p>
} else {
return (
<Layout title={t('tos')}>
<div>
{query["lang"] === 'ja' ? (
<ReactMarkdown plugins={[gfm]}>
{ja}
</ReactMarkdown>
) : (
<ReactMarkdown plugins={[gfm]}>
{en}
</ReactMarkdown>
)}
</div>
</Layout>
)
}
}

1600
yarn.lock

File diff suppressed because it is too large Load Diff