From d05a21a066b72e2c7808715697cd36a388b4992e Mon Sep 17 00:00:00 2001 From: Xeu Date: Wed, 10 Jul 2024 20:13:06 +0800 Subject: [PATCH 1/7] test: lock cors --- .github/workflows/deploy.yaml | 2 +- server/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index d5a5987e..288c7619 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -50,5 +50,5 @@ jobs: RSS_DESCRIPTION: ${{ vars.RSS_DESCRIPTION }} run: | cd Rin/ - bun install --frozen-lockfile + bun install bun scripts/migrator.ts diff --git a/server/package.json b/server/package.json index fe607cee..fc8caa49 100644 --- a/server/package.json +++ b/server/package.json @@ -24,7 +24,7 @@ "dependencies": { "@aws-sdk/client-s3": "^3.583.0", "@aws-sdk/s3-request-presigner": "^3.583.0", - "@elysiajs/cors": "^1.0.2", + "@elysiajs/cors": "1.0.2", "@elysiajs/cron": "^1.0.3", "@elysiajs/eden": "^1.0.13", "@elysiajs/server-timing": "^1.0.2", From f64d86a5749630adaff472b225e9feb437534dd3 Mon Sep 17 00:00:00 2001 From: Xeu Date: Wed, 10 Jul 2024 21:28:42 +0800 Subject: [PATCH 2/7] docs: change repo path --- README.md | 28 ++++++++++------------------ README_zh_CN.md | 27 ++++++++++----------------- client/src/components/footer.tsx | 2 +- docs/DEPLOY.md | 30 +++++++++++++++--------------- docs/SEO.md | 4 ++-- server/src/server.ts | 2 +- 6 files changed, 39 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index 7ab67600..8e794f6f 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,11 @@ English | [简体中文](./README_zh_CN.md) ![Cover](https://repository-images.githubusercontent.com/803866357/958bc2c1-1703-4127-920c-853291495bdc) -![GitHub commit activity](https://img.shields.io/github/commit-activity/w/OXeu/Rin?style=for-the-badge) -![GitHub branch check runs](https://img.shields.io/github/check-runs/OXeu/Rin/main?style=for-the-badge) -![GitHub top language](https://img.shields.io/github/languages/top/OXeu/Rin?style=for-the-badge) -![GitHub License](https://img.shields.io/github/license/OXeu/Rin?style=for-the-badge) -![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/OXeu/Rin/deploy.yaml?style=for-the-badge) +![GitHub commit activity](https://img.shields.io/github/commit-activity/w/openRin/Rin?style=for-the-badge) +![GitHub branch check runs](https://img.shields.io/github/check-runs/openRin/Rin/main?style=for-the-badge) +![GitHub top language](https://img.shields.io/github/languages/top/openRin/Rin?style=for-the-badge) +![GitHub License](https://img.shields.io/github/license/openRin/Rin?style=for-the-badge) +![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/openRin/Rin/deploy.yaml?style=for-the-badge) # Introduction @@ -34,23 +34,15 @@ Rin is a blog based on Cloudflare Pages + Workers + D1 + R2. It does not require 13. For more features, please refer to https://xeu.life # Documentation -1. [Deployment Documentation](./docs/DEPLOY.md) - -2. [Environment Variables List](./docs/ENV.md) - -3. [SEO Optimization Configuration](./docs/SEO.md) - -4. [Contribution Guide](./CONTRIBUTING.md) - -5. [Code of Conduct](./CODE_OF_CONDUCT.md) +[rin-docs.xeu.life](https://rin-docs.xeu.life) ## Star History - + - - - Star History Chart + + + Star History Chart diff --git a/README_zh_CN.md b/README_zh_CN.md index 14f6129b..6e7ead99 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -5,11 +5,11 @@ ![封面](https://repository-images.githubusercontent.com/803866357/958bc2c1-1703-4127-920c-853291495bdc) -![GitHub commit activity](https://img.shields.io/github/commit-activity/w/OXeu/Rin?style=for-the-badge) -![GitHub branch check runs](https://img.shields.io/github/check-runs/OXeu/Rin/main?style=for-the-badge) -![GitHub top language](https://img.shields.io/github/languages/top/OXeu/Rin?style=for-the-badge) -![GitHub License](https://img.shields.io/github/license/OXeu/Rin?style=for-the-badge) -![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/OXeu/Rin/deploy.yaml?style=for-the-badge) +![GitHub commit activity](https://img.shields.io/github/commit-activity/w/openRin/Rin?style=for-the-badge) +![GitHub branch check runs](https://img.shields.io/github/check-runs/openRin/Rin/main?style=for-the-badge) +![GitHub top language](https://img.shields.io/github/languages/top/openRin/Rin?style=for-the-badge) +![GitHub License](https://img.shields.io/github/license/openRin/Rin?style=for-the-badge) +![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/openRin/Rin/deploy.yaml?style=for-the-badge) # 介绍 @@ -36,23 +36,16 @@ Rin 是一个基于 Cloudflare Pages + Workers + D1 + R2 全家桶的博客, 13. 更多特性请参考 https://xeu.life # 文档 -1. [部署文档(Github)](./docs/DEPLOY.md) -2. [环境变量列表](./docs/ENV.md) - -3. [SEO 优化配置](./docs/SEO.md) - -4. [贡献指南](./CONTRIBUTING.md) - -5. [行为准则](./CODE_OF_CONDUCT.md) +[rin-docs.xeu.life](https://rin-docs.xeu.life) ## Star History - + - - - Star History Chart + + + Star History Chart diff --git a/client/src/components/footer.tsx b/client/src/components/footer.tsx index 616e6be3..a157204b 100644 --- a/client/src/components/footer.tsx +++ b/client/src/components/footer.tsx @@ -44,7 +44,7 @@ function Footer() {

- © 2024 Powered by Rin + © 2024 Powered by Rin {config.get('rss') && <> diff --git a/docs/DEPLOY.md b/docs/DEPLOY.md index 754563f9..560cbec1 100644 --- a/docs/DEPLOY.md +++ b/docs/DEPLOY.md @@ -1,6 +1,6 @@ # 部署 -项目目前处于开发阶段,文档可能未及时更新或存在描述不清,如遇部署失败请提 [Issue](https://github.com/OXeu/Rin/issues/new?assignees=&labels=help+wanted&projects=&template=need-help.md&title=%5BHelp%5D+%E9%97%AE%E9%A2%98%E6%8F%8F%E8%BF%B0) +项目目前处于开发阶段,文档可能未及时更新或存在描述不清,如遇部署失败请提 [Issue](https://github.com/openRin/Rin/issues/new?assignees=&labels=help+wanted&projects=&template=need-help.md&title=%5BHelp%5D+%E9%97%AE%E9%A2%98%E6%8F%8F%E8%BF%B0) > [!TIP] > 我们在文档末尾追加了完整的部署流程演示视频,以便解决您在部署期间遇到的部分困难 @@ -63,12 +63,12 @@ S3_SECRET_ACCESS_KEY=<你的S3SecretAccessKey> > > 这就是最终的命令 -打开仓库页面:https://github.com/OXeu/Rin +打开仓库页面:https://github.com/openRin/Rin ## Fork 点击 Fork 按钮 fork 出一个新仓库 -![1000000657](https://github.com/OXeu/Rin/assets/36541432/df3607ca-a8a9-49b8-92ce-6b348afeb13f) +![1000000657](https://github.com/openRin/Rin/assets/36541432/df3607ca-a8a9-49b8-92ce-6b348afeb13f) ## 前端 @@ -79,20 +79,20 @@ S3_SECRET_ACCESS_KEY=<你的S3SecretAccessKey> > > 下文提到的前端与后端你可以分别等价代换为 Cloudflare Pages 与 Cloudflare Workers,当提到说需要前端地址或者后端地址时,即为 Cloudflare Pages 地址或 Cloudflare Workers 地址,你可以在 Cloudflare 控制面板中通过少量的操作找到这两个地址,如下面的截图所示: > 前端(Pages)的地址在 `Workers 和 Pages` > 你的 Pages 项目 > `部署` 中可以找到: -> ![图片](https://github.com/OXeu/Rin/assets/36541432/d9dcc5f2-6930-4487-af4b-0ab52e948114) +> ![图片](https://github.com/openRin/Rin/assets/36541432/d9dcc5f2-6930-4487-af4b-0ab52e948114) > 图中的`rin-6qe.pages.dev`,`direct.xeu.life` 都是前端地址,如果有更多的地址,你还可以点击形如 `+2 个域` 的链接查看更多的地址,这些地址都是可以访问的,你可以使用其中任意一个地址,但是需要保持不同地方都填写的是同一个前端地址(如果有多个环境变量要求填写前端地址的话),通常来说前端地址是 `https://rin-6qe.pages.dev` 或 `https://direct.xeu.life` 这样的形式 > > 后端(Workers)的地址在 `Workers 和 Pages` > 你的 Workers 项目 > `设置` > `触发器` 中可以找到: -> ![图片](https://github.com/OXeu/Rin/assets/36541432/0a2385b7-94db-4469-bef9-399cc334f1b6) +> ![图片](https://github.com/openRin/Rin/assets/36541432/0a2385b7-94db-4469-bef9-399cc334f1b6) > 图中的 `rin.xeu.life` 和 `rin-server.xeu.workers.dev` 都是后端地址,前者是自定义域名,后者是默认分配的域名,你可以使用默认分配的域名,也可以自定义域名,自定义域名需要在 Cloudflare 控制面板中进行配置,在本文档中当要求填写后端地址时,你可以填写形如 `https://rin.xeu.life` 或 `https://rin-server.xeu.workers.dev`的地址,但需保持不同地方都填写的是同一个后端地址(如果有多个环境变量要求填写后端地址的话) 登录 [Cloudflare](https://dash.cloudflare.com) 控制台,进入 `Workers 和 Pages` 页面,点击`创建应用程序`,选择 Pages -![1000000658](https://github.com/OXeu/Rin/assets/36541432/35d4f9e3-3af3-4ec8-8060-2a352f4d51ae) +![1000000658](https://github.com/openRin/Rin/assets/36541432/35d4f9e3-3af3-4ec8-8060-2a352f4d51ae) 点击连接到 Git 连接自己的 GitHub 账号并选择 Fork 的存储库 -![1000000666](https://github.com/OXeu/Rin/assets/36541432/e3b6da75-1a5f-46ec-9820-636cc5238023) +![1000000666](https://github.com/openRin/Rin/assets/36541432/e3b6da75-1a5f-46ec-9820-636cc5238023) 点击 `开始设置` 进入配置页面: @@ -105,7 +105,7 @@ S3_SECRET_ACCESS_KEY=<你的S3SecretAccessKey> 路径:<留空> ``` -![1000000659](https://github.com/OXeu/Rin/assets/36541432/98fb3021-932b-4bfa-8118-3378f98ff628) +![1000000659](https://github.com/openRin/Rin/assets/36541432/98fb3021-932b-4bfa-8118-3378f98ff628) 环境变量复制以下内容,根据自身情况修改变量值: @@ -122,15 +122,15 @@ SKIP_DEPENDENCY_INSTALL=true UNSTABLE_PRE_BUILD=asdf install bun latest && asdf global bun latest && bun i ``` -![1000000660](https://github.com/OXeu/Rin/assets/36541432/0fe9276f-e16f-4b8a-87c5-14de582c9a3a) +![1000000660](https://github.com/openRin/Rin/assets/36541432/0fe9276f-e16f-4b8a-87c5-14de582c9a3a) 点击`保存并部署`,等待构建部署,不出意外的话约 30s 后即可部署完成: -![1000000661](https://github.com/OXeu/Rin/assets/36541432/979810b7-3f6f-415b-a8e8-5b08b0da905d) +![1000000661](https://github.com/openRin/Rin/assets/36541432/979810b7-3f6f-415b-a8e8-5b08b0da905d) 点击打开即可看见前端页面 -![1000000662](https://github.com/OXeu/Rin/assets/36541432/57c61ad6-c324-48e4-a28f-a1708fd7d41a) +![1000000662](https://github.com/openRin/Rin/assets/36541432/57c61ad6-c324-48e4-a28f-a1708fd7d41a) 前端就全部部署完成啦 🎉 @@ -169,7 +169,7 @@ UNSTABLE_PRE_BUILD=asdf install bun latest && asdf global bun latest && bun i ID 随意点击一个自己绑定的域名,进入后在右侧(需要向下滑动一段距离)可以找到`账户ID` 创建 API 令牌:点击右上角`头像` > `我的个人资料` > `API 令牌` > `创建令牌`,模板选择`编辑 Cloudflare Workers`: -![1000000663](https://github.com/OXeu/Rin/assets/36541432/3a34a2ad-b993-47fe-965d-31cca4a8e92a) +![1000000663](https://github.com/openRin/Rin/assets/36541432/3a34a2ad-b993-47fe-965d-31cca4a8e92a) 创建完成后保存令牌 @@ -232,7 +232,7 @@ https://<你的后端地址>/user/github/callback ``` 这里附上我的参数 -![GitHub OAuth 配置](https://github.com/OXeu/Rin/assets/36541432/74ab8d16-93ca-4919-beec-4beb7a2003a6) +![GitHub OAuth 配置](https://github.com/openRin/Rin/assets/36541432/74ab8d16-93ca-4919-beec-4beb7a2003a6) 随后配置环境变量中 OAuth 部分 @@ -243,7 +243,7 @@ https://<你的后端地址>/user/github/callback 理论上支持任意遵循 S3 协议的对象存储服务,这里只介绍接入 Cloudflare R2 的操作 Cloudflare 面板中点击 `R2` > `创建存储桶`,填写名称,选择距离自己近的位置: -![1000000665](https://github.com/OXeu/Rin/assets/36541432/17c5ad7b-8a3a-49b2-845a-8d043484aa63) +![1000000665](https://github.com/openRin/Rin/assets/36541432/17c5ad7b-8a3a-49b2-845a-8d043484aa63) 创建存储桶之后进入存储桶详情页 > `设置`,复制 S3 API 地址,去除末尾的存储桶名称后填入 `S3_ENDPOINT`,如: @@ -276,6 +276,6 @@ S3_ACCESS_HOST=https://image.xeu.life 由于时间原因未对以下视频做剪辑与后期说明处理,如果对于部署流程不了解或疑惑可参考视频步骤 -https://github.com/OXeu/Rin/assets/36541432/3ed98e93-2cc3-4e5f-a885-4d16a48500c3 +https://github.com/openRin/Rin/assets/36541432/3ed98e93-2cc3-4e5f-a885-4d16a48500c3 diff --git a/docs/SEO.md b/docs/SEO.md index 7ecdf94c..fcdb460e 100644 --- a/docs/SEO.md +++ b/docs/SEO.md @@ -41,7 +41,7 @@ S3_SECRET_ACCESS_KEY=<你的S3SecretAccessKey> ``` xeu.life/seo/* ``` -![图片](https://github.com/OXeu/Rin/assets/36541432/ed0ecc72-f61f-4460-8ede-4475ca54ffcb) +![图片](https://github.com/openRin/Rin/assets/36541432/ed0ecc72-f61f-4460-8ede-4475ca54ffcb) Worker 选择为部署的 Worker,点击保存。 @@ -58,6 +58,6 @@ concat("/seo",http.request.uri.path) 选择`保留查询` 参考配置截图: -![转换规则](https://github.com/OXeu/Rin/assets/36541432/657e9546-1dc0-4390-9bfc-5d3eb725e792) +![转换规则](https://github.com/openRin/Rin/assets/36541432/657e9546-1dc0-4390-9bfc-5d3eb725e792) 点击部署,即可完成 SEO 配置。 diff --git a/server/src/server.ts b/server/src/server.ts index 0c9bd274..c16e2d1d 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -17,7 +17,7 @@ export const app = () => new Elysia({ aot: false }) origin: '*', methods: '*', allowedHeaders: [ - 'Authorization', + 'authorization', 'content-type' ], maxAge: 600, From 63902cdc1edc9f364cd888e5257b9101bae3a5dc Mon Sep 17 00:00:00 2001 From: Xeu Date: Wed, 10 Jul 2024 21:45:06 +0800 Subject: [PATCH 3/7] fix: first top failed --- client/src/page/feed.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/page/feed.tsx b/client/src/page/feed.tsx index f4118164..f867fc82 100644 --- a/client/src/page/feed.tsx +++ b/client/src/page/feed.tsx @@ -72,7 +72,7 @@ export function FeedPage({ id, TOC, clean }: { id: string, TOC: () => JSX.Elemen } function topFeed() { const isUnTop = !(top > 0) - const topNew = top === 0 ? 1 : 0; + const topNew = isUnTop ? 1 : 0; // Confirm showConfirm( isUnTop ? t("article.top.title") : t("article.untop.title"), From fa1e20513a8a02a85222baa5c4f94da2bd62ce90 Mon Sep 17 00:00:00 2001 From: Xeu Date: Wed, 10 Jul 2024 22:08:11 +0800 Subject: [PATCH 4/7] fix: false config not work --- client/src/page/feed.tsx | 4 ++-- client/src/state/config.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/src/page/feed.tsx b/client/src/page/feed.tsx index f867fc82..de6f6969 100644 --- a/client/src/page/feed.tsx +++ b/client/src/page/feed.tsx @@ -204,12 +204,12 @@ export function FeedPage({ id, TOC, clean }: { id: string, TOC: () => JSX.Elemen )}

{counterEnabled &&

- {t("count.pv")} + {t("count.pv")} {feed.pv} | - {t("count.uv")} + {t("count.uv")} {feed.uv} diff --git a/client/src/state/config.tsx b/client/src/state/config.tsx index fb522d29..47144782 100644 --- a/client/src/state/config.tsx +++ b/client/src/state/config.tsx @@ -10,7 +10,7 @@ export const defaultClientConfig = new Map(Object.entries({ export const defaultServerConfig = new Map(Object.entries({ "friend_apply_auto_accept": false, "friend_crontab": true, - "friend_ua":"Rin-Check/0.1.0" + "friend_ua": "Rin-Check/0.1.0" })) export class ConfigWrapper { @@ -22,7 +22,7 @@ export class ConfigWrapper { } get(key: string) { const value = this.config[key]; - if (value != undefined && value != "") { + if (value != undefined && value !== "") { return value as T; } if (this.defaultConfig.has(key)) { From b14bc5fa4cde8e12914d1f6dda8688c3bc460d83 Mon Sep 17 00:00:00 2001 From: Xeu Date: Wed, 10 Jul 2024 22:18:50 +0800 Subject: [PATCH 5/7] fix: waiting for hashtags --- client/src/page/hashtags.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/page/hashtags.tsx b/client/src/page/hashtags.tsx index a1eecd79..1ad52c58 100644 --- a/client/src/page/hashtags.tsx +++ b/client/src/page/hashtags.tsx @@ -17,7 +17,7 @@ type Hashtag = { export function HashtagsPage() { const { t } = useTranslation(); - const [hashtags, setHashtags] = useState([]); + const [hashtags, setHashtags] = useState(); const ref = useRef(false); useEffect(() => { if (ref.current) return; @@ -47,7 +47,7 @@ export function HashtagsPage() {

- {hashtags.filter(({ feeds }) => feeds > 0).map((hashtag, index) => { + {hashtags?.filter(({ feeds }) => feeds > 0).map((hashtag, index) => { return (
From 155df16a783ef9264c906b7f0009275ee2efa3c5 Mon Sep 17 00:00:00 2001 From: Xeu Date: Wed, 10 Jul 2024 22:40:28 +0800 Subject: [PATCH 6/7] chore: refactor all != to !== --- client/src/App.tsx | 4 ++-- client/src/components/header.tsx | 2 +- client/src/components/markdown.tsx | 2 +- client/src/hooks/useTableOfContents.tsx | 2 +- client/src/page/feeds.tsx | 2 +- client/src/page/friends.tsx | 8 ++++---- client/src/page/hashtag.tsx | 2 +- client/src/page/hashtags.tsx | 2 +- client/src/page/search.tsx | 2 +- client/src/page/settings.tsx | 6 +++--- client/src/page/timeline.tsx | 2 +- client/src/page/writing.tsx | 6 +++--- client/src/state/config.tsx | 2 +- scripts/render.ts | 2 +- server/src/services/feed.ts | 2 +- 15 files changed, 23 insertions(+), 23 deletions(-) diff --git a/client/src/App.tsx b/client/src/App.tsx index f6819ef6..9b283116 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -32,7 +32,7 @@ function App() { client.user.profile.get({ headers: headersWithAuth() }).then(({ data }) => { - if (data && typeof data != 'string') { + if (data && typeof data !== 'string') { setProfile({ id: data.id, avatar: data.avatar || '', @@ -49,7 +49,7 @@ function App() { setConfig(configWrapper) } else { client.config({ type: "client" }).get().then(({ data }) => { - if (data && typeof data != 'string') { + if (data && typeof data !== 'string') { sessionStorage.setItem('config', JSON.stringify(data)) const config = new ConfigWrapper(data, defaultClientConfig) setConfig(config) diff --git a/client/src/components/header.tsx b/client/src/components/header.tsx index 2f6aa2e9..91289fbf 100644 --- a/client/src/components/header.tsx +++ b/client/src/components/header.tsx @@ -229,7 +229,7 @@ function SearchButton({ className, onClose }: { className?: string, onClose?: () setIsOpened(false) onClose?.() }, 100) - if (value.length != 0) + if (value.length !== 0) setLocation(`/search/${key}`) } return (
diff --git a/client/src/components/markdown.tsx b/client/src/components/markdown.tsx index e97cc0e2..39ae569e 100644 --- a/client/src/components/markdown.tsx +++ b/client/src/components/markdown.tsx @@ -365,7 +365,7 @@ export function Markdown({ content }: { content: string }) { }, }; }) - .filter((slide) => slide.src != ""); + .filter((slide) => slide.src !== ""); slides.current = (slidesLocal); } const index = slidesLocal?.findIndex((slide) => slide.src === src) ?? -1; diff --git a/client/src/hooks/useTableOfContents.tsx b/client/src/hooks/useTableOfContents.tsx index ddafe85c..de411f40 100644 --- a/client/src/hooks/useTableOfContents.tsx +++ b/client/src/hooks/useTableOfContents.tsx @@ -58,7 +58,7 @@ const useTableOfContents = (selector: string) => { ) intersectingList.length = 0 // reset array headers.forEach((header, i) => { - if (header.getAttribute('data-id') != null) return + if (header.getAttribute('data-id') !== null) return header.setAttribute('data-id', i.toString()) // set data-id intersectingList.push(false) // increase array length io.current!.observe(header) // register to observe diff --git a/client/src/page/feeds.tsx b/client/src/page/feeds.tsx index 13fbacc7..fb8c4a31 100644 --- a/client/src/page/feeds.tsx +++ b/client/src/page/feeds.tsx @@ -45,7 +45,7 @@ export function FeedsPage() { }, headers: headersWithAuth() }).then(({ data }) => { - if (data && typeof data != 'string') { + if (data && typeof data !== 'string') { setFeeds({ ...feeds, [type]: data diff --git a/client/src/page/friends.tsx b/client/src/page/friends.tsx index d9964a18..5cdb26ad 100644 --- a/client/src/page/friends.tsx +++ b/client/src/page/friends.tsx @@ -98,13 +98,13 @@ export function FriendsPage() { - +
0} friends={friendsAvailable} /> 0} friends={friendsUnavailable} /> 0} friends={waitList} /> 0} friends={refusedList} /> - + {profile && (profile.permission || config.get("friend_apply_enable")) &&
@@ -210,7 +210,7 @@ function Friend({ friend }: { friend: FriendItem }) {

{friend.name}

{friend.health.length == 0 &&

{friend.desc}

} - {friend.accepted != 1 &&

{statusOption[friend.accepted + 1].label}

} + {friend.accepted !== 1 &&

{statusOption[friend.accepted + 1].label}

} {friend.health.length > 0 &&

{errorHumanize(friend.health)}

} {(profile?.permission || profile?.id === friend.uid) && <>