first commit
8
.dockerignore
Normal file
@ -0,0 +1,8 @@
|
||||
Dockerfile
|
||||
.dockerignore
|
||||
node_modules
|
||||
npm-debug.log
|
||||
README.md
|
||||
.next
|
||||
.git
|
||||
codegen.ts
|
6
.eslintrc.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": "next/core-web-vitals",
|
||||
"rules": {
|
||||
"@next/next/no-img-element": "off"
|
||||
}
|
||||
}
|
37
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
### Summary:
|
||||
[Provide a brief summary of the issue.]
|
||||
|
||||
### Environment:
|
||||
- Operating System:
|
||||
- Browser (If applicable):
|
||||
- Project Version:
|
||||
- Additional relevant information:
|
||||
|
||||
### Steps to Reproduce:
|
||||
1. [First step]
|
||||
2. [Second step]
|
||||
3. [And so on…]
|
||||
|
||||
### Expected Behavior:
|
||||
[Provide a detailed description of the expected behavior.]
|
||||
|
||||
### Actual Behavior:
|
||||
[Provide a detailed description of the actual behavior you are experiencing.]
|
||||
|
||||
### Screenshots (if applicable):
|
||||
[Attach screenshots to help illustrate the issue.]
|
||||
|
||||
### Additional Information:
|
||||
[Any additional information, configuration, or data that might be necessary to reproduce the issue.]
|
||||
|
||||
### Potential Solutions (if applicable):
|
||||
[Optional: Provide any thoughts or ideas you might have on potential solutions to the issue.]
|
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
### Feature Request:
|
||||
[Quick summary of the feature you would like to be added.]
|
||||
|
||||
### Why is this feature important?
|
||||
[Explain why you think this feature would be beneficial.]
|
||||
|
||||
### How should it work?
|
||||
[Briefly describe how you envision this feature working, or how you would like it to be implemented.]
|
24
.github/pull_request_template.md
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
### Description:
|
||||
[Provide a brief description of the changes in the pull request.]
|
||||
|
||||
### Related Issue(s):
|
||||
[Link to the related Issue(s), if any.]
|
||||
|
||||
### Changes Included:
|
||||
- [ ] Bugfix (a change that fixes an issue)
|
||||
- [ ] New feature (a change that adds new functionality)
|
||||
- [ ] Refactoring (a change that improves code quality and/or architecture)
|
||||
- [ ] Other (explain below)
|
||||
|
||||
### Implementation Details:
|
||||
[Explain any new decisions made during the implementation of the changes.]
|
||||
|
||||
### Testing:
|
||||
[Describe how the changes have been tested.]
|
||||
|
||||
### Checklist:
|
||||
- [ ] My code follows the style guidelines of this project
|
||||
- [ ] I have performed a self-review of my own code
|
||||
- [ ] I have commented my code, particularly in hard-to-understand areas
|
||||
- [ ] My changes generate no new warnings
|
||||
- [ ] Any dependent changes have been merged and published in downstream modules
|
40
.gitignore
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
# 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
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# local env files
|
||||
.env*.local
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
|
||||
.idea
|
||||
|
||||
public/rss.xml
|
||||
public/atom*.xml
|
4
.husky/pre-commit
Executable file
@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
npx lint-staged
|
7
.prettierrc
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"tabWidth": 2,
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"plugins": ["prettier-plugin-organize-imports"]
|
||||
}
|
17
Dockerfile
Normal file
@ -0,0 +1,17 @@
|
||||
FROM node:18.13.0-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Listening port
|
||||
ARG PORT=3000
|
||||
EXPOSE ${PORT}
|
||||
|
||||
ENV NODE_ENV=production
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN yarn install --production
|
||||
RUN yarn build
|
||||
|
||||
CMD ["yarn", "start"]
|
126
Jenkinsfile
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
parameters {
|
||||
string(
|
||||
name: 'IMAGE_TAG',
|
||||
defaultValue: params.IMAGE_TAG ?: '',
|
||||
description: 'Optional Docker image tag to push.'
|
||||
)
|
||||
}
|
||||
|
||||
options {
|
||||
disableConcurrentBuilds()
|
||||
/* manage how many builds we keep */
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '20',
|
||||
daysToKeepStr: '30',
|
||||
))
|
||||
}
|
||||
|
||||
environment {
|
||||
IMAGE_NAME = 'statusteam/ift'
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Build') {
|
||||
steps {
|
||||
script {
|
||||
withCredentials([
|
||||
usernamePassword(
|
||||
credentialsId: 'ift-unbody-api-token',
|
||||
usernameVariable: 'UNBODY_PROJECT_ID',
|
||||
passwordVariable: 'UNBODY_API_KEY'
|
||||
),
|
||||
string(
|
||||
credentialsId: 'ift-simplecast-token',
|
||||
variable: 'SIMPLECAST_ACCESS_TOKEN'
|
||||
),
|
||||
string(
|
||||
credentialsId: 'ift-webhook-token',
|
||||
variable: 'REVALIDATE_WEBHOOK_TOKEN'
|
||||
),
|
||||
]) {
|
||||
image = docker.build(
|
||||
"${IMAGE_NAME}:${GIT_COMMIT.take(8)}",
|
||||
["--build-arg='UNBODY_PROJECT_ID=${env.UNBODY_PROJECT_ID}'",
|
||||
"--build-arg='UNBODY_API_KEY=${env.UNBODY_API_KEY}'",
|
||||
"--build-arg='SIMPLECAST_ACCESS_TOKEN=${SIMPLECAST_ACCESS_TOKEN}'",
|
||||
"--build-arg='REVALIDATE_WEBHOOK_TOKEN=${REVALIDATE_WEBHOOK_TOKEN}'",
|
||||
"."].join(' ')
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Push') {
|
||||
steps { script {
|
||||
withDockerRegistry([
|
||||
credentialsId: 'dockerhub-statusteam-auto', url: ''
|
||||
]) {
|
||||
image.push()
|
||||
}
|
||||
} }
|
||||
}
|
||||
|
||||
stage('Deploy') {
|
||||
when { expression { params.IMAGE_TAG != '' } }
|
||||
steps { script {
|
||||
withDockerRegistry([
|
||||
credentialsId: 'dockerhub-statusteam-auto', url: ''
|
||||
]) {
|
||||
image.push(params.IMAGE_TAG)
|
||||
}
|
||||
} }
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
cleanup { cleanWs() }
|
||||
always { script {
|
||||
def result = currentBuild.result.toLowerCase() ?: 'unknown'
|
||||
discordNotify(header: "Logos Press Engine Docker image build ${result}!")
|
||||
} }
|
||||
}
|
||||
}
|
||||
|
||||
def discordNotify(Map args=[:]) {
|
||||
def opts = [
|
||||
header: args.header ?: 'Deployment successful!',
|
||||
title: args.title ?: "${env.JOB_NAME}#${env.BUILD_NUMBER}",
|
||||
cred: args.cred ?: 'ift-discord-webhook-url',
|
||||
]
|
||||
def repo = [
|
||||
url: GIT_URL.minus('.git'),
|
||||
branch: GIT_BRANCH.minus('origin/'),
|
||||
commit: GIT_COMMIT.take(8),
|
||||
prev: (
|
||||
env.GIT_PREVIOUS_SUCCESSFUL_COMMIT ?: env.GIT_PREVIOUS_COMMIT ?: 'master'
|
||||
).take(8),
|
||||
]
|
||||
wrap([$class: 'BuildUser']) {
|
||||
BUILD_USER_ID = env.BUILD_USER_ID
|
||||
}
|
||||
withCredentials([
|
||||
string(
|
||||
credentialsId: opts.cred,
|
||||
variable: 'DISCORD_WEBHOOK',
|
||||
),
|
||||
]) {
|
||||
discordSend(
|
||||
link: env.BUILD_URL,
|
||||
result: currentBuild.currentResult,
|
||||
webhookURL: env.DISCORD_WEBHOOK,
|
||||
title: opts.title,
|
||||
description: """
|
||||
${opts.header}
|
||||
Image: [`${env.IMAGE_NAME}:${params.IMAGE_TAG}`](https://hub.docker.com/r/${params.DOCKER_NAME}/tags?name=${params.IMAGE_TAG})
|
||||
Branch: [`${repo.branch}`](${repo.url}/commits/${repo.branch})
|
||||
Commit: [`${repo.commit}`](${repo.url}/commit/${repo.commit})
|
||||
Diff: [`${repo.prev}...${repo.commit}`](${repo.url}/compare/${repo.prev}...${repo.commit})
|
||||
By: [`${BUILD_USER_ID}`](${repo.url}/commits?author=${BUILD_USER_ID})
|
||||
""",
|
||||
)
|
||||
}
|
||||
}
|
61
README.md
Normal file
@ -0,0 +1,61 @@
|
||||
# IFT
|
||||
|
||||
## Test pages
|
||||
- `next-mdx-remote` test page: '/'
|
||||
- `@next/mdx` test page: '/test'
|
||||
|
||||
|
||||
## How to Run Locally
|
||||
|
||||
1. Clone this repository
|
||||
```bash
|
||||
$ git clone https://github.com/acid-info/ift.git
|
||||
```
|
||||
|
||||
2. Install the dependencies:
|
||||
```bash
|
||||
$ yarn install
|
||||
```
|
||||
|
||||
3. Start the development server:
|
||||
```bash
|
||||
$ yarn dev
|
||||
```
|
||||
|
||||
4. Visit `http://localhost:3000` in your browser
|
||||
|
||||
|
||||
## How to Run a Static Build (Production Build)
|
||||
|
||||
1. Generate static files for production:
|
||||
|
||||
```bash
|
||||
$ yarn build
|
||||
```
|
||||
|
||||
The static files will be created in the `build` directory.
|
||||
|
||||
2. Serve the static build:
|
||||
|
||||
```bash
|
||||
$ yarn start
|
||||
```
|
||||
|
||||
4. Visit `http://localhost:3000` in your browser
|
||||
|
||||
|
||||
## CI/CD
|
||||
|
||||
- The `master` branch is automatically deployed to the production server (e.g., logos.co) through [CI](https://ci.infra.status.im)
|
||||
- The `develop` branch is automatically deployed to the staging server (e.g., dev.logos.co) through [CI](https://ci.infra.status.im)
|
||||
|
||||
|
||||
## Change Process
|
||||
|
||||
1. Create a new working branch from `develop`: `git checkout develop; git checkout -b my-changes`.
|
||||
|
||||
2. Make your changes, push them to the `origin`, and open a Pull Request against the `develop` branch.
|
||||
|
||||
3. After approval, merge the pull request, and verify the changes on the staging server (https://dev-press.logos.co/).
|
||||
|
||||
4. When ready to promote changes to the live website, create a pull request against the "master" branch, based on the "develop" branch.
|
BIN
assets/Inter-Regular.ttf
Normal file
BIN
assets/Lora-Regular.ttf
Normal file
7
mdx-components.tsx
Normal file
@ -0,0 +1,7 @@
|
||||
import type { MDXComponents } from 'mdx/types'
|
||||
|
||||
export function useMDXComponents(components: MDXComponents): MDXComponents {
|
||||
return {
|
||||
...components,
|
||||
}
|
||||
}
|
10
next.config.js
Normal file
@ -0,0 +1,10 @@
|
||||
const withMDX = require('@next/mdx')()
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
reactStrictMode: true,
|
||||
pageExtensions: ['js', 'jsx', 'mdx', 'ts', 'tsx'],
|
||||
// Optionally, add any other Next.js config below
|
||||
}
|
||||
|
||||
module.exports = withMDX(nextConfig)
|
52
package.json
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"name": "ift",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint",
|
||||
"prepare": "husky install"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{ts,tsx}": [
|
||||
"prettier --write",
|
||||
"eslint --fix"
|
||||
]
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@mdx-js/loader": "^2.3.0",
|
||||
"@mdx-js/react": "^2.3.0",
|
||||
"@next/mdx": "^13.5.5",
|
||||
"@types/mdx": "^2.0.8",
|
||||
"@vercel/og": "^0.5.4",
|
||||
"axios": "^1.4.0",
|
||||
"next": "13.5.5",
|
||||
"next-mdx-remote": "^4.4.1",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^18",
|
||||
"@types/react-dom": "^18",
|
||||
"clsx": "^1.2.1",
|
||||
"dotenv": "^16.3.1",
|
||||
"dotenv-cli": "^7.2.1",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "13.5.5",
|
||||
"husky": "^8.0.3",
|
||||
"lint-staged": "^13.2.1",
|
||||
"prettier": "^2.8.7",
|
||||
"prettier-plugin-organize-imports": "^3.2.3",
|
||||
"typescript": "^5"
|
||||
}
|
||||
}
|
BIN
public/favicon.ico
Normal file
After Width: | Height: | Size: 31 KiB |
11
public/hashing-it-out-logo.svg
Normal file
@ -0,0 +1,11 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="24" height="24" rx="12" fill="#FFE922"/>
|
||||
<g clip-path="url(#clip0_33_583)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.6278 8.33879H8.28654V15.6801H15.6278V8.33879ZM7.06299 7.11523V16.9036H16.8514V7.11523H7.06299ZM9.51009 14.4567L9.51009 9.56248H10.7336L10.7336 14.4567H9.51009ZM14.4043 14.4567H13.1808L13.1808 9.56248H14.4043L14.4043 14.4567ZM11.9572 12.6214V11.3978L13.1808 11.3978L13.1808 12.6214H11.9572Z" fill="black"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_33_583">
|
||||
<rect width="9.81" height="9.81" fill="white" transform="translate(7 7)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 687 B |
BIN
public/logo.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
6
public/logos-state-logo.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="24" height="24" rx="12" fill="black"/>
|
||||
<path d="M16.0485 16.3056H8.11108V11.4797H16.041L16.0485 16.3056ZM12.071 11.8668C11.3935 11.8675 10.7267 12.0331 10.1297 12.3488C9.53276 12.6646 9.0241 13.1208 8.64891 13.6768C8.59928 13.7333 8.57195 13.8055 8.57195 13.8803C8.57195 13.955 8.59928 14.0272 8.64891 14.0837C9.02651 14.6372 9.53614 15.091 10.1331 15.4051C10.73 15.7192 11.396 15.8841 12.0727 15.8853C12.7494 15.8865 13.416 15.724 14.0141 15.412C14.6122 15.1001 15.1235 14.6482 15.5031 14.096C15.5573 14.0364 15.5872 13.9591 15.5872 13.879C15.5872 13.799 15.5573 13.7217 15.5031 13.662C15.1245 13.1082 14.6133 12.6549 14.0147 12.3422C13.4161 12.0295 12.7485 11.8671 12.071 11.8693V11.8668Z" fill="white"/>
|
||||
<path d="M12.0935 11.0284C11.4204 11.027 10.7576 10.8648 10.162 10.5556C9.56644 10.2463 9.05582 9.79933 8.67394 9.25287C8.61027 9.1861 8.57482 9.09791 8.57482 9.00627C8.57482 8.91464 8.61027 8.82645 8.67394 8.75968C9.05561 8.2142 9.56657 7.76881 10.1625 7.46216C10.7584 7.15551 11.4212 6.99689 12.0934 7.00005C12.7656 7.00321 13.4268 7.16806 14.0197 7.48029C14.6126 7.79252 15.1193 8.24269 15.4956 8.79173C15.5496 8.85101 15.5795 8.92785 15.5795 9.0075C15.5795 9.08715 15.5496 9.164 15.4956 9.22327C15.1197 9.77371 14.6136 10.2257 14.0208 10.5402C13.4281 10.8547 12.7666 11.0222 12.0935 11.0284ZM13.5745 9.03093C13.5814 8.73692 13.4993 8.44754 13.3387 8.19972C13.1781 7.95191 12.9462 7.75691 12.6726 7.63961C12.399 7.52231 12.0962 7.48804 11.8028 7.54117C11.5094 7.5943 11.2387 7.73243 11.0252 7.93791C10.8118 8.14339 10.6653 8.40691 10.6045 8.69482C10.5437 8.98274 10.5713 9.28198 10.6838 9.55435C10.7963 9.82673 10.9886 10.0599 11.2361 10.224C11.4837 10.3882 11.7752 10.4759 12.0735 10.476C12.4656 10.4761 12.8422 10.325 13.1227 10.0549C13.4031 9.78485 13.5653 9.41732 13.5745 9.03093Z" fill="white"/>
|
||||
<path d="M12.0785 15.3364C11.7876 15.3315 11.5046 15.242 11.2652 15.0791C11.0257 14.9162 10.8405 14.6872 10.7326 14.4208C10.6248 14.1544 10.5993 13.8626 10.6592 13.5819C10.7192 13.3013 10.8619 13.0443 11.0696 12.8434C11.2772 12.6425 11.5404 12.5066 11.8262 12.4527C12.1119 12.3988 12.4075 12.4293 12.6757 12.5405C12.9438 12.6517 13.1727 12.8386 13.3335 13.0776C13.4943 13.3166 13.5798 13.5971 13.5794 13.8839C13.5788 14.0768 13.5393 14.2676 13.4633 14.4453C13.3873 14.623 13.2763 14.7841 13.1367 14.9192C12.9971 15.0543 12.8316 15.1607 12.65 15.2323C12.4683 15.304 12.2741 15.3393 12.0785 15.3364Z" fill="white"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
16
public/manifest.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"short_name": "Network State Press",
|
||||
"name": "Network State Press",
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff",
|
||||
"icons": [
|
||||
{
|
||||
"src": "./favicon.ico",
|
||||
"sizes": "64x64",
|
||||
"type": "image/icon",
|
||||
"purpose": "any maskable"
|
||||
}
|
||||
]
|
||||
}
|
1
public/next.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
After Width: | Height: | Size: 1.3 KiB |
BIN
public/og.png
Normal file
After Width: | Height: | Size: 11 KiB |
1
public/vercel.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 283 64"><path fill="black" d="M141 16c-11 0-19 7-19 18s9 18 20 18c7 0 13-3 16-7l-7-5c-2 3-6 4-9 4-5 0-9-3-10-7h28v-3c0-11-8-18-19-18zm-9 15c1-4 4-7 9-7s8 3 9 7h-18zm117-15c-11 0-19 7-19 18s9 18 20 18c6 0 12-3 16-7l-8-5c-2 3-5 4-8 4-5 0-9-3-11-7h28l1-3c0-11-8-18-19-18zm-10 15c2-4 5-7 10-7s8 3 9 7h-19zm-39 3c0 6 4 10 10 10 4 0 7-2 9-5l8 5c-3 5-9 8-17 8-11 0-19-7-19-18s8-18 19-18c8 0 14 3 17 8l-8 5c-2-3-5-5-9-5-6 0-10 4-10 10zm83-29v46h-9V5h9zM37 0l37 64H0L37 0zm92 5-27 48L74 5h10l18 30 17-30h10zm59 12v10l-3-1c-6 0-10 4-10 10v15h-9V17h9v9c0-5 6-9 13-9z"/></svg>
|
After Width: | Height: | Size: 629 B |
11
src/components/Main/Main.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
import styled from '@emotion/styled'
|
||||
|
||||
export type MainProps = Partial<React.ComponentProps<typeof Container>> & {}
|
||||
|
||||
export const Main = ({ children, ...props }: MainProps) => {
|
||||
return <Container {...props}>{children}</Container>
|
||||
}
|
||||
|
||||
const Container = styled.main``
|
||||
|
||||
export default Main
|
1
src/components/Main/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default as Main } from './Main'
|
72
src/components/SEO/SEO.tsx
Normal file
@ -0,0 +1,72 @@
|
||||
import { getWebsiteUrl } from '@/utils/route.utils'
|
||||
import Head from 'next/head'
|
||||
|
||||
type Metadata = {
|
||||
title?: string
|
||||
description?: string
|
||||
type?: string
|
||||
locale?: string
|
||||
site_name?: string
|
||||
pageURL?: string
|
||||
imageUrl?: string
|
||||
image?: string | null
|
||||
tags?: string[]
|
||||
pagePath?: string
|
||||
date?: string | null
|
||||
contentType?: string
|
||||
noIndex?: boolean
|
||||
}
|
||||
|
||||
const SITE_URL = getWebsiteUrl()
|
||||
|
||||
export default function SEO({
|
||||
title,
|
||||
description,
|
||||
type,
|
||||
locale,
|
||||
site_name,
|
||||
pageURL,
|
||||
imageUrl,
|
||||
tags = [],
|
||||
pagePath = '',
|
||||
noIndex = false,
|
||||
}: Metadata) {
|
||||
const ogImageUrl = imageUrl
|
||||
|
||||
return (
|
||||
<Head>
|
||||
<title>{title}</title>
|
||||
<meta name="description" content={description} />
|
||||
<meta property="og:title" content={title} />
|
||||
<meta property="og:locale" content={locale ?? 'en-US'} />
|
||||
<meta property="og:description" content={description} />
|
||||
<meta property="og:type" content={type ?? 'website'} />
|
||||
<meta property="og:url" content={pageURL ?? `${SITE_URL}${pagePath}`} />
|
||||
<meta property="keywords" content={tags.join(', ')} />
|
||||
<meta property="og:site_name" content={site_name} />
|
||||
<meta name="twitter:title" content={title} />
|
||||
<meta name="twitter:description" content={description} />
|
||||
<meta property="og:image" content={ogImageUrl} />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:url" content={pageURL ?? `${SITE_URL}${pagePath}`} />
|
||||
<meta name="twitter:site" content={`@${site_name}`} />
|
||||
<meta property="twitter:image" content={ogImageUrl} />
|
||||
<link rel="canonical" href={`${SITE_URL}${pagePath}`} />
|
||||
<link
|
||||
rel="alternate"
|
||||
type="application/rss+xml"
|
||||
href={`${getWebsiteUrl()}/rss.xml`}
|
||||
/>
|
||||
<link
|
||||
rel="alternate"
|
||||
type="application/atom+xml"
|
||||
href={`${getWebsiteUrl()}/atom.xml`}
|
||||
/>
|
||||
{noIndex && (
|
||||
<>
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
</>
|
||||
)}
|
||||
</Head>
|
||||
)
|
||||
}
|
1
src/components/SEO/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default as SEO } from './SEO'
|
0
src/configs/.placeholder
Normal file
15
src/containers/HomePage/HomePage.tsx
Normal file
@ -0,0 +1,15 @@
|
||||
import styled from '@emotion/styled'
|
||||
import React from 'react'
|
||||
|
||||
export type HomePageProps = React.DetailedHTMLProps<
|
||||
React.HTMLAttributes<HTMLDivElement>,
|
||||
HTMLDivElement
|
||||
>
|
||||
|
||||
export const HomePage: React.FC<HomePageProps> = ({ ...props }) => {
|
||||
return <Root {...props}>IFT</Root>
|
||||
}
|
||||
|
||||
const Root = styled.div`
|
||||
width: 100%;
|
||||
`
|
1
src/containers/HomePage/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './HomePage'
|
17
src/layouts/DefaultLayout/Default.layout.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
import { Main } from '@/components/Main'
|
||||
import { PropsWithChildren } from 'react'
|
||||
import { MainProps } from '../../components/Main/Main'
|
||||
|
||||
interface Props {
|
||||
mainProps?: Partial<MainProps>
|
||||
}
|
||||
|
||||
export default function DefaultLayout(props: PropsWithChildren<Props>) {
|
||||
const { mainProps = {} } = props
|
||||
|
||||
return (
|
||||
<>
|
||||
<Main {...mainProps}>{props.children}</Main>
|
||||
</>
|
||||
)
|
||||
}
|
1
src/layouts/DefaultLayout/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default as DefaultLayout } from './Default.layout'
|
0
src/lib/.placeholder
Normal file
29
src/pages/index.tsx
Normal file
@ -0,0 +1,29 @@
|
||||
import { MDXRemote, MDXRemoteSerializeResult } from 'next-mdx-remote'
|
||||
import { serialize } from 'next-mdx-remote/serialize'
|
||||
import SEO from '../components/SEO/SEO'
|
||||
import { DefaultLayout } from '../layouts/DefaultLayout'
|
||||
|
||||
interface Props {
|
||||
mdxSource: MDXRemoteSerializeResult
|
||||
}
|
||||
|
||||
const Page = ({ mdxSource }: Props) => {
|
||||
return (
|
||||
<>
|
||||
<SEO />
|
||||
<MDXRemote {...mdxSource} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Page.getLayout = function getLayout(page: React.ReactNode) {
|
||||
return <DefaultLayout>{page}</DefaultLayout>
|
||||
}
|
||||
|
||||
export async function getStaticProps() {
|
||||
const source = '**mdx** example'
|
||||
const mdxSource = await serialize(source)
|
||||
return { props: { mdxSource } }
|
||||
}
|
||||
|
||||
export default Page
|
11
src/pages/test.mdx
Normal file
@ -0,0 +1,11 @@
|
||||
# Welcome to my MDX page!
|
||||
|
||||
This is some **bold** and _italics_ text.
|
||||
|
||||
This is a list in markdown:
|
||||
|
||||
- One
|
||||
- Two
|
||||
- Three
|
||||
|
||||
Checkout my React component:
|
0
src/styles/globals.css
Normal file
0
src/types/.placeholder
Normal file
7
src/utils/route.utils.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export const getWebsiteUrl = () => {
|
||||
if (typeof window === 'undefined')
|
||||
return process.env.NEXT_PUBLIC_SITE_URL || 'https://dev-press.logos.co'
|
||||
|
||||
const url = new URL(window.location.href)
|
||||
return url.origin
|
||||
}
|
24
tsconfig.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"types": ["@emotion/react/types/css-prop"],
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|