Docs Site Revamp: Tutorials (#370)

* Add discord, twitter, and github icons.

* Update docusaurus.

* Move security page to sidebar.

* Remove copyright from site footers.

* Add caret icons for dropdown css override.

* Build and style custom docs navbar.

* Resolve Icon merge conflict.

* Change Developers dropdown to Builders.

* lint: Remove unused variable

* Add tutorials; initial commit

* Add and display new frontmatter

* Convert tutorials to single page pt. 1

* Update tutorial data; fix paths

* Ecopage - rubyscore + lore logos (#373)

* Update ecosystem.json (#374)

* Fix incorrectly rendering open graph metadata (#369)

* feat(web): Serve dynamic og:metadata server-side

* feat(docs): Serve dynamic og:metadata server-side

* fix(web): Resolve linting errors

* fix(web): Linting

* fix(web): Additional linting corrections

* fix(web): Resolve Typescript-related syntax error

* refactor(web): Add ogData to data structure

* fix(ecosystem): Typo in partner image name (#375)

* feat(bridge): Add planned paused note to top of page (#376)

* Update hyperframes to use state (#377)

* Update hyperframes to use state

* Respond to feedback

* fix(bridge): Add default open graph metadata (#378)

* Added Moralis to data indexers (#371)

* Added Moralis to data indexers

* typos

* Update copy

* Remove superlatives

---------

Co-authored-by: taycaldwell <taylor.lee.caldwell@gmail.com>

* docs(bridge): Update bridge pause to new date (#381)

* mention setting `OP_NODE_L1_BEACON` (#380)

* feat(docs): Add Uniswap V3 Base Sepolia contracts (#382)

* Improve loading experience on jobs page (#389)

* Docs Site Revamp: Navbar, Sidebar, and Doc Page (#379)

* Add discord, twitter, and github icons.

* Update docusaurus.

* Move security page to sidebar.

* Remove copyright from site footers.

* Add caret icons for dropdown css override.

* Build and style custom docs navbar.

* Resolve Icon merge conflict.

* Change Developers dropdown to Builders.

* lint: Remove unused variable

* Re-add node polyfills required for cookie manager to work.

* Disable DocFeedback component.

* Disable paginator and table of contents.

* Add collapse icons for css override.

* Fix Modal overlay styles.

* Adjust DocChat floating button position.

* Reorganize and restyle sidebar for new design.

* Update gray0 and modal overlay styles.

* Add stylesheet for new doc page styles.

* Remove TODO. Add sidebar link hover styles.

* Move responsive styles to bottom.

* Disable breadcrumb component. Update layout spacing.

---------

Co-authored-by: taycaldwell <taylor.lee.caldwell@gmail.com>

* refactor(bridge): Drop bridge maintenance notice (#390)

* Add tutorials; initial commit

* Add and display new frontmatter

* Update tutorial data

* Fix frontmatter

* Update TOC

* Update tutorials page

* Update toc margin

* fix nested categories in sidebar

* Add all tutorials back link

---------

Co-authored-by: Jacob Moore <jacob.moore@coinbase.com>
Co-authored-by: Kathryn <kathryn.snow@coinbase.com>
Co-authored-by: wbnns <hello@wbnns.com>
Co-authored-by: Brian Doyle <brian.doyle@coinbase.com>
Co-authored-by: Filip Martinsson <martinsson.filip@gmail.com>
Co-authored-by: abhi <abhijeet.bhagat@gmx.com>
Co-authored-by: Matthew Bunday <matthew.bunday@coinbase.com>
This commit is contained in:
taycaldwell
2024-03-28 11:33:18 -07:00
committed by GitHub
parent 17244ae6bf
commit 47ca5b7b77
92 changed files with 2472 additions and 1441 deletions

View File

@@ -0,0 +1,93 @@
const yaml = require('js-yaml');
const fs = require('fs');
const { readFile } = require('fs/promises');
const path = require('path');
const tutorialsDir = path.join(__dirname, '..', 'tutorials', 'docs');
async function getDuration(filePath) {
try {
let content = await readFile(filePath, 'utf8');
const words = content.trim().split(/\s+/).length;
const averageReadingSpeed = 225; // Average between 200 and 250 wpm
const readingTimeMinutes = (words / averageReadingSpeed) * 2; // Double estimated time
const hours = Math.floor(readingTimeMinutes / 60);
const minutes = Math.round(readingTimeMinutes % 60);
let timeString = '';
if (hours > 0) {
timeString += `${hours} hrs `;
}
timeString += `${minutes} mins`;
return `${timeString}`;
} catch (error) {
console.error('Error reading file:', error);
return null;
}
}
async function getLastUpdated(filePath) {
try {
const stats = await fs.promises.stat(filePath);
const lastModified = stats.mtime;
const months = [
'Jan',
'Feb',
'Mar',
'Apr',
'May',
'Jun',
'Jul',
'Aug',
'Sep',
'Oct',
'Nov',
'Dec',
];
const month = months[lastModified.getMonth()];
const day = lastModified.getDate();
return `${month} ${day}`;
} catch (error) {
console.error('Error getting file stats:', error);
return null;
}
}
(async () => {
const tutorials = {};
try {
const files = await fs.promises.readdir(tutorialsDir);
for (const file of files) {
const tutorialsPath = path.join(tutorialsDir, file);
const tutorialsStat = await fs.promises.stat(tutorialsPath);
if (tutorialsStat.isDirectory()) {
// const files = await fs.promises.readdir(tutorialsPath);
// for (const file of files) {
// const tutorialPath = path.join(tutorialsPath, file);
// const tutorialStat = await fs.promises.stat(tutorialPath);
// if (tutorialStat.isFile()) {
// let content = await readFile(tutorialPath, 'utf8');
// content = content.split('---\n')[1];
// const frontMatter = yaml.load(content);
// tutorials[frontMatter.slug.substring(1)] = frontMatter;
// }
// }
} else if (tutorialsStat.isFile()) {
let content = await readFile(tutorialsPath, 'utf8');
content = content.split('---\n')[1];
const frontMatter = yaml.load(content);
tutorials[frontMatter.slug.substring(1)] = frontMatter;
tutorials[frontMatter.slug.substring(1)].last_updated = await getLastUpdated(tutorialsPath);
tutorials[frontMatter.slug.substring(1)].duration = await getDuration(tutorialsPath);
}
}
} catch (e) {
console.error('Error updating tutorial data.', e);
}
const outputFilePath = path.join(__dirname, '..', 'tutorials', 'data.json');
fs.writeFileSync(outputFilePath, JSON.stringify(tutorials, null, 4));
})();