Skip to content

Commit

Permalink
Merge pull request #69 from Magickbase/ckb_explorer_page
Browse files Browse the repository at this point in the history
feat: add ckb explorer page
  • Loading branch information
PainterPuppets authored Mar 14, 2024
2 parents 658db48 + bd8642c commit 8602d31
Show file tree
Hide file tree
Showing 78 changed files with 2,870 additions and 0 deletions.
21 changes: 21 additions & 0 deletions packages/explorer/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Since the ".env" file is gitignored, you can use the ".env.example" file to
# build a new ".env" file when you clone the repo. Keep this file up-to-date
# when you add new variables to `.env`.

# This file will be committed to version control, so make sure not to have any
# secrets in it. If you are cloning this repo, create a copy of this file named
# ".env" and populate it with your secrets.

# When adding additional environment variables, the schema in "/src/env.mjs"
# should be updated accordingly.

# Example:
# SERVERVAR="foo"
# NEXT_PUBLIC_CLIENTVAR="bar"
NEXT_PUBLIC_REPO=nervosnetwork/ckb-explorer

# For accessing api.github.com
# https://docs.github.com/en/rest/overview/authenticating-to-the-rest-api?apiVersion=2022-11-28
GITHUB_TOKEN=

UPTIME_KEY=
7 changes: 7 additions & 0 deletions packages/explorer/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/** @type {import("eslint").Linter.Config} */
const config = {
root: true,
extends: ['@magickbase-website/eslint-config/next.js'],
}

module.exports = config
9 changes: 9 additions & 0 deletions packages/explorer/.lintstagedrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const path = require('path')

const buildEslintCommand = filenames =>
`next lint --fix --file ${filenames.map(f => path.relative(process.cwd(), f)).join(' --file ')}`

module.exports = {
'*.{js,cjs,mjs,jsx,ts,tsx}': ['prettier --write', buildEslintCommand],
'*.{css,scss}': ['prettier --write', 'stylelint --fix'],
}
52 changes: 52 additions & 0 deletions packages/explorer/.stylelintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"overrides": [
{
"files": ["**/*.scss"],
"customSyntax": "postcss-scss"
}
],
"extends": [
"stylelint-config-standard-scss",
"stylelint-config-rational-order",
"stylelint-config-css-modules",
"stylelint-config-prettier-scss"
],
"rules": {
"selector-class-pattern": [
"^[a-z][a-zA-Z0-9]*$",
{
"message": "Expected class selector to be lowerCamelCase"
}
],
"custom-property-pattern": [
"^[a-z][a-zA-Z0-9]*$",
{
"message": "Expected custom property name to be lowerCamelCase"
}
],
"keyframes-name-pattern": [
"^[a-z][a-zA-Z0-9]*$",
{
"message": "Expected class selector to be lowerCamelCase"
}
],
"scss/dollar-variable-pattern": [
"^[a-z][a-zA-Z0-9]*$",
{
"message": "Expected variable to be lowerCamelCase"
}
],
"scss/percent-placeholder-pattern": [
"^[a-z][a-zA-Z0-9]*$",
{
"message": "Expected placeholder to be lowerCamelCase"
}
],
"scss/at-mixin-pattern": [
"^[a-z][a-zA-Z0-9]*$",
{
"message": "Expected mixin name to be lowerCamelCase"
}
]
}
}
120 changes: 120 additions & 0 deletions packages/explorer/i18next-parser.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { UserConfig } from 'i18next-parser'

const config: UserConfig = {
// Key separator used in your translation keys
contextSeparator: '_',

// Save the \_old files
createOldCatalogs: false,

// Default namespace used in your i18next config
defaultNamespace: 'translation',

defaultValue(locale, namespace, key) {
return key ?? ''
},

// Indentation of the catalog files
indentation: 2,

// Keep keys from the catalog that are no longer in code
// You may either specify a boolean to keep or discard all removed keys.
// You may also specify an array of patterns: the keys from the catalog that are no long in the code but match one of the patterns will be kept.
// The patterns are applied to the full key including the namespace, the parent keys and the separators.
keepRemoved: false,

// Key separator used in your translation keys
// If you want to use plain english keys, separators such as `.` and `:` will conflict. You might want to set `keySeparator: false` and `namespaceSeparator: false`. That way, `t('Status: Loading...')` will not think that there are a namespace and three separator dots for instance.
keySeparator: false,

// see below for more details
lexers: {
hbs: ['HandlebarsLexer'],
handlebars: ['HandlebarsLexer'],

htm: ['HTMLLexer'],
html: ['HTMLLexer'],

mjs: ['JavascriptLexer'],
js: ['JavascriptLexer'],
ts: [
{
lexer: 'JavascriptLexer',
functions: ['t', 'addI18nKey'],
namespaceFunctions: ['useTranslation', 'withTranslation', 'createI18nKeyAdder'],
},
],
jsx: ['JsxLexer'],
tsx: ['JsxLexer'],

default: ['JavascriptLexer'],
},

// Control the line ending. See options at https://github.com/ryanve/eol
lineEnding: 'lf',

// An array of the locales in your applications
locales: ['en', 'zh'],

// Namespace separator used in your translation keys
// If you want to use plain english keys, separators such as `.` and `:` will conflict. You might want to set `keySeparator: false` and `namespaceSeparator: false`. That way, `t('Status: Loading...')` will not think that there are a namespace and three separator dots for instance.
namespaceSeparator: false,

// Supports $LOCALE and $NAMESPACE injection
// Supports JSON (.json) and YAML (.yml) file formats
// Where to write the locale files relative to process.cwd()
output: 'public/locales/$LOCALE/$NAMESPACE.json',

// Plural separator used in your translation keys
// If you want to use plain english keys, separators such as `_` might conflict. You might want to set `pluralSeparator` to a different string that does not occur in your keys.
// If you don't want to generate keys for plurals (for example, in case you are using ICU format), set `pluralSeparator: false`.
pluralSeparator: '_',

// An array of globs that describe where to look for source files
// relative to the location of the configuration file
input: ['src/**/*.{ts,tsx}', '../shared/src/**/*.{ts,tsx}'],

// Whether or not to sort the catalog. Can also be a [compareFunction](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#parameters)
sort: true,

// Display info about the parsing including some stats
verbose: false,

// Exit with an exit code of 1 on warnings
failOnWarnings: false,

// Exit with an exit code of 1 when translations are updated (for CI purpose)
failOnUpdate: false,

// If you wish to customize the value output the value as an object, you can set your own format.
// ${defaultValue} is the default value you set in your translation function.
// Any other custom property will be automatically extracted.
//
// Example:
// {
// message: "${defaultValue}",
// description: "${maxLength}", // t('my-key', {maxLength: 150})
// }
customValueTemplate: null,

// The locale to compare with default values to determine whether a default value has been changed.
// If this is set and a default value differs from a translation in the specified locale, all entries
// for that key across locales are reset to the default value, and existing translations are moved to
// the `_old` file.
resetDefaultValueLocale: null,

// If you wish to customize options in internally used i18next instance, you can define an object with any
// configuration property supported by i18next (https://www.i18next.com/overview/configuration-options).
// { compatibilityJSON: 'v3' } can be used to generate v3 compatible plurals.
i18nextOptions: null,

// If you wish to customize options for yaml output, you can define an object here.
// Configuration options are here (https://github.com/nodeca/js-yaml#dump-object---options-).
// Example:
// {
// lineWidth: -1,
// }
yamlOptions: null,
}

export default config
21 changes: 21 additions & 0 deletions packages/explorer/next-i18next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* next-i18next not support mjs config
*/
/* eslint-disable @typescript-eslint/no-var-requires */

const path = require('path')

/**
* @type {import('next-i18next').UserConfig}
*/
module.exports = {
i18n: {
defaultLocale: 'en',
locales: ['en', 'zh'],
localeDetection: true,
},
fallbackNS: 'common',
localePath: typeof window === 'undefined' ? path.resolve('./public/locales') : '/locales',

reloadOnPrerender: process.env.NODE_ENV === 'development',
}
107 changes: 107 additions & 0 deletions packages/explorer/next.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
const i18nConfig = (await import('./next-i18next.config.js')).default

/**
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation.
* This is especially useful for Docker builds.
*/
!process.env.SKIP_ENV_VALIDATION && (await import('./src/env.mjs'))

/** @type {import("next").NextConfig} */
const config = {
reactStrictMode: true,

pageExtensions: ['tsx', 'ts', 'jsx', 'js'].map(suffix => `page.${suffix}`),

/**
* If you have the "experimental: { appDir: true }" setting enabled, then you
* must comment the below `i18n` config out.
*
* @see https://github.com/vercel/next.js/issues/41980
*/
i18n: i18nConfig.i18n,

images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'avatars.githubusercontent.com',
},
],
},

transpilePackages: ['@magickbase-website/shared'],

sassOptions: {
logger: {
warn: function (message) {
console.warn(message)
},
debug: function (message) {
console.log(message)
},
},
},

webpack(config) {
config.module.rules.push({
test: /\.svg$/i,
issuer: /\.[jt]sx?$/,
use: [
{
loader: '@svgr/webpack',
options: {
svgoConfig: {
plugins: [
{
name: 'preset-default',
params: {
overrides: {
removeViewBox: false,
},
},
},
],
},
},
},
],
})

// https://dhanrajsp.me/snippets/customize-css-loader-options-in-nextjs
const oneOf = config.module.rules.find(rule => typeof rule.oneOf === 'object')
if (oneOf) {
const moduleSassRule = oneOf.oneOf.find(rule => regexEqual(rule.test, /\.module\.(scss|sass)$/))
if (moduleSassRule) {
// Get the config object for css-loader plugin
const cssLoader = moduleSassRule.use.find(({ loader }) => loader.includes('css-loader'))
if (cssLoader) {
cssLoader.options = {
...cssLoader.options,
modules: {
...cssLoader.options.modules,
mode: 'local',
},
}
}
}
}

return config
},
}

/**
* Stolen from https://stackoverflow.com/questions/10776600/testing-for-equality-of-regular-expressions
*/
function regexEqual(x, y) {
return (
x instanceof RegExp &&
y instanceof RegExp &&
x.source === y.source &&
x.global === y.global &&
x.ignoreCase === y.ignoreCase &&
x.multiline === y.multiline
)
}

export default config
Loading

0 comments on commit 8602d31

Please sign in to comment.