diff --git a/.all-contributorsrc b/.all-contributorsrc new file mode 100644 index 0000000..67102c1 --- /dev/null +++ b/.all-contributorsrc @@ -0,0 +1,35 @@ +{ + "files": [ + "README.md" + ], + "imageSize": 100, + "commit": false, + badgeTemplate: "", + "contributors": [ + { + "login": "wonderlandpark", + "name": "Junseo Park", + "avatar_url": "https://avatars.githubusercontent.com/u/31924512?v=4", + "profile": "https://wonder.im", + "contributions": [ + "maintenance", + "business" + ] + }, + { + "login": "zero734kr", + "name": "zero734kr", + "avatar_url": "https://avatars.githubusercontent.com/u/51540538?v=4", + "profile": "https://github.com/zero734kr", + "contributions": [ + "review" + ] + } + ], + "contributorsPerLine": 7, + "projectName": "koreanbots", + "projectOwner": "koreanbots", + "repoType": "github", + "repoHost": "https://github.com", + "skipCi": true +} diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..a839ed0 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +.next/ +node_modules/ +Dockerfile +yarn-error.log +.dockerignore +.git +.gitignore +.github \ No newline at end of file diff --git a/.env.demo.local b/.env.demo.local new file mode 100644 index 0000000..ea834e5 --- /dev/null +++ b/.env.demo.local @@ -0,0 +1,15 @@ +KOREANBOTS_URL=http://localhost:3000 +MYSQL_HOST=mysql +MYSQL_USER=root +MYSQL_PASSWORD=YOUSHALLNOTPASS +MYSQL_DATABASE=discordbots + +DISCORD_CLIENT_ID=CLIENT_ID +DISCORD_CLIENT_SECRET=CLIENT_SECRET +DISCORD_SCOPE=SCOPE +DISCORD_TOKEN=BOT_TOKEN + +GITHUB_CLIENT_ID=GH_CLIENT_ID +GITHUB_CLIENT_SECRET=GH_CLIENT_SECRET + +CSRF_SECRET=CSRF_SECRET \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..1c198f9 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,41 @@ +module.exports = { + root: true, + env: { + node: true, + es6: true, + browser: true, + es2021: true, + }, + ignorePatterns: ['node_modules/*', '.next/*', '.out/*', '!.prettierrc.js'], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:react/recommended', + 'plugin:react-hooks/recommended', + 'plugin:jsx-a11y/recommended', + ], + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + ecmaVersion: 12, + sourceType: 'module', + }, + plugins: ['react', '@typescript-eslint'], + rules: { + 'jsx-quotes': ['error', 'prefer-single'], + 'react/no-unescaped-entities': 'off', + 'react/prop-types': 'off', + 'react/react-in-jsx-scope': 'off', + 'jsx-a11y/anchor-is-valid': 'off', + 'jsx-a11y/no-noninteractive-element-interactions': 'off', + 'jsx-a11y/no-static-element-interactions': 'off', + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-unused-vars': ['warn'], + indent: ['error', 'tab'], + quotes: ['error', 'single'], + semi: ['error', 'never'], + }, +} diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..6ab880d --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,78 @@ +# 기여하기 + +## 이슈를 등록하기 전에 + +### 버그 + +먼저 지원하는 기기인지 확인합니다. + +#### 지원하지 않는 기기 + +```md +- 어떠한 확장프로그램 (AdBlock, Darkmode etc.) +- 브라우저: IE, Pre 17 Edge. +- Windows 7 이전의 Windows +- 10.10 버전 이하의 macOS +- 10.0 버전 이하의 iOS +- 5.0 버전 이하의 안드로이드 +- 3.5" 아이폰 +- 모든 VM +- 탈옥 또는 루팅된 기기 +- 공식 지원 종료된 모든 리눅스 버전 +- 보안 이슈 (보안과 관련된 문제는 비공개적이게 개발자에게 전달해주세요) +- 정식빌드에서는 발생하지 않는 Canary혹은 PTB와 같은 베타 버전의 브라우저/OS에서 발생하는 버그 +- 이외 개발자가 지원 종료 선언한 모든 플랫폼혹은 기기 +``` + +그 다음 이슈를 등록합니다. +[등록하기](https://github.com/koreanbots/koreanbots/issues/new/choose) + +**이슈에서는 빠른 소통을 위해 약자를 사용합니다.** +이슈를 보신다면 댓글을 남겨주세요. + +- `CR` **Can Reproduce** 의 약자로 재현 가능한 버그라는 뜻입니다. +- `CNR` **Can Not Reproduce** 의 약자로 재현이 불가능하다는 뜻입니다. +- `NAB` **Not a Bug** 의 약자로 버그에 해당하지 않는다는 뜻입니다. + +#### 승인과 거부 + +버그는 2개의 재현가능 여부에 대한 승인(Approve) 또는 거부(Deny)를 받게되면, 승인과 거부가 결정됩니다. + +##### 승인 + +버그가 재현 가능하다고 2명 이상의 유저에게 승인이 된다면, 해당 버그는 개발자의 확인을 기다리며, `approved` 라벨을 획득합니다. + +##### 거부 + +버그가 재현 가능하지않다고 2명 이상의 유저에게 거부가 된다면, 해당 버그는 `deny` 라벨을 획득하며, 이슈는 `Closed` 처리됩니다. + +### 제안 + +제안은 [Discussions](https://github.com/koreanbots/koreanbots/discussions)에서 자유롭게 해주세요! + +## 관리 + +이슈는 관리자와 버그 헌터분들이 관리합니다. + +### 버그 헌터란? + +버그 헌터는 버그를 열심히 찾아주시거나, 해당 레포지토리에 활발하게 참여하여, 특정 기준 이상을 참여해주신 유저분들에게 지급해드리는 권한입니다. + +버그헌터는 이슈를 닫거나, 라벨을 추가할 수 있으며 `Approve`와 `Deny`와 같은 상태를 관리합니다. + +### 처벌 + +이슈에서 장난식 발언을 하거나, 관련성이 없는 말 또는 스팸을 게시한다면, 통보없이 처벌되실 수 있습니다. + +## 기여 + +기여는 언제든 환영입니다 커밋메세지는 다음 규칙을 따라주시면 감사하겠습니다! + +[Conventional Commits](https://www.conventionalcommits.org/ko/v1.0.0/) + +--- + +### 기존 레포들 + +- [client](https://github.com/koreanbots/client) +- [api](https://github.com/koreanbots/api) diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug_report.md similarity index 93% rename from .github/ISSUE_TEMPLATE/bug.md rename to .github/ISSUE_TEMPLATE/bug_report.md index acccc8a..57c9b96 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,32 +1,40 @@ --- -name: 🐛 버그 제보 +name: "\U0001F41B 버그 제보" about: 버그를 제보해주세요! title: "[버그] " -labels: 'bug' +labels: bug assignees: '' --- ## 재현방법 + > 어떻게하면 발생시킬 수 있나요? ## 예상되는 정상적인 동작 + > 정상이라면 어떻게 되야하나요? ## 발생한 문제 + > 어떤 문제가 발생하나요? ## 클라이언트 버전 + > 클라이언트 버전을 알려주세요! + + ## 사양 + > OS 정보와 브라우저의 버전을 알려주세요! ## 확인 + - [ ] 중복되는 이슈는 없나요? - [ ] 해당 버그를 다시 발생시킬 수 있나요? diff --git a/.github/assets/koreanbots-en.png b/.github/assets/koreanbots-en.png new file mode 100644 index 0000000..d67d19e Binary files /dev/null and b/.github/assets/koreanbots-en.png differ diff --git a/.github/assets/koreanbots-ko.png b/.github/assets/koreanbots-ko.png new file mode 100644 index 0000000..823fd5d Binary files /dev/null and b/.github/assets/koreanbots-ko.png differ diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 0000000..c084aec --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,7 @@ +{ + "labels": ["meta: dependencies"], + "reviewers": ["team:core-developer"], + "schedule": ["before 8am"], + "extends": ["config:base"], + "timezone": "Asia/Seoul" +} diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml new file mode 100644 index 0000000..80a1b01 --- /dev/null +++ b/.github/workflows/testing.yml @@ -0,0 +1,92 @@ +name: CI +on: + push: + branches: + - 'master' + - 'stable' + pull_request: + branches: + - '*' +jobs: + eslint: + name: ESLint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: install node v14 + uses: actions/setup-node@v2 + with: + node-version: 14 + - name: yarn install + run: yarn install + - name: run eslint + run: yarn lint + env: + CI: true + test: + name: Run Test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: install node v14 + uses: actions/setup-node@v2 + with: + node-version: 14 + - name: yarn install + run: yarn install + - name: Setup MySQL + uses: getong/mariadb-action@v1.1 + with: + mysql database: 'discordbots' + mysql root password: 'test' + - name: Wait for MySQL + run: | + while ! mysqladmin ping --host=127.0.0.1 --password=test --silent; do + sleep 1 + done + - name: Run Jest + run: yarn test + - name: Generate RSA Key Pair + run: | + ssh-keygen -b 2048 -t rsa -f key -q -P "" + ssh-keygen -b 2048 -e -m pem -f key -q -P "" > private.key + mv key public.pem + rm key.pub + - name: Setup environments + run: | + mv .env.demo.local .env.production.local + printf 'MARIADB_ROOT_PASSWORD=YOUSHALLNOTPASS\nCOMMIT_HASH=${{ github.sha }}' > .env + - name: Create needed files + run: echo '{"tester":"DEMO_KEY"}' > secret.json + - name: Build + run: yarn build + env: + CI: true + + # docker: + # needs: + # - eslint + # - build + # - test + # name: Docker Image CI + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v2 + # - name: install node v14 + # uses: actions/setup-node@v1 + # with: + # node-version: 14 + # - name: Generate RSA Key Pair + # run: | + # ssh-keygen -b 2048 -t rsa -f key -q -P "" + # ssh-keygen -b 2048 -e -m pem -f key -q -P "" > private.key + # mv key public.pem + # rm key.pub + # - name: Setup environments + # run: | + # mv .env.demo.local .env.production.local + # printf 'MARIADB_ROOT_PASSWORD=YOUSHALLNOTPASS\nCOMMIT_HASH=${{ github.sha }}' > .env + # - name: Create needed files + # run: echo '{"tester":"DEMO_KEY"}' > secret.json + # - name: Docker Compose + # run: docker-compose up -d diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4939a0a --- /dev/null +++ b/.gitignore @@ -0,0 +1,46 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem +*.key + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# docker env file +.env + +# local env files +.env.local +.env.development.local +.env.test.local +.env.production.local +.env.*.production.local +.env.mysql.local + +# vercel +.vercel + +# Prevent commiting lock file. +package-lock.json + +# sub module +api-docs/ \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e2f7d2c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "api-docs"] + path = api-docs + url = https://github.com/koreanbots/api-docs + branch = master diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..9b76e35 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +.next/ +node_modules/ \ No newline at end of file diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..c41c7fd --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,11 @@ +module.exports = { + // Change your rules accordingly to your coding style preferences. + // https://prettier.io/docs/en/options.html + semi: false, + trailingComma: 'es5', + singleQuote: true, + printWidth: 100, + tabWidth: 2, + useTabs: true, + plugins: ['prettier-plugin-tailwind'] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..eca599f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "editor.formatOnSave": false, + "editor.tabSize": 2, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true + } +} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ff86cd6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,36 @@ +FROM node:14.16-alpine + +# install packages +RUN apk update && apk upgrade && \ + apk add --no-cache bash git openssh python3 py3-pip build-base + +# Create app directory +RUN mkdir -p /usr/src/app +WORKDIR /usr/src/app + +# Get Argument +ARG NEXT_PUBLIC_SENTRY_DSN +ARG SENTRY_DSN +ARG SENTRY_AUTH_TOKEN + +ENV NEXT_PUBLIC_SENTRY_DSN $NEXT_PUBLIC_SENTRY_DSN +ENV SENTRY_DSN $SENTRY_DSN +ENV SENTRY_AUTH_TOKEN $SENTRY_AUTH_TOKEN +ENV SENTRY_ORG koreanbots +ENV SENTRY_PROJECT api +# Installing dependencies +COPY package*.json /usr/src/app/ +COPY yarn.lock /usr/src/app/ +RUN yarn install + +# Copying source files +COPY . /usr/src/app + + +RUN printf "NEXT_PUBLIC_TESTER_KEY=9f9c4a7ae9afeb045fe818ed8b741c70b1d25ec236b189566a0db020c5596441\nNEXT_PUBLIC_COMMIT_HASH=$(git rev-parse HEAD)\nNEXT_PUBLIC_BRANCH=$(git branch | sed -n -e 's/^\* \(.*\)/\1/p')" > .env.local + +# Building app +RUN yarn build + +# Running the app +CMD yarn start \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3a81e3b --- /dev/null +++ b/LICENSE @@ -0,0 +1,677 @@ +GNU AFFERO GENERAL PUBLIC LICENSE + +Version 3, 19 November 2007 + +Copyright (C) Koreanbots + +Everyone is permitted to copy and distribute verbatim copies of +this license document, but changing it is not allowed. + +Preamble + +The GNU Affero +General Public License is a free, copyleft license for software and other kinds +of works, specifically designed to ensure cooperation with the community in the +case of network server software. + +The licenses for most software and other +practical works are designed to take away your freedom to share and change the +works. By contrast, our General Public Licenses are intended to guarantee your +freedom to share and change all versions of a program--to make sure it remains +free software for all its users. + +When we speak of free software, we are +referring to freedom, not price. Our General Public Licenses are designed to make +sure that you have the freedom to distribute copies of free software (and charge +for them if you wish), that you receive source code or can get it if you want it, +that you can change the software or use pieces of it in new free programs, and +that you know you can do these things. + +Developers that use our General Public +Licenses protect your rights with two steps: (1) assert copyright on the +software, and (2) offer you this License which gives you legal permission to +copy, distribute and/or modify the software. + +A secondary benefit of defending +all users' freedom is that improvements made in alternate versions of the +program, if they receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and encouraged by the +resulting cooperation. However, in the case of software used on network servers, +this result may fail to come about. The GNU General Public License permits making +a modified version and letting the public access it on a server without ever +releasing its source code to the public. + +The GNU Affero General Public License +is designed specifically to ensure that, in such cases, the modified source code +becomes available to the community. It requires the operator of a network server +to provide the source code of the modified version running there to the users of +that server. Therefore, public use of a modified version, on a publicly +accessible server, gives the public access to the source code of the modified +version. + +An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is a +different license, not a version of the Affero GPL, but Affero has released a new +version of the Affero GPL which permits relicensing under this license. + +The +precise terms and conditions for copying, distribution and modification +follow. + +TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to +version 3 of the GNU Affero General Public License. + + "Copyright" also means +copyright-like laws that apply to other kinds of works, such as semiconductor +masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and "recipients" may be +individuals or organizations. + + To "modify" a work means to copy from or adapt +all or part of the work in a fashion requiring copyright permission, other than +the making of an exact copy. The resulting work is called a "modified version" of +the earlier work or a work "based on" the earlier work. + + A "covered work" +means either the unmodified Program or a work based on the Program. + + To +"propagate" a work means to do anything with it that, without permission, would +make you directly or secondarily liable for infringement under applicable +copyright law, except executing it on a computer or modifying a private copy. +Propagation includes copying, distribution (with or without modification), making +available to the public, and in some countries other activities as well. + + To +"convey" a work means any kind of propagation that enables other parties to make +or receive copies. Mere interaction with a user through a computer network, with +no transfer of a copy, is not conveying. + + An interactive user interface +displays "Appropriate Legal Notices" to the extent that it includes a convenient +and prominently visible feature that (1) displays an appropriate copyright +notice, and (2) tells the user that there is no warranty for the work (except to +the extent that warranties are provided), that licensees may convey the work +under this License, and how to view a copy of this License. If the interface +presents a list of user commands or options, such as a menu, a prominent item in +the list meets this criterion. + + 1. Source Code. + + The "source code" for a +work means the preferred form of the work for making modifications to it. "Object +code" means any non-source form of a work. + + A "Standard Interface" means an +interface that either is an official standard defined by a recognized standards +body, or, in the case of interfaces specified for a particular programming +language, one that is widely used among developers working in that language. + + +The "System Libraries" of an executable work include anything, other than the +work as a whole, that (a) is included in the normal form of packaging a Major +Component, but which is not part of that Major Component, and (b) serves only to +enable use of the work with that Major Component, or to implement a Standard +Interface for which an implementation is available to the public in source code +form. A "Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system (if any) on +which the executable work runs, or a compiler used to produce the work, or an +object code interpreter used to run it. + + The "Corresponding Source" for a work +in object code form means all the source code needed to generate, install, and +(for an executable work) run the object code and to modify the work, including +scripts to control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free programs +which are used unmodified in performing those activities but which are not part +of the work. For example, Corresponding Source includes interface definition +files associated with source files for the work, and the source code for shared +libraries and dynamically linked subprograms that the work is specifically +designed to require, such as by intimate data communication or control flow +between those + + subprograms and other parts of the work. + + The Corresponding +Source need not include anything that users can regenerate automatically from +other parts of the Corresponding Source. + + The Corresponding Source for a work +in source code form is that same work. + + 2. Basic Permissions. + + All rights +granted under this License are granted for the term of copyright on the Program, +and are irrevocable provided the stated conditions are met. This License +explicitly affirms your unlimited permission to run the unmodified Program. The +output from running a covered work is covered by this License only if the output, +given its content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may +make, run and propagate covered works that you do not convey, without conditions +so long as your license otherwise remains in force. You may convey covered works +to others for the sole purpose of having them make modifications exclusively for +you, or provide you with facilities for running those works, provided that you +comply with the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works for you +must do so exclusively on your behalf, under your direction and control, on terms +that prohibit them from making any copies of your copyrighted material outside +their relationship with you. + + Conveying under any other circumstances is +permitted solely under the conditions stated below. Sublicensing is not allowed; +section 10 makes it unnecessary. + + 3. Protecting Users' Legal Rights From +Anti-Circumvention Law. + + No covered work shall be deemed part of an effective +technological measure under any applicable law fulfilling obligations under +article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar +laws prohibiting or restricting circumvention of such measures. + + When you +convey a covered work, you waive any legal power to forbid circumvention of +technological measures to the extent such circumvention is effected by exercising +rights under this License with respect to the covered work, and you disclaim any +intention to limit operation or modification of the work as a means of enforcing, +against the work's users, your or third parties' legal rights to forbid +circumvention of technological measures. + + 4. Conveying Verbatim Copies. + + +You may convey verbatim copies of the Program's source code as you receive it, in +any medium, provided that you conspicuously and appropriately publish on each +copy an appropriate copyright notice; keep intact all notices stating that this +License and any non-permissive terms added in accord with section 7 apply to the +code; keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any +price or no price for each copy that you convey, and you may offer support or +warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You +may convey a work based on the Program, or the modifications to produce it from +the Program, in the form of source code under the terms of section 4, provided +that you also meet all of these conditions: + + a) The work must carry +prominent notices stating that you modified it, and giving a relevant date. + + +b) The work must carry prominent notices stating that it is released under this +License and any conditions added under section 7. This requirement modifies the +requirement in section 4 to "keep intact all notices". + + c) You must license +the entire work, as a whole, under this License to anyone who comes into +possession of a copy. This License will therefore apply, along with any +applicable section 7 additional terms, to the whole of the work, and all its +parts, regardless of how they are packaged. This License gives no permission to +license the work in any other way, but it does not invalidate such permission if +you have separately received it. + + d) If the work has interactive user +interfaces, each must display Appropriate Legal Notices; however, if the Program +has interactive interfaces that do not display Appropriate Legal Notices, your +work need not make them do so. + + A compilation of a covered work with other +separate and independent works, which are not by their nature extensions of the +covered work, and which are not combined with it such as to form a larger +program, in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not used to limit +the access or legal rights of the compilation's users beyond what the individual +works permit. Inclusion of a covered work in an aggregate does not cause this +License to apply to the other parts of the aggregate. + + 6. Conveying Non-Source +Forms. + + You may convey a covered work in object code form under the terms of +sections 4 and 5, provided that you also convey the machine-readable +Corresponding Source under the terms of this License, in one of these ways: + + +a) Convey the object code in, or embodied in, a physical product (including a +physical distribution medium), accompanied by the Corresponding Source fixed on a +durable physical medium customarily used for software interchange. + + b) +Convey the object code in, or embodied in, a physical product (including a +physical distribution medium), accompanied by a written offer, valid for at least +three years and valid for as long as you offer spare parts or customer support +for that product model, to give anyone who possesses the object code either (1) a +copy of the Corresponding Source for all the software in the product that is +covered by this License, on a durable physical medium customarily used for +software interchange, for a price no more than your reasonable cost of physically +performing this conveying of source, or (2) access to copy the Corresponding +Source from a network server at no charge. + + c) Convey individual copies of +the object code with a copy of the written offer to provide the Corresponding +Source. This alternative is allowed only occasionally and noncommercially, and +only if you received the object code with such an offer, in accord with +subsection 6b. + + d) Convey the object code by offering access from a +designated place (gratis or for a charge), and offer equivalent access to the +Corresponding Source in the same way through the same place at no further charge. +You need not require recipients to copy the Corresponding Source along with the +object code. If the place to copy the object code is a network server, the +Corresponding Source may be on a different server (operated by you or a third +party) that supports equivalent copying facilities, provided you maintain clear +directions next to the object code saying where to find the Corresponding Source. +Regardless of what server hosts the Corresponding Source, you remain obligated to +ensure that it is available for as long as needed to satisfy these +requirements. + + e) Convey the object code using peer-to-peer transmission, +provided you inform other peers where the object code and Corresponding Source of +the work are being offered to the general public at no charge under subsection +6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be included in +conveying the object code work. + + A "User Product" is either (1) a "consumer +product", which means any tangible personal property which is normally used for +personal, family, or household purposes, or (2) anything designed or sold for +incorporation into a dwelling. In determining whether a product is a consumer +product, doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a typical or +common use of that class of product, regardless of the status of the particular +user or of the way in which the particular user actually uses, or expects or is +expected to use, the product. A product is a consumer product regardless of +whether the product has substantial commercial, industrial or non-consumer uses, +unless such uses represent the only significant mode of use of the product. + + +"Installation Information" for a User Product means any methods, procedures, +authorization keys, or other information required to install and execute modified +versions of a covered work in that User Product from a modified version of its +Corresponding Source. The information must suffice to ensure that the continued +functioning of the modified object code is in no case prevented or interfered +with solely because modification has been made. + + If you convey an object code +work under this section in, or with, or specifically for use in, a User Product, +and the conveying occurs as part of a transaction in which the right of +possession and use of the User Product is transferred to the recipient in +perpetuity or for a fixed term (regardless of how the transaction is +characterized), the Corresponding Source conveyed under this section must be +accompanied by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install modified object +code on the User Product (for example, the work has been installed in ROM). + + +The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates for a +work that has been modified or installed by the recipient, or for the User +Product in which it has been modified or installed. Access to a network may be +denied when the modification itself materially and adversely affects the +operation of the network or violates the rules and protocols for communication +across the network. + + Corresponding Source conveyed, and Installation +Information provided, in accord with this section must be in a format that is +publicly documented (and with an implementation available to the public in source +code form), and must require no special password or key for unpacking, reading or +copying. + + 7. Additional Terms. + + "Additional permissions" are terms that +supplement the terms of this License by making exceptions from one or more of its +conditions. Additional permissions that are applicable to the entire Program +shall be treated as though they were included in this License, to the extent that +they are valid under applicable law. If additional permissions apply only to part +of the Program, that part may be used separately under those permissions, but the +entire Program remains governed by this License without regard to the additional +permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of it. +(Additional permissions may be written to require their own removal in certain +cases when you modify the work.) You may place additional permissions on +material, added by you to a covered work, for which you have or can give +appropriate copyright permission. + + Notwithstanding any other provision of this +License, for material you add to a covered work, you may (if authorized by the +copyright holders of that material) supplement the terms of this License with +terms: + + a) Disclaiming warranty or limiting liability differently from the +terms of sections 15 and 16 of this License; or + + b) Requiring preservation +of specified reasonable legal notices or author attributions in that material or +in the Appropriate Legal Notices displayed by works containing it; or + + c) +Prohibiting misrepresentation of the origin of that material, or requiring that +modified versions of such material be marked in reasonable ways as different from +the original version; or + + d) Limiting the use for publicity purposes of +names of licensors or authors of the material; or + + e) Declining to grant +rights under trademark law for use of some trade names, trademarks, or service +marks; or + + f) Requiring indemnification of licensors and authors of that +material by anyone who conveys the material (or modified versions of it) with +contractual assumptions of liability to the recipient, for any liability that +these contractual assumptions directly impose on those licensors and authors. + + +All other non-permissive additional terms are considered "further restrictions" +within the meaning of section 10. If the Program as you received it, or any part +of it, contains a notice stating that it is governed by this License along with a +term that is a further restriction, you may remove that term. If a license +document contains a further restriction but permits relicensing or conveying +under this License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does not survive +such relicensing or conveying. + + If you add terms to a covered work in accord +with this section, you must place, in the relevant source files, a statement of +the additional terms that apply to those files, or a notice indicating where to +find the applicable terms. + + Additional terms, permissive or non-permissive, +may be stated in the form of a separately written license, or stated as +exceptions; the above requirements apply either way. + + 8. Termination. + + You +may not propagate or modify a covered work except as expressly provided under +this License. Any attempt otherwise to propagate or modify it is void, and will +automatically terminate your rights under this License (including any patent +licenses granted under the third paragraph of section 11). + + However, if you +cease all violation of this License, then your license from a particular +copyright holder is reinstated (a) provisionally, unless and until the copyright +holder explicitly and finally terminates your license, and (b) permanently, if +the copyright holder fails to notify you of the violation by some reasonable +means prior to 60 days after the cessation. + + Moreover, your license from a +particular copyright holder is reinstated permanently if the copyright holder +notifies you of the violation by some reasonable means, this is the first time +you have received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after your receipt +of the notice. + + Termination of your rights under this section does not +terminate the licenses of parties who have received copies or rights from you +under this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same material +under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are +not required to accept this License in order to receive or run a copy of the +Program. Ancillary propagation of a covered work occurring solely as a +consequence of using peer-to-peer transmission to receive a copy likewise does +not require acceptance. However, nothing other than this License grants you +permission to propagate or modify any covered work. These actions infringe +copyright if you do not accept this License. Therefore, by modifying or +propagating a covered work, you indicate your acceptance of this License to do +so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you +convey a covered work, the recipient automatically receives a license from the +original licensors, to run, modify and propagate that work, subject to this +License. You are not responsible for enforcing compliance by third parties with +this License. + + An "entity transaction" is a transaction transferring control +of an organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered work results +from an entity transaction, each party to that transaction who receives a copy of +the work also receives whatever licenses to the work the party's predecessor in +interest had or could give under the previous paragraph, plus a right to +possession of the Corresponding Source of the work from the predecessor in +interest, if the predecessor has it or can get it with reasonable efforts. + + +You may not impose any further restrictions on the exercise of the rights granted +or affirmed under this License. For example, you may not impose a license fee, +royalty, or other charge for exercise of rights granted under this License, and +you may not initiate litigation (including a cross-claim or counterclaim in a +lawsuit) alleging that any patent claim is infringed by making, using, selling, +offering for sale, or importing the Program or any portion of it. + + 11. +Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The work thus +licensed is called the contributor's "contributor version". + + A contributor's +"essential patent claims" are all patent claims owned or controlled by the +contributor, whether already acquired or hereafter acquired, that would be +infringed by some manner, permitted by this License, of making, using, or selling +its contributor version, but do not include claims that would be infringed only +as a consequence of further modification of the contributor version. For purposes +of this definition, "control" includes the right to grant patent sublicenses in a +manner consistent with the requirements of this License. + + Each contributor +grants you a non-exclusive, worldwide, royalty-free patent license under the +contributor's essential patent claims, to make, use, sell, offer for sale, import +and otherwise run, modify and propagate the contents of its contributor +version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent (such as an +express permission to practice a patent or covenant not to s ue for patent +infringement). To "grant" such a patent license to a party means to make such an +agreement or commitment not to enforce a patent against the party. + + If you +convey a covered work, knowingly relying on a patent license, and the +Corresponding Source of the work is not available for anyone to copy, free of +charge and under the terms of this License, through a publicly available network +server or other readily accessible means, then you must either (1) cause the +Corresponding Source to be so available, or (2) arrange to deprive yourself of +the benefit of the patent license for this particular work, or (3) arrange, in a +manner consistent with the requirements of this License, to extend the patent + + +license to downstream recipients. "Knowingly relying" means you have actual +knowledge that, but for the patent license, your conveying the covered work in a +country, or your recipient's use of the covered work in a country, would infringe +one or more identifiable patents in that country that you have reason to believe +are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a covered work, +and grant a patent license to some of the parties receiving the covered work +authorizing them to use, propagate, modify or convey a specific copy of the +covered work, then the patent license you grant is automatically extended to all +recipients of the covered work and works based on it. + + A patent license is +"discriminatory" if it does not include within the scope of its coverage, +prohibits the exercise of, or is conditioned on the non-exercise of one or more +of the rights that are specifically granted under this License. You may not +convey a covered work if you are a party to an arrangement with a third party +that is in the business of distributing software, under which you make payment to +the third party based on the extent of your activity of conveying the work, and +under which the third party grants, to any of the parties who would receive the +covered work from you, a discriminatory patent license (a) in connection with +copies of the covered work conveyed by you (or copies made from those copies), or +(b) primarily for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, or that +patent license was granted, prior to 28 March 2007. + + Nothing in this License +shall be construed as excluding or limiting any implied license or other defenses +to infringement that may otherwise be available to you under applicable patent +law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on +you (whether by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the conditions of this +License. If you cannot convey a covered work so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, then as a +consequence you may + + not convey it at all. For example, if you agree to terms +that obligate you to collect a royalty for further conveying from those to whom +you convey the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote +Network Interaction; Use with the GNU General Public License. + + Notwithstanding +any other provision of this License, if you modify the Program, your modified +version must prominently offer all users interacting with it remotely through a +computer network (if your version supports such interaction) an opportunity to +receive the Corresponding Source of your version by providing access to the +Corresponding Source from a network server at no charge, through some standard or +customary means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 of the +GNU General Public License that is incorporated pursuant to the following +paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed under version +3 of the GNU General Public License into a single combined work, and to convey +the resulting work. The terms of this License will continue to apply to the part +which is the covered work, but the work with which it is combined will remain +governed by version 3 of the GNU General Public License. + + 14. Revised Versions +of this License. + + The Free Software Foundation may publish revised and/or new +versions of the GNU Affero General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may differ in +detail to address new problems or concerns. + + Each version is given a +distinguishing version number. If the Program specifies that a certain numbered +version of the GNU Affero General Public License "or any later version" applies +to it, you have the option of following the terms and conditions either of that +numbered version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the GNU Affero +General Public License, you may choose any version ever published by the Free +Software Foundation. + + If the Program specifies that a proxy can decide which +future versions of the GNU Affero General Public License can be used, that +proxy's public statement of acceptance of a version permanently authorizes you to +choose that version for the Program. + + Later license versions may give you +additional or different permissions. However, no additional obligations are +imposed on any author or copyright holder as a result of your choosing to follow +a later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE +PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED +IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" +WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY +COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS +PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, +INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE +THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED +INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE +PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY +HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + 17. Interpretation of +Sections 15 and 16. + +If the disclaimer of warranty and limitation of liability +provided above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates an absolute +waiver of all civil liability in connection with the Program, unless a warranty +or assumption of liability accompanies a copy of the Program in return for a fee. +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If +you develop a new program, and you want it to be of the greatest possible use to +the public, the best way to achieve this is to make it free software which +everyone can redistribute and change under these terms. + +To do so, attach the +following notices to the program. It is safest to attach them to the start of +each source file to most effectively state the exclusion of warranty; and each +file should have at least the "copyright" line and a pointer to where the full +notice is found. + + + +Copyright (C) 2021 + +This program is free software: +you can redistribute it and/or modify it under the terms of the GNU Affero +General Public License as published by the Free Software Foundation, either +version 3 of the License, or (at your option) any later version. + +This program is +distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU Affero General Public License for more details. + +You should have +received a copy of the GNU Affero General Public License along with this program. +If not, see . + +Also add information on how to +contact you by electronic and paper mail. + +If your software can interact with +users remotely through a computer network, you should also make sure that it +provides a way for users to get its source. For example, if your program is a web +application, its interface could display a "Source" link that leads users to an +archive of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the specific +requirements. + +You should also get your employer (if you work as a programmer) or +school, if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. \ No newline at end of file diff --git a/README.en.md b/README.en.md new file mode 100644 index 0000000..bc16687 --- /dev/null +++ b/README.en.md @@ -0,0 +1,85 @@ +
+ +
+ +![Tests](https://github.com/koreanbots/koreanbots/workflows/Tests/badge.svg) +![Deploy](https://github.com/koreanbots/koreanbots/workflows/Deploy/badge.svg) +[![DeepScan grade](https://deepscan.io/api/teams/12468/projects/15503/branches/310734/badge/grade.svg)](https://deepscan.io/dashboard#view=project&tid=12468&pid=15503&bid=310734) + +> Korean Discord Bots in one place. + +# SNS + +- [Twitter](https://twitter.com/koreanbots) +- [Instagram](https://instagram.com/koreanbots) + +# Contact + +- [Developer Email](mailto:wonderlandpark@callisto.team) +- [Discord](https://discord.gg/JEh53MQ) + +# Contributing + +Issues and PRs are always welcomed. + +## Before submitting an Issue + +### Bug + +First, check if the device supports it. + +### Devices not supported + +```md +- Any extension program (AdBlock, Darkmode etc.) +- Browser: IE, Pre 17 Edge. +- Windows prior to Windows 7 +- MacOS version 10.10 or lower +- iOS version 10.0 or lower +- Android version 5.0 or lower +- 3.5" iPhone +- All VMs +- Jailbroken or rooted device +- All Linux versions that have ended official support +- Security issues (Please forward security-related issues to the developer privately) +- Bugs that do not occur in the official build, occur in the browser/OS of beta versions such as Canary or PTB +- All platforms or devices that other developers have declared end of support +``` + +Then register the issue. +[Submit](https://github.com/koreanbots/koreanbots/issues/new/choose) + +If you see an issue, please leave a comment like these. + +- `CR` Means **Can Reproduce** +- `CNR` Means **Can Not Reproduce** +- `NAB` Means **Not a Bug** + +### Approval and deny + +When a bug receives two reproducible approvals or denial, the approval and rejection are decided. + +#### Approve + +If a bug is approved by more than two user as reproducible, the bug waits for confirmation from the developer and obtains a `approved` label. + +#### Deny + +If a bug is rejected by more than one user because it is not reproducible, the bug gets a `deny` label and the issue is `Closed`. + +### Suggestions + +Please feel free to make suggestions at [Discussions](https://github.com/koreanbots/koreanbots/discussions)! + +## Submit Pull Request + +Contributions are always welcome. We appreciate your commit messages if you follow the rules below! + +[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) + +--- + +### Old Repositories + +- [client](https://github.com/koreanbots/client) +- [api](https://github.com/koreanbots/api) diff --git a/README.md b/README.md index ba5d826..74a16c5 100644 --- a/README.md +++ b/README.md @@ -1,82 +1,46 @@ -# koreanbots +
+ + + +
+ +![Tests](https://github.com/koreanbots/koreanbots/workflows/Tests/badge.svg) +![Deploy](https://github.com/koreanbots/koreanbots/workflows/Deploy/badge.svg) +[![DeepScan grade](https://deepscan.io/api/teams/12468/projects/15503/branches/310734/badge/grade.svg)](https://deepscan.io/dashboard#view=project&tid=12468&pid=15503&bid=310734) + +[Introduced in English](./README.en.md) > 국내 디스코드봇을 한곳에서. -## 여긴 뭔가요? +# SNS -이 공간은 버그와 제안을 관리하기 위한 공간입니다. +- [Twitter](https://twitter.com/koreanbots) +- [Instagram](https://instagram.com/koreanbots) -## 이슈를 등록하기 전에 +# 문의 -### 버그 +- [개발자 이메일](mailto:wonderlandpark@callisto.team) +- [디스코드](https://discord.gg/JEh53MQ) -먼저 지원하는 기기인지 확인합니다. +# 기여하기 -#### 지원하지 않는 기기 +이슈와 PR은 언제든지 환영입니다. -```md -- 어떠한 확장프로그램 (AdBlock, Darkmode etc.) -- 브라우저: IE, Pre 17 Edge. -- Windows 7 이전의 Windows -- 10.10 버전 이하의 macOS -- 10.0 버전 이하의 iOS -- 5.0 버전 이하의 안드로이드 -- 3.5" 아이폰 -- 모든 VM -- 탈옥 또는 루팅된 기기 -- 공식 지원 종료된 모든 리눅스 버전 -- 보안 이슈 (보안과 관련된 문제는 비공개적이게 개발자에게 전달해주세요) -- 정식빌드에서는 발생하지 않는 Canary혹은 PTB와 같은 베타 버전의 브라우저/OS에서 발생하는 버그 -- 이외 개발자가 지원 종료 선언한 모든 플랫폼혹은 기기 -``` +[기여 규칙](./.github/CONTRIBUTING.md) -그 다음 이슈를 등록합니다. -[등록하기](https://github.com/koreanbots/koreanbots/issues/new/choose) +## 기여자 -**이슈에서는 빠른 소통을 위해 약자를 사용합니다.** -이슈를 보신다면 댓글을 남겨주세요. + + + + + + + + +

Junseo Park

🚧 💼

zero734kr

👀
-- `CR` **Can Reproduce** 의 약자로 재현 가능한 버그라는 뜻입니다. -- `CNR` **Can Not Reproduce** 의 약자로 재현이 불가능하다는 뜻입니다. -- `NAB` **Not a Bug** 의 약자로 버그에 해당하지 않는다는 뜻입니다. + + -#### 승인과 거부 - -버그는 2개의 재현가능 여부에 대한 승인(Approve) 또는 거부(Deny)를 받게되면, 승인과 거부가 결정됩니다. - -##### 승인 - -버그가 재현 가능하다고 2명 이상의 유저에게 승인이 된다면, 해당 버그는 개발자의 확인을 기다리며, `approved` 라벨을 획득합니다. - -##### 거부 - -버그가 재현 가능하지않다고 2명 이상의 유저에게 거부가 된다면, 해당 버그는 `deny` 라벨을 획득하며, 이슈는 `Closed` 처리됩니다. - -### 제안 - -제안은 자유롭게 해주셔도 됩니다! - -## 관리 - -이슈는 관리자와 버그 헌터분들이 관리합니다. - -### 버그 헌터란? - -버그 헌터는 버그를 열심히 찾아주시거나, 해당 레포지토리에 활발하게 참여하여, 특정 기준 이상을 참여해주신 유저분들에게 지급해드리는 권한입니다. - -버그헌터는 이슈를 닫거나, 라벨을 추가할 수 있으며 `Approve`와 `Deny`와 같은 상태를 관리합니다. - -### 처벌 - -이슈에서 장난식 발언을 하거나, 관련성이 없는 말 또는 스팸을 게시한다면, 통보없이 처벌되실 수 있습니다. - -## 사이트 레포들 - -- [client](https://github.com/koreanbots/client) -- [api](https://github.com/koreanbots/api) - -### 기여 - -기여는 언제든 환영입니다 커밋메세지는 다음 규칙을 따라주시면 감사하겠습니다! - -[Conventional Commits](https://www.conventionalcommits.org/ko/v1.0.0/) \ No newline at end of file + diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..fbe4860 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,9 @@ +# Security Policy + +## Korean + +[버그 바운티 프로그램](https://beta.koreanbots.dev/security) + +## English + +Please [mail](mailto:koreanbots.dev@gmail.com) us! diff --git a/api-docs b/api-docs new file mode 160000 index 0000000..effc22e --- /dev/null +++ b/api-docs @@ -0,0 +1 @@ +Subproject commit effc22ea2b191f7cfd35e08a4545bc7879e61d24 diff --git a/app.css b/app.css new file mode 100644 index 0000000..5829e09 --- /dev/null +++ b/app.css @@ -0,0 +1,192 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +html { + scroll-behavior: smooth; + min-height: 100%; + overflow-x: hidden; + width: 100%; +} + +body { + min-height: 100vh; + width: 100%; +} + +body * { + outline: none; +} + +@font-face { + font-family: 'Uni Sans Heavy CAPS'; + src: url('/logofont.otf'); + font-display: swap; +} + +.logofont { + font-family: 'Uni Sans Heavy CAPS'; +} + +.animation-dropdown { + animation: dropdown 0.1s linear; +} + +.iu-is-the-best { + min-height: 100vh; +} + +.__control--is-focused { + border: none !important; + box-shadow: none !important; +} + +i { + width: 20px; +} + +/* html * ::-webkit-scrollbar { + -webkit-appearance: none; + width: 8px; + height: 8px; +} + +html * ::-webkit-scrollbar-thumb { + cursor: pointer; + border-radius: 5px; + background: #ccc; + -webkit-transition: color 0.2s ease; + transition: color 0.2s ease; +} + +html .dark * ::-webkit-scrollbar-thumb { + cursor: pointer; + border-radius: 5px; + background: #202225; + -webkit-transition: color 0.2s ease; + transition: color 0.2s ease; +} + +html * ::-webkit-scrollbar-track { + background: #f2f2f2; + border-radius: 0; + border: 4px solid transparent; + border-radius: 8px; +} + +html .dark * ::-webkit-scrollbar-track { + background: #2e3338; + border-radius: 0; +} */ + +.dark .__multi-value, +.dark .__multi-value__label, +.dark .__multi-value__remove { + background: #2e3338 !important; +} + +.scroll-none { + -ms-overflow-style: none; + scrollbar-width: none; +} + +.scroll-none ::-webkit-scrollbar { + display: none; +} + +button { + outline: none !important; +} + +.emoji-selector-button { + width: 24px; + height: 24px; + display: inline-block; + background-image: url('https://unpkg.com/emoji-datasource-twitter@5.0.1/img/twitter/sheets-256/64.png'); + background-size: 5700% 5700%; + background-position: 53.5714% 62.5%; + filter: grayscale(100%); +} + +.emoji-selector-button:hover { + filter: grayscale(0%); + transform: scale(1.1, 1.1); + opacity: 90%; + transition: ease-in 100ms; + cursor: pointer; +} + +.emoji-mart-category-list > *, +.emoji-mart-emoji > span { + cursor: pointer; +} + +.cursor-heart { + cursor: url("/img/heart.svg"), auto; +} + +/* NProgress */ + +#nprogress { + pointer-events: none; +} + +#nprogress .bar { + background: #3366FF; + + position: fixed; + z-index: 1031; + top: 0; + left: 0; + + width: 100%; + height: 1.5px; +} + +/* Fancy blur effect */ +#nprogress .peg { + display: block; + position: absolute; + right: 0px; + width: 100px; + height: 100%; + box-shadow: 0 0 10px #3366FF, 0 0 5px #3366FF; + opacity: 1.0; + transform: rotate(3deg) translate(0px, -4px); +} + +/* Remove these to get rid of the spinner */ +#nprogress .spinner { + display: block; + position: fixed; + z-index: 1031; + top: 15px; + right: 15px; +} + +#nprogress .spinner-icon { + width: 18px; + height: 18px; + box-sizing: border-box; + + border: solid 2px transparent; + border-top-color: #3366FF; + border-left-color: #3366FF; + border-radius: 50%; + animation: nprogress-spinner 400ms linear infinite; +} + +.nprogress-custom-parent { + overflow: hidden; + position: relative; +} + +.nprogress-custom-parent #nprogress .spinner, +.nprogress-custom-parent #nprogress .bar { + position: absolute; +} + +@keyframes nprogress-spinner { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} \ No newline at end of file diff --git a/components/Advertisement.tsx b/components/Advertisement.tsx new file mode 100644 index 0000000..d770ecb --- /dev/null +++ b/components/Advertisement.tsx @@ -0,0 +1,49 @@ +import { useEffect } from 'react' +import Logger from '@utils/Logger' + +const Advertisement: React.FC = ({ size = 'short' }) => { + useEffect(() => { + if (process.env.NODE_ENV === 'production') { + window.adsbygoogle = window.adsbygoogle || [] + window.adsbygoogle.push({}) + } + Logger.debug('Ads Pushed') + }, []) + + return ( +
+ {process.env.NODE_ENV === 'production' ? ( + + ) : ( + 'Advertisement' + )} +
+ ) +} + +declare global { + interface Window { + adsbygoogle: { + loaded?: boolean + push(obj: unknown): void + } + } +} + +interface AdvertisementProps { + size?: 'short' | 'tall' +} + +export default Advertisement diff --git a/components/Application.tsx b/components/Application.tsx new file mode 100644 index 0000000..9409bae --- /dev/null +++ b/components/Application.tsx @@ -0,0 +1,22 @@ +import dynamic from 'next/dynamic' +import Link from 'next/link' + +const DiscordAvatar = dynamic(() => import('@components/DiscordAvatar')) + +const Application: React.FC = ({ type, id, name }) => { + return +
+ +

{name}

+
+ + +} + +interface ApplicationProps { + type: 'bot' + id: string + name: string +} + +export default Application diff --git a/components/BotCard.tsx b/components/BotCard.tsx new file mode 100644 index 0000000..fd90048 --- /dev/null +++ b/components/BotCard.tsx @@ -0,0 +1,124 @@ +import Link from 'next/link' +import dynamic from 'next/dynamic' + +import { checkBotFlag, formatNumber, makeBotURL } from '@utils/Tools' +import { Status } from '@utils/Constants' +import { Bot } from '@types' + +const Divider = dynamic(() => import('@components/Divider')) +const Tag = dynamic(() => import('@components/Tag')) +const DiscordAvatar = dynamic(() => import('@components/DiscordAvatar')) + +const BotCard: React.FC = ({ manage = false, bot }) => { + return
+
+
+
+
+ +
+
+
+
+ +
+ +
+

+ + {Status[bot.status]?.text} +

+

{bot.name}

+
+
+
+ + {formatNumber(bot.votes)} + + } + dark + /> + {formatNumber(bot.servers)} 서버 : 'N/A'} + dark + /> +
+
+

+ {bot.intro} +

+
+
+ {bot.category.slice(0, 3).map(el => ( + + ))}{' '} + {bot.category.length > 3 && } +
+
+
+ + +
+
+ + + 보기 + + + {manage ? ( + + + 관리하기 + + + ) : bot.state !== 'ok' ? + 초대하기 + : + + 초대하기 + + } +
+
+
+
+
+
+
+ +} + +interface BotCardProps { + manage?: boolean + bot: Bot +} + +export default BotCard \ No newline at end of file diff --git a/components/Button.tsx b/components/Button.tsx new file mode 100644 index 0000000..7a588d9 --- /dev/null +++ b/components/Button.tsx @@ -0,0 +1,47 @@ +import Link from 'next/link' +import { ReactNode } from 'react' + +const Button: React.FC = ({ + type = 'button', + className, + children, + href, + disabled=false, + onClick, +}) => { + return href ? + + {children} + + + : onClick ? + : + +} + +interface ButtonProps { + type?: 'button' | 'submit' | 'reset' + className?: string + children: ReactNode + href?: string + disabled?: boolean + onClick?: () => void +} + +export default Button diff --git a/components/Captcha.tsx b/components/Captcha.tsx new file mode 100644 index 0000000..b04755c --- /dev/null +++ b/components/Captcha.tsx @@ -0,0 +1,15 @@ +import { Ref } from 'react' +import HCaptcha from '@hcaptcha/react-hcaptcha' + + +const Captcha: React.FC = ({ dark, onVerify }) => { + return +} + +interface CaptchaProps { + dark: boolean + onVerify(token: string, eKey?: string): void + ref?: Ref +} + +export default Captcha \ No newline at end of file diff --git a/components/ColorCard.tsx b/components/ColorCard.tsx new file mode 100644 index 0000000..66f6c32 --- /dev/null +++ b/components/ColorCard.tsx @@ -0,0 +1,21 @@ +const ColorCard: React.FC = ({ header, first, second, className }) => { + return ( +
+

{header}

+

+ {first} +
+ {second} +

+
+ ) +} + +interface ColorCardProps { + header: string + first: string + second: string + className: string +} + +export default ColorCard diff --git a/components/Container.tsx b/components/Container.tsx new file mode 100644 index 0000000..414be2f --- /dev/null +++ b/components/Container.tsx @@ -0,0 +1,27 @@ +import { ReactNode } from 'react' + +const Container: React.FC = ({ + ignoreColor, + className, + paddingTop = false, + children, +}) => { + return ( +
+
{children}
+
+ ) +} + +interface ContainerProps { + ignoreColor?: boolean + className?: string + paddingTop?: boolean + children: ReactNode +} + +export default Container diff --git a/components/DeveloperLayout.tsx b/components/DeveloperLayout.tsx new file mode 100644 index 0000000..169d536 --- /dev/null +++ b/components/DeveloperLayout.tsx @@ -0,0 +1,104 @@ +/* eslint-disable jsx-a11y/click-events-have-key-events */ +import dynamic from 'next/dynamic' +import Link from 'next/link' +import { ReactNode, useState } from 'react' + +import { DocsData } from '@types' +import { NextSeo } from 'next-seo' + +const Container = dynamic(() => import('@components/Container')) +const Divider = dynamic(() => import('@components/Divider')) + +const DeveloperLayout: React.FC = ({ children, enabled, docs, currentDoc }:DeveloperLayout) => { + const [ navbarEnabled, setNavbarOpen ] = useState(false) + + return
+ +
+
+
    +
  • + +
  • +
  • + +
  • + { + enabled === 'docs' && <> + +
  • setNavbarOpen(true)} onClick={() => setNavbarOpen(true)}> + +
  • + } +
+
+
+
+
+
    +
  • setNavbarOpen(false)} onClick={() => setNavbarOpen(false)}>닫기
  • + + +
  • + 나의 봇 +
  • + + +
  • + 문서 +
  • + +
+ { + enabled === 'docs' && <> + +
    +
  • setNavbarOpen(false)} className='lg:hidden cursor-pointer py-1 px-4 rounded-md mb-2'> + 닫기 +
  • + + { + docs?.map(el => { + if(el.list) return
    + {el.name} +
      + { + el.list.map(e => + +
    • setNavbarOpen(false)} className={`cursor-pointer px-4 py-2 rounded-md ${currentDoc === e.name ? 'bg-discord-blurple text-white' : 'hover:text-gray-500 dark:hover:text-white'}`}> + {e.name} +
    • + + ) + } +
    +
    + + return +
  • setNavbarOpen(false)} className={`cursor-pointer py-2 px-4 rounded-md ${currentDoc === el.name ? 'bg-discord-blurple text-white' : 'hover:text-gray-500 dark:hover:text-white'}`}> + {el.name} +
  • + + }) + } +
+ + } +
+
+
+ + {children} + +
+
+} + +interface DeveloperLayout { + children: ReactNode + enabled: 'applications' | 'docs' + docs?: DocsData[] + currentDoc?: string +} + +export default DeveloperLayout diff --git a/components/DiscordAvatar.tsx b/components/DiscordAvatar.tsx new file mode 100644 index 0000000..d248950 --- /dev/null +++ b/components/DiscordAvatar.tsx @@ -0,0 +1,60 @@ +import { SyntheticEvent, useEffect, useState } from 'react' +import { KoreanbotsEndPoints } from '@utils/Constants' +import { supportsWebP } from '@utils/Tools' +import Logger from '@utils/Logger' + +const DiscordAvatar: React.FC = props => { + const fallback = '/img/default.png' + const [ webpUnavailable, setWebpUnavailable ] = useState() + + useEffect(()=> { + setWebpUnavailable(localStorage.webp === 'false') + }, []) + + return {props.alt)=> { + if(webpUnavailable) { + (e.target as ImageTarget).onerror = (event) => { + // All Fails + (event.target as ImageTarget).onerror = ()=> { Logger.warn('FALLBACK IMAGE LOAD FAIL') } + (event.target as ImageTarget).src = fallback + + } + } + else { + (e.target as ImageTarget).onerror = (event) => { + // All Fails + (event.target as ImageTarget).onerror = ()=> { Logger.warn('FALLBACK IMAGE LOAD FAIL') } + (event.target as ImageTarget).src = fallback + } + // Webp Load Fail + (e.target as ImageTarget).src = KoreanbotsEndPoints.CDN.avatar(props.userID, { size: props.size ?? 256}) + if(!supportsWebP()) localStorage.setItem('webp', 'false') + } + }} + /> +} + +interface DiscordAvatarProps { + alt?: string + userID: string + className?: string + size? : 128 | 256 | 512 +} + +interface ImageEvent extends Event { + target: ImageTarget +} + +interface ImageTarget extends EventTarget { + src: string + onerror: (event: SyntheticEvent) => void +} + +export default DiscordAvatar diff --git a/components/Divider.tsx b/components/Divider.tsx new file mode 100644 index 0000000..1d116aa --- /dev/null +++ b/components/Divider.tsx @@ -0,0 +1,17 @@ +const Divider: React.FC = ({ className }) => { + return ( +
+ ) +} + +interface DividerProps { + className?: string +} + +export default Divider diff --git a/components/Docs.tsx b/components/Docs.tsx new file mode 100644 index 0000000..8cb455d --- /dev/null +++ b/components/Docs.tsx @@ -0,0 +1,38 @@ +import { NextSeo } from 'next-seo' +import dynamic from 'next/dynamic' + +const Container = dynamic(() => import('@components/Container')) + +const Docs: React.FC = ({ title, header, description, subheader, children }) => { + return ( + <> + +
+ +

+ {header} +

+

+ {description} +

+

+ {subheader} +

+
+
+ +
{children}
+
+ + ) +} + +export default Docs + +interface DocsProps { + header: string | React.ReactNode + title?: string + description?: string + subheader?: string + children: React.ReactNode +} diff --git a/components/Footer.tsx b/components/Footer.tsx new file mode 100644 index 0000000..fe01537 --- /dev/null +++ b/components/Footer.tsx @@ -0,0 +1,118 @@ +import Link from 'next/link' +import dynamic from 'next/dynamic' + +import { Theme } from '@types' + +const Container = dynamic(() => import('@components/Container')) +const Toggle = dynamic(() => import('@components/Toggle')) + +const Footer: React.FC = ({ theme, setTheme }) => { + return ( +
+
+ +
+

국내 디스코드 봇을 한 곳에서.

+ 2020-2021 Koreanbots, All rights reserved. +
+ + + + + + + + + + + +
+
+
+
+

한국 디스코드봇 리스트

+ +
+
+

정책

+ +
+
+

커뮤니티

+ +
+
+

기타

+
+ 다크모드 + { + const t = theme === 'dark' ? 'light' : 'dark' + setTheme(t) + localStorage.setItem('theme', t) + }} + /> +
+
+
+
+
+
+ ) +} + +interface FooterProps { + theme: Theme + setTheme(value: Theme): void +} + +export default Footer diff --git a/components/Forbidden.tsx b/components/Forbidden.tsx new file mode 100644 index 0000000..72232a8 --- /dev/null +++ b/components/Forbidden.tsx @@ -0,0 +1,26 @@ +import dynamic from 'next/dynamic' +import { useRouter } from 'next/router' +import { NextSeo } from 'next-seo' + +import { ErrorText } from '@utils/Constants' + +const Button = dynamic(() => import('@components/Button')) + +const Forbidden:React.FC = () => { + const router = useRouter() + return <> + +
+
+

403

+

+ {ErrorText[403]} +

+ +

해당 작업을 수행할 수 있는 권한이 없습니다. 무언가 잘못된 것 같다면 문의해주세요.

+
+
+ +} + +export default Forbidden diff --git a/components/Form/CheckBox.tsx b/components/Form/CheckBox.tsx new file mode 100644 index 0000000..f72350b --- /dev/null +++ b/components/Form/CheckBox.tsx @@ -0,0 +1,12 @@ +import { Field } from 'formik' + +const CheckBox: React.FC = ({ name, ...props }) => { + return +} + +interface CheckBoxProps { + name: string + [key: string]: unknown +} + +export default CheckBox diff --git a/components/Form/CsrfToken.tsx b/components/Form/CsrfToken.tsx new file mode 100644 index 0000000..be1c609 --- /dev/null +++ b/components/Form/CsrfToken.tsx @@ -0,0 +1,11 @@ +import { Field } from 'formik' + +const CsrfToken: React.FC = ({ token }) => { + return