mirror of
https://github.com/BradNut/awesome-uses
synced 2025-09-08 17:40:31 +00:00
Merge branch 'master' into pr/1525
This commit is contained in:
commit
237225749e
40 changed files with 14736 additions and 35726 deletions
13
.arc
13
.arc
|
|
@ -1,13 +0,0 @@
|
|||
@app
|
||||
start-u1s
|
||||
|
||||
@static
|
||||
|
||||
@http
|
||||
get /
|
||||
|
||||
@tables
|
||||
data
|
||||
scopeID *String
|
||||
dataID **String
|
||||
ttl TTL
|
||||
2
.github/workflows/data-validate.yml
vendored
2
.github/workflows/data-validate.yml
vendored
|
|
@ -14,7 +14,7 @@ jobs:
|
|||
- uses: actions/checkout@v1
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 13.x
|
||||
node-version: 16.x
|
||||
|
||||
- name: Cache/Restore node modules
|
||||
uses: actions/cache@v1
|
||||
|
|
|
|||
2
.github/workflows/populate-readme.yml
vendored
2
.github/workflows/populate-readme.yml
vendored
|
|
@ -17,7 +17,7 @@ jobs:
|
|||
- uses: actions/checkout@v1
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 13.x
|
||||
node-version: 16.x
|
||||
|
||||
- name: Cache/Restore node modules
|
||||
uses: actions/cache@v1
|
||||
|
|
|
|||
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -1,3 +1,4 @@
|
|||
build/
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
|
@ -54,9 +55,7 @@ typings/
|
|||
# dotenv environment variable files
|
||||
.env*
|
||||
|
||||
# gatsby files
|
||||
.cache/
|
||||
public
|
||||
|
||||
# Mac files
|
||||
.DS_Store
|
||||
|
|
@ -78,3 +77,6 @@ haters/
|
|||
|
||||
.idea/
|
||||
.history/
|
||||
|
||||
# Local Netlify folder
|
||||
.netlify
|
||||
|
|
|
|||
1
.npmrc
1
.npmrc
|
|
@ -1,3 +1,4 @@
|
|||
fund=false
|
||||
audit=false
|
||||
legacy-peer-deps=true
|
||||
shamefully-hoist=true
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
A /uses page lists a developer's setup, gear, software, and configs (what they *use*). It's a great reference for those looking to add to their library of tools or reconfigure ones they already use.
|
||||
|
||||
**The URL MUST to follow the format of use|uses|using|setup|environment at the end.**
|
||||
**The URL MUST follow the format of use|uses|using|setup|environment at the end.**
|
||||
|
||||
### What Should I Include?
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
import React from 'react';
|
||||
import { FilterProvider } from './src/context/FilterContext';
|
||||
import './static/fonts.css';
|
||||
|
||||
export const wrapRootElement = ({ element }) => (
|
||||
<FilterProvider>{element}</FilterProvider>
|
||||
);
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
module.exports = {
|
||||
siteMetadata: {
|
||||
title: `/uses`,
|
||||
description: `A list of /uses pages detailing developer setups.`,
|
||||
author: `@wesbos`,
|
||||
siteUrl: 'https://uses.tech',
|
||||
},
|
||||
plugins: [
|
||||
{
|
||||
resolve: `gatsby-source-filesystem`,
|
||||
options: {
|
||||
name: `images`,
|
||||
path: `${__dirname}/src/images`,
|
||||
},
|
||||
},
|
||||
`gatsby-transformer-sharp`,
|
||||
`gatsby-plugin-sharp`,
|
||||
{
|
||||
resolve: `gatsby-plugin-manifest`,
|
||||
options: {
|
||||
name: `gatsby-starter-default`,
|
||||
short_name: `starter`,
|
||||
start_url: `/`,
|
||||
background_color: `#663399`,
|
||||
theme_color: `#663399`,
|
||||
display: `minimal-ui`,
|
||||
icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site.
|
||||
},
|
||||
},
|
||||
`gatsby-plugin-react-helmet`,
|
||||
`gatsby-plugin-styled-components`,
|
||||
],
|
||||
};
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
const { tags, countries, devices, normalizeTag } = require('./src/util/stats');
|
||||
const people = require('./src/data.js');
|
||||
|
||||
function unique(arr) {
|
||||
return Array.from(new Set(arr));
|
||||
}
|
||||
|
||||
function sourceNodes({ actions, createNodeId, createContentDigest }) {
|
||||
const normalizedTagMap = tags().reduce((acc, tag) => {
|
||||
const normalizedTag = normalizeTag(tag.name);
|
||||
acc[normalizedTag] = tag.name;
|
||||
return acc;
|
||||
}, {});
|
||||
// Add People to the GraphQL API, we randomize the data on each build so no one gets their feelings hurt
|
||||
people
|
||||
.sort(() => Math.random() - 0.5)
|
||||
.forEach((person) => {
|
||||
const normalizedPerson = {
|
||||
...person,
|
||||
// Clean out people that added basically the same tags twice
|
||||
tags: unique(
|
||||
person.tags.map((tag) => normalizedTagMap[normalizeTag(tag)] || tag)
|
||||
),
|
||||
};
|
||||
const nodeMeta = {
|
||||
id: createNodeId(`person-${normalizedPerson.name}`),
|
||||
parent: null,
|
||||
children: [],
|
||||
internal: {
|
||||
type: `Person`,
|
||||
mediaType: `text/html`,
|
||||
content: JSON.stringify(normalizedPerson),
|
||||
contentDigest: createContentDigest(normalizedPerson),
|
||||
},
|
||||
};
|
||||
|
||||
actions.createNode({ ...normalizedPerson, ...nodeMeta });
|
||||
});
|
||||
|
||||
// Add tags to GraphQL API
|
||||
tags().forEach((tag) => {
|
||||
const nodeMeta = {
|
||||
id: createNodeId(`tag-${tag.name}`),
|
||||
parent: null,
|
||||
children: [],
|
||||
internal: {
|
||||
type: `Tag`,
|
||||
mediaType: `text/html`,
|
||||
content: JSON.stringify(tag),
|
||||
contentDigest: createContentDigest(tag),
|
||||
},
|
||||
};
|
||||
|
||||
actions.createNode({ ...tag, ...nodeMeta });
|
||||
});
|
||||
|
||||
// Add Countries to GraphQL API
|
||||
countries().forEach((country) => {
|
||||
const nodeMeta = {
|
||||
id: createNodeId(`country-${country.name}`),
|
||||
parent: null,
|
||||
children: [],
|
||||
internal: {
|
||||
type: `Country`,
|
||||
mediaType: `text/html`,
|
||||
content: JSON.stringify(country),
|
||||
contentDigest: createContentDigest(country),
|
||||
},
|
||||
};
|
||||
|
||||
actions.createNode({ ...country, ...nodeMeta });
|
||||
});
|
||||
|
||||
// Add Devices to GraphQL API
|
||||
devices().forEach((device) => {
|
||||
const nodeMeta = {
|
||||
id: createNodeId(`device-${device.name}`),
|
||||
parent: null,
|
||||
children: [],
|
||||
internal: {
|
||||
type: `device`,
|
||||
mediaType: `text/html`,
|
||||
content: JSON.stringify(device),
|
||||
contentDigest: createContentDigest(device),
|
||||
},
|
||||
};
|
||||
actions.createNode({ ...device, ...nodeMeta });
|
||||
});
|
||||
}
|
||||
|
||||
exports.sourceNodes = sourceNodes;
|
||||
|
|
@ -1 +0,0 @@
|
|||
export { wrapRootElement } from './gatsby-browser';
|
||||
103
migration.md
103
migration.md
|
|
@ -1,103 +0,0 @@
|
|||
We need to move these people over to the data.js file:
|
||||
|
||||
https://github.com/wesbos/awesome-uses/blob/master/src/data.js
|
||||
|
||||
Grab a random person, and fill out the info as best as possible.
|
||||
|
||||
If possible maybe ask the user on twitter to update or review theirs.
|
||||
|
||||
When done, check that person off.
|
||||
|
||||
|
||||
* [x] [Wes Bos](https://wesbos.com/uses) — Web Developer, Tutorial Maker, Podcaster.
|
||||
* [x] [Glenn Reyes](https://glennreyes.com/uses) - Independent Software Engineer, Trainer & Speaker.
|
||||
* [x] [Smakosh](https://smakosh.com/the-tech-tools-I-use) - JavaScript Developer, indie maker.
|
||||
* [ ] [Eric L. Barnes](https://ericlbarnes.com/uses/) - Laravel Developer, Maker, Writer
|
||||
* [x] [Benjamin Lannon](https://lannonbr.com/uses/) - Web Developer, Open Source Contributor.
|
||||
* [ ] [Thibault Maekelbergh](https://thibmaek.com/uses) - All-round developer, DIY enthousiast, record collector.
|
||||
* [x] [Kent C. Dodds](https://kentcdodds.com/uses) - Web Developer, Educator, Live Streamer, Open Sourcerer.
|
||||
* [ ] [Randy Oest, aka amazingrando](https://randyoest.com/uses/) - Lead Design and Frontend Engineer, Four Kitchens
|
||||
* [ ] [Elijah Manor](https://elijahmanor.com/uses) - Front-End Developer and Educator
|
||||
* [ ] [Dave Kiss](https://davekiss.com/uses) - Web Developer, Solopreneur, Adventurer
|
||||
* [x] [Jonathan Suh](https://jonsuh.com/uses) - Designer, Developer
|
||||
* [ ] [Manuel Wildauer](https://wildauer.io/uses) - Developer
|
||||
* [ ] [Elliot Forbes](https://tutorialedge.net/uses/) - All-round Developer
|
||||
* [ ] [Dr. Abstract](https://zimjs.com/uses/) - Founder of ZIM JavaScript Canvas Framework
|
||||
* [ ] [Jay Collett](https://www.jaycollett.co/uses/) - Freelance web designer and front end developer with CraftCMS
|
||||
* [ ] [Amit Merchant](https://www.amitmerchant.com/uses/) - Fullstack web developer, blogger.
|
||||
* [ ] [Adam Greenough](https://adamgreenough.me/uses/) - Freelance Digital Designer & Web Developer
|
||||
* [x] [Georgi Yanev](https://gyanev.com/uses/) - Web Developer, FPV drone pilot
|
||||
* [ ] [Kumar Abhirup](https://kumar.now.sh/uses) - A 15yo Jnr. developer with a passion for learning 👋🏻
|
||||
* [ ] [Chris Enns](https://chrisenns.com/uses/) - Podcast Editor & WordPress Wannabe
|
||||
* [ ] [David Llop](https://davidllop.com/uses/) - Laravel & ChatBots Developer
|
||||
* [ ] [Med Ben hartouz](https://benhartouz.com/uses/) - Fullstack Javascript Developer.
|
||||
* [ ] [Łukasz Ostrowski](https://ostrowski.ninja/uses/) - Frontend developer
|
||||
* [ ] [Tim Smith](https://www.iamtimsmith.com/uses) - Web developer, Blogger, and Freelancer
|
||||
* [ ] [Jon Quach](https://jonquach.com/uses/) - Design Engineer
|
||||
* [ ] [Tracy Osborn](https://limedaring.com/uses/) - Designer, Developer, Tech Author, Entreprenerd
|
||||
* [ ] [Daniel Van Cuylenburg](https://dvanc.co/uses/) - Web Designer, Front-end Developer, Guitarist.
|
||||
* [ ] [Aurel Tyson](https://aureltyson.info/uses) - iOS and backend developer
|
||||
* [ ] [Nick Janetakis](https://nickjanetakis.com/uses) - Web developer, Sysadmin, Teacher
|
||||
* [x] [Andrew Healey](https://healeycodes.com/uses/) - Fullstack Software Engineer, Blogger, Tutorial Creator.
|
||||
* [ ] [Alex Carpenter](https://alexcarpenter.me/uses/) - Front-end Web Developer and Screencaster.
|
||||
* [ ] [Wang Junxiao](http://www.feng0207.site/uses/) — Java Web Developer, Student.
|
||||
* [x] [Jeff Wen](https://sinchang.me/uses/) - Web Developer, Open Source Contributor
|
||||
* [ ] [Tracy Osborn](https://limedaring.com/uses/) - Designer, Developer, Tech Author, Entreprenerd
|
||||
* [ ] [Bruno Brito](https://brunobrito.pt/uses/) - Web Developer, Content Creator, Digital Marketing 🇵🇹
|
||||
* [ ] [Lemon 🍋](https://ahoylemon.xyz/uses/) - Web Developer, Podcaster, Human Who Makes Dumb Shit
|
||||
* [ ] [Kevin Jalbert](https://kevinjalbert.com/uses/) - Developer Lead (React/Rails), Blogger.
|
||||
* [x] [Swapnil Agarwal](https://swapnil.net/uses/) - Backend Developer, Aspiring Writer, Budding Designer
|
||||
* [x] [Hugo Di Francesco](https://codewithhugo.com/uses/) - JavaScript Developer, Blogger
|
||||
* [x] [Josiah Wiebe](https://jwie.be/uses/) - Full Stack Developer & Designer
|
||||
* [ ] [Khalil Stemmler](https://khalilstemmler.com/uses/) - Fullstack Javascript Developer / Designer, Musician 🇨🇦
|
||||
* [ ] [Pierre-Antoine _Leny_ Delnatte](https://leny.me/uses/) - Fullstack Web Developer, Bootcamp coach 🇧🇪
|
||||
* [ ] [Harry Roberts](https://csswizardry.com/uses/) - Consultant Front-end Architect, designer, developer, writer and speaker.
|
||||
* [ ] [Matt D. Smith](http://mds.is/using-stuff/) - Owner and Design Director at Studio Mds.
|
||||
* [ ] [Ash Hitchcock](https://www.ashleyhitchcock.com/uses) - Front-end Developer 🇬🇧
|
||||
* [ ] [Oscar te Giffel](https://oscartegiffel.com/uses/) - Fullstack Software engineer
|
||||
* [ ] [John Michael Ferraris](https://jhnferraris.dev/uses/) - Fullstack Developer (that is still eager to learn), Runner
|
||||
* [ ] [François Rabanel aka Pesko](https://peskoo.github.io/lasalledutemps/articles/2019-04/uses) - Fullstack Software Engineer
|
||||
* [ ] [Jesse Burton](https://burtonmediainc.com/uses) - Web Developer, Freelancer, Blogger
|
||||
* [ ] [Philipp John](https://www.jplace.de/uses) - Fullstack Web Developer
|
||||
* [ ] [Enea Xharja](https://eneaxharja.com/uses) — Web Developer
|
||||
* [ ] [Daniel Kim](https://www.danielkim.io/uses) — Software Engineer
|
||||
* [ ] [Sam Baldwin](https://sambaldwin.info/uses) — Designer and front-end developer
|
||||
* [ ] [Zack Eaton](https://zackeaton.com/uses/) - Student, Developer, Caffiene Enthusiast
|
||||
* [x] [Brad Garropy](https://bradgarropy.com/uses) - self taught ⚛ frontender @ [adobe](https://www.adobe.com/). [blogger](https://bradgarropy.com), [streamer](https://youtube.com/bradgarropy), [tweeter](https://twitter.com/bradgarropy). 📝📺🐦
|
||||
* [ ] [Stefan Zweifel](https://stefanzweifel.io/uses/) - Fullstack Web Developer
|
||||
* [ ] [Ignacio Villanueva](https://ignaciodenuevo.com/uses) - Frontend Developer 🇪🇸
|
||||
* [ ] [Sheree Peña](https://smariapena.com/uses) - Front Ender, Tester.
|
||||
* [ ] [Pawel Grzybek](https://pawelgrzybek.com/uses/) - Software Engineer at Mindera
|
||||
* [ ] [Jessica Dembe](https://www.jessicadembe.tech/uses/) - Software Engineer
|
||||
* [ ] [Keziah Moselle](https://blog.keziahmoselle.fr/uses/) - Front-end developer
|
||||
* [x] [Scott Zirkel](https://scottzirkel.com/uses) - Developer, Designer, Artist, Writer
|
||||
* [x] [Maxence Poutord](https://www.maxpou.fr/uses/) - Front-end Engineer and Nomadic worker
|
||||
* [x] [Jonathan Speek](https://speek.design/uses/) - Fullstack Developer, Designer, Musician
|
||||
* [ ] [Nervewax](https://nervewax.com/uses/) - Designer / Developer
|
||||
* [ ] [Niko Heikkilä](https://nikoheikkila.fi/uses/) - Backend Developer & DevOps Engineer at Paytrail
|
||||
* [ ] [Sil van Diepen](https://silvandiepen.nl/uses/) - Creative Front-end Developer
|
||||
* [ ] [Matthias Hampel](https://dev.to/fullstack_to/tools-services-i-use-je9) - Fullstack Software Engineer / DevOps Enthusiast
|
||||
* [ ] [Ste Grainer](https://stegrainer.com/uses) - Product designer, front-end developer, and writer
|
||||
* [x] [Scott Tolinski](https://kit.com/leveluptutorials/podcasting-screencasting-gear) - Web Developer, Tutorial Maker, Podcaster.
|
||||
* [ ] [Ben Hong](https://www.bencodezen.io/uses/) - Senior Frontend Engineer @ Meltano GitLab
|
||||
* [ ] [Danny de Vries](https://dandevri.es/uses/) - Indie Maker and Lecturer
|
||||
* [x] [Scott Spence](https://scottspence.me/uses) - Web Engineer @ Karmarama
|
||||
* [ ] [Stephen Senkomago Musoke](https://ssmusoke.com/uses/) - Software Engineer [METS](https://mets.or.ug/), [UCSF Informatics Hub](https://globalhealthsciences.ucsf.edu/resources/informatics-hub) & PHP lover by night 🇺🇬
|
||||
* [ ] [Gideon Bamuleseyo](https://medium.com/developer-circle-kampala/what-i-use-my-tools-of-trade-552655db4b8d) - Software Engineer [Andela](https://andela.com/), JavaScript junkie 🇺🇬
|
||||
* [ ] [Jason Cory Alvernaz](https://jasoncoryalvernaz.com/uses/) - Fullstack Web Developer, Freelancer, Designer
|
||||
* [ ] [Freek Van der Herten](https://freek.dev/uses/) - Developer, Package Creator, Conference Speaker, Blogger 🇧🇪
|
||||
* [ ] [Adam Wathan](https://adamwathan.me/uses/) - Fullstack Web Developer, Entrepeneur, Maker of courses, Speaker, Blogger, Podcaster 🇨🇦
|
||||
* [x] [Josh Manders](https://joshmanders.com/uses/) - Full Snack Developer and Indie Maker 🌯
|
||||
* [x] [Daniel Wirtz](https://danielwirtz.com/uses/) - Designer who codes @Crisp Studio
|
||||
* [x] [Harry Wolff](https://hswolff.com/uses/) - Front-end engineer and YouTouber
|
||||
* [x] [Pouria Ezzati](https://pouria.dev/uses/) - Web developer
|
||||
* [x] [James Mills](https://jamesmills.co.uk/uses/) - Web Consultant
|
||||
* [x] [Jeffrey Way](https://laracasts.com/blog/laracasts-uses) - Laracasts author
|
||||
* [x] [Terry Godier](https://terrygodier.com/uses/) - Developer and Marketer
|
||||
* [x] [David O'Trakoun](https://www.davidosomething.com/uses/) - Software Engineer
|
||||
* [x] [Nuno Maduro](https://nunomaduro.com/uses/) - Software engineer, Open Source contributor, Speaker
|
||||
* [x] [Erno Salo](https://endormi.io/uses/) - Full Stack Developer and Open Source Contributor
|
||||
* [x] [James Brooks](https://james.brooks.page/uses/) - Software Developer at Laravel and Podcaster
|
||||
* [x] [Béla Varga](http://ecmanauten.de/uses/) - Front-end Developer, Meetup & Event Organizer and UX/UI Designer
|
||||
|
||||
[awesome-badge]: https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg
|
||||
13
netlify.toml
Normal file
13
netlify.toml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
[build]
|
||||
command = "remix build"
|
||||
publish = "public"
|
||||
|
||||
[dev]
|
||||
command = "remix watch"
|
||||
port = 3000
|
||||
autoLaunch = false
|
||||
|
||||
[[headers]]
|
||||
for = "/build/*"
|
||||
[headers.values]
|
||||
"Cache-Control" = "public, max-age=31536000, s-maxage=31536000"
|
||||
34825
package-lock.json
generated
34825
package-lock.json
generated
File diff suppressed because it is too large
Load diff
87
package.json
87
package.json
|
|
@ -5,69 +5,56 @@
|
|||
"author": "Wes Bos",
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"wesbos"
|
||||
"wesbos/typescript"
|
||||
]
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 12"
|
||||
"node": ">= 16"
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.2.1",
|
||||
"@actions/exec": "^1.0.3",
|
||||
"@actions/github": "^2.0.1",
|
||||
"@babel/core": "^7.16.7",
|
||||
"@babel/eslint-parser": "^7.16.5",
|
||||
"@babel/preset-react": "^7.16.7",
|
||||
"@types/node": "^16.11.19",
|
||||
"@typescript-eslint/eslint-plugin": "^5.9.1",
|
||||
"@typescript-eslint/parser": "^5.9.1",
|
||||
"@actions/core": "^1.10.0",
|
||||
"@actions/exec": "^1.1.1",
|
||||
"@actions/github": "^5.1.1",
|
||||
"@babel/core": "^7.21.0",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@netlify/edge-functions": "^2.0.0",
|
||||
"@netlify/functions": "^1.4.0",
|
||||
"@netlify/remix-edge-adapter": "^1.0.0",
|
||||
"@remix-run/dev": "^1.13.0",
|
||||
"@remix-run/netlify": "^1.13.0",
|
||||
"@remix-run/node": "^1.13.0",
|
||||
"@remix-run/react": "^1.13.0",
|
||||
"@remix-run/serve": "^1.13.0",
|
||||
"@remix-run/server-runtime": "^1.13.0",
|
||||
"@types/node": "^18.14.0",
|
||||
"@types/react": "^18.0.28",
|
||||
"@types/react-dom": "^18.0.11",
|
||||
"country-emoji": "^1.5.6",
|
||||
"eslint-config-airbnb-typescript": "^16.1.0",
|
||||
"gatsby": "^4.5.0",
|
||||
"gatsby-image": "^3.11.0",
|
||||
"gatsby-plugin-manifest": "^4.5.0",
|
||||
"gatsby-plugin-offline": "^5.5.0",
|
||||
"gatsby-plugin-react-helmet": "^5.5.0",
|
||||
"gatsby-plugin-sharp": "^4.5.0",
|
||||
"gatsby-plugin-styled-components": "^5.5.0",
|
||||
"gatsby-plugin-web-font-loader": "^1.0.4",
|
||||
"gatsby-source-filesystem": "^4.5.0",
|
||||
"gatsby-transformer-sharp": "^4.5.0",
|
||||
"joi": "^17.5.0",
|
||||
"isbot": "^3.6.6",
|
||||
"joi": "^17.8.1",
|
||||
"netlify-cli": "^13.0.0",
|
||||
"normalize.css": "^8.0.1",
|
||||
"prop-types": "^15.8.1",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-helmet": "^6.1.0",
|
||||
"styled-components": "5.3.3",
|
||||
"typescript": "^4.5.4"
|
||||
"react-is": "^18.2.0",
|
||||
"styled-components": "5.3.6",
|
||||
"typescript": "^4.9.5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "gatsby build",
|
||||
"develop": "gatsby develop",
|
||||
"start": "npm run develop",
|
||||
"serve": "gatsby serve",
|
||||
"clean": "gatsby clean"
|
||||
"build": "netlify build",
|
||||
"dev": "NODE_ENV=development netlify dev"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.6.0",
|
||||
"eslint-config-airbnb": "^19.0.4",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-config-wesbos": "^3.0.2",
|
||||
"eslint-plugin-html": "^6.2.0",
|
||||
"eslint-plugin-import": "^2.25.4",
|
||||
"eslint-plugin-jsx-a11y": "^6.5.1",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-react": "^7.28.0",
|
||||
"eslint-plugin-react-hooks": "^4.3.0",
|
||||
"husky": "^4.0.10",
|
||||
"lint-staged": "^9.5.0",
|
||||
"prettier": "^2.5.1"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
}
|
||||
"@types/styled-components": "^5.1.26",
|
||||
"eslint": "^8.34.0",
|
||||
"eslint-config-wesbos": "^3.2.3",
|
||||
"husky": "^8.0.3",
|
||||
"lint-staged": "^13.1.2",
|
||||
"postcss": "^8.4.21",
|
||||
"postcss-nesting": "^11.2.1",
|
||||
"prettier": "^2.8.4"
|
||||
},
|
||||
"lint-staged": {
|
||||
"src/data.js": [
|
||||
|
|
|
|||
13649
pnpm-lock.yaml
Normal file
13649
pnpm-lock.yaml
Normal file
File diff suppressed because it is too large
Load diff
5
postcss.config.js
Normal file
5
postcss.config.js
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
const postcssNesting = require("postcss-nesting");
|
||||
|
||||
module.exports = {
|
||||
plugins: [postcssNesting()],
|
||||
};
|
||||
BIN
public/default.png
Normal file
BIN
public/default.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 755 B |
14
readme.md
14
readme.md
|
|
@ -30,17 +30,23 @@ This readme is auto-generated from the data.js file, so please don't PR this fil
|
|||
|
||||
# Awesome Uses ![Awesome][awesome-badge]
|
||||
|
||||
* [Vladimir Vo](https://vldmr.website/uses) — Frontend developer with passion for great product design
|
||||
* [uncenter](https://www.uncenter.org/uses) — Very incompetent developer
|
||||
* [Donavon West](https://donavon.com/uses) — Spread Love {...❤️}
|
||||
* [Justin Mahar](https://justinmahar.com/uses/) — Extremely bald Software Architect & Content Creator
|
||||
* [Syofyan Zuhad](https://syofyan-profile.vercel.app/uses/) — Full Stack Software Engineer 🇮🇩
|
||||
* [Zilvinas Kucinskas](https://www.ziku.dev/uses/) — Full Stack Ruby on Rails Engineer and Entrepreneur
|
||||
* [Alex O'Reilly](https://alekzandriia.com/uses/) — Scientist turned Web developer from the Great White North.
|
||||
* [Martin Bean](https://martinbean.dev/uses) — Web developer and software engineer.
|
||||
* [Dominic Ruggiero](https://userexe.me/uses) — Student and idiot
|
||||
* [Maicol Santos](https://maicolsantos.github.io/#/uses) — Front End Developer.
|
||||
* [Carretta Riccardo](https://carrettariccardo.dev/uses/) — Software Developer & UX/UI Designer
|
||||
* [Josh Medeski](https://www.joshmedeski.com/uses/) — Full-stack developer and content creator.
|
||||
* [Simon Rogers](https://midnite.uk/uses) — Software Engineer
|
||||
* [Allan Im](https://allanim.com/uses) — Software Engineer
|
||||
* [Rev](https://cinnamoroll.me/uses) — A Software developer and artist based in Europe.
|
||||
* [Vijay Goswmai](https://vijaygoswami.in/uses) — Full Stack Developer from Agra, Uttar Pradesh
|
||||
* [Edimar Calebe Castanho](https://blog.calebe.dev.br/uses.html) — A passionate embedded systems developer from Brazil
|
||||
* [Ihtisham Khan](https://iihtisham.com/uses.html) — Full-Stack Web Developer | Tech Enthusiast
|
||||
* [Robb Knight](https://rknight.me/uses) — Developer, Podcaster, Lego Builder, Cat Owner
|
||||
* [Riley](https://riley-uses.netlify.app/) — Software Developer
|
||||
|
|
@ -189,10 +195,12 @@ This readme is auto-generated from the data.js file, so please don't PR this fil
|
|||
* [Matías Hernández](https://github.com/matiasfh/uses) — Frontend Engineer, Podcaster, Father, Calisthenic Athlete
|
||||
* [Sean Coker](https://sean.is/using) — Creator & Thinker. Sometimes simultaneously.
|
||||
* [Michael Bonner](https://michaelbonner.dev/uses) — Full stack JavaScript and PHP developer in Salt Lake City, USA
|
||||
* [Filip Kalousek](https://blog.filipkalousek.cz/uses/setup) — Frontend Developer & Idea Maker
|
||||
* [Agu Valeriani](https://agustinvaleriani.com/uses) — Software developer, previously more full stack, lately focused on frontend. Enjoy traveling and gaming.
|
||||
* [Yash Singh](https://www.yashsingh.us/uses) — Fullstack web software developer
|
||||
* [Gabor Gyure](https://www.gaborgyure.com/uses) — Fullstack developer with lots of love for industry and engineering in Europe. In love with boardsports, the semantic and accessible web
|
||||
* [Ben Brougher](https://benbrougher.tech/uses) — Full stack enterprise web devloper from the Pacific Northwest.
|
||||
* [Dawit Mekonnen](https://dawit.dev/uses) — Full stack developer and javascript enthusiast.
|
||||
* [Vincent Lejtzén](https://lejtzendesign.se/en/uses) — Front end developer with love for design, user experience and SEO.
|
||||
* [Yves Engetschwiler](http://bee-interactive.ch/uses) — Developer, cms enthusiast, bicycle traveler, content creator, Independent at Bee Interactive
|
||||
* [Sapan Bodiwala](https://sapanbodiwala.com/uses) — Full Stack Software Engineer
|
||||
|
|
@ -344,7 +352,7 @@ This readme is auto-generated from the data.js file, so please don't PR this fil
|
|||
* [Chris Otto](https://chrisotto.dev/uses/) — Software engineer. I enjoy JavaScript, DevOps and Testing.
|
||||
* [Chris Berry](http://chrisberry.io/uses) — Designer / Developer 🦄, Linux advocate, mechanical keyboard connoisseur
|
||||
* [James Quick](https://jamesqquick.com/uses) — Developer Advocate Engineer at @auth0 and content creator
|
||||
* [Federico Vitale](https://fedevitale.dev/uses) — 20yo, Self Taught FullStack Developer, Full Time. Bikes lover, Tech (obviously) enthusiast.
|
||||
* [Federico Vitale](https://fedevitale.dev/uses) — Software Engineer based in Rome
|
||||
* [Vishwasa Navada K](https://vishwas.tech/uses) — Geek. Open source Enthusiast. Occasional blogger, photographer and traveler.
|
||||
* [Silvestar Bistrović](https://www.silvestar.codes/uses/) — Fearless web engineer, CSS developer, JAMstack enthusiast, and WordPress theme specialist.
|
||||
* [Adam Schwartz](https://adamschwartz.co/uses/) — Software developer, designer, film music composer
|
||||
|
|
@ -370,6 +378,7 @@ This readme is auto-generated from the data.js file, so please don't PR this fil
|
|||
* [Robin Bakker](https://robinbakker.nl/uses) — Web Developer
|
||||
* [Alessia Bellisario](https://aless.co/uses) — Web engineer, mechanical keyboard builder, plotter art maker.
|
||||
* [AriaieBOY](https://ariaieboy.ir/uses/) — Web Developer that loves creating and sharing🇩
|
||||
* [Sunny](https://sny.sh/#uses) — Programmer, designer, musician, photographer and video editor.
|
||||
* [Russell McWhae](https://russellmcwhae.ca/uses) — Backcountry skier, photographer, designer, and web developer from Canada
|
||||
* [Karl Koch](https://www.kejk.tech/uses) — Product designer, frontend developer and musician. Building HomeHero and making other things.
|
||||
* [Praveen Kumar Purushothaman](https://blog.praveen.science/my-personal-development-environment/) — Cook, Cat Lover, Front End Architect, Full Stack Web Developer Evangelist & Cloud Computing Consultant.
|
||||
|
|
@ -402,6 +411,7 @@ This readme is auto-generated from the data.js file, so please don't PR this fil
|
|||
* [Josiah Wiebe](https://jwie.be/uses/) — Designer & developer, lifelong learner.
|
||||
* [Muhammad Oka](https://muhammadoka.dev/uses/) — Computer Science student, Cyber Security enthusiast.
|
||||
* [Benjamin Lannon](https://lannonbr.com/uses/) — Web Developer, Open Source Contributor, Livestreamer
|
||||
* [Dmytro Litvinov](https://dmytrolitvinov.com/uses/) — Full Stack Python developer from 🇺🇦
|
||||
* [Braden Watkins](https://bradenwatkins.dev/uses) — Student, Full Stack Developer, Lover of all things analog
|
||||
* [Rikin Patel](https://patelrikin.com/#uses) — Experienced Front-end developer, Passionate about Javascript
|
||||
* [Joris Hens](https://www.goodbytes.be/uses) — Web development teacher, Security and hacking enthousiast, Cook.
|
||||
|
|
@ -414,6 +424,7 @@ This readme is auto-generated from the data.js file, so please don't PR this fil
|
|||
* [Adrian Marin](https://adrianthedev.com/uses) — Product-Minded Software Engineer, Digital nomad, no-nonsense enjoyer of life, friends and family.
|
||||
* [Jahir Fiquitiva](https://jahir.dev/uses) — Passionate and Creative Full Stack Developer
|
||||
* [Christophe Querton](https://kertof.com/what-i-use) — Software Engineer, xoogler, co-founder of @accelery. Full-stack, technical debt collector. Lover of the Outdoors, BBQ, sailing.
|
||||
* [Adil Haddaoui](https://adilhaddaoui.com/uses) — Full stack Developer
|
||||
* [Jorge Ruvalcaba](https://jorgearuv.dev/uses) — Software Engineer & Aspiring Entrepreneur who does things. Frontend at Vest
|
||||
* [Michael Knepprath](https://mknepprath.com/uses) — Pokémon-obsessed Software Engineer & Designer. Twitter bots are my jam.
|
||||
* [Matt TK Taylor](https://tk.gg/uses) — Product Manager in news & media
|
||||
|
|
@ -643,6 +654,7 @@ This readme is auto-generated from the data.js file, so please don't PR this fil
|
|||
* [Tomek Buszewski](https://www.buszewski.com/uses/) — Developer and team leader based in Warsaw, Poland.
|
||||
* [Benjamin Mock](https://codesnacks.net/uses/) — coder, runner, reader, maker
|
||||
* [Dan Holloran](https://danholloran.me/uses/) — Full Stack Developer
|
||||
* [Sean Boult](https://boult.me/uses) — Full stack developer who likes ReactJS
|
||||
* [Kevin Woblick](https://www.kovah.de/uses/) — I turn Pizza into Code and Photos
|
||||
* [Michal Slepko](https://michalslepko.dev/uses) — Senior web developer learning iOS development. Live coding streamer on Twitch
|
||||
* [Michał Miszczyszyn](https://typeofweb.com/michal-miszczyszyn-uses/) — Motivated full-stack developer not afraid to use any technology. Experienced developer and leader. He, him.
|
||||
|
|
|
|||
15
remix.config.js
Normal file
15
remix.config.js
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
const { config } = require("@netlify/remix-edge-adapter");
|
||||
/** @type {import('@remix-run/dev').AppConfig} */
|
||||
module.exports = {
|
||||
...(process.env.NETLIFY || process.env.NETLIFY_LOCAL ? config : {}),
|
||||
appDirectory: "src",
|
||||
future: {
|
||||
unstable_postcss: true,
|
||||
},
|
||||
ignoredRouteFiles: ["**/.*"],
|
||||
server:
|
||||
process.env.NETLIFY || process.env.NETLIFY_LOCAL
|
||||
? "./server.js"
|
||||
: undefined,
|
||||
// serverBuildPath: ".netlify/functions-internal/server.js",
|
||||
};
|
||||
13
scripts/multiple-emojis.mjs
Normal file
13
scripts/multiple-emojis.mjs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import people from '../src/data.js';
|
||||
|
||||
function stringLength(str) {
|
||||
return Array.from(new Intl.Segmenter().segment(str)).length;
|
||||
}
|
||||
|
||||
function checkEmojiLength(person) {
|
||||
if(stringLength(person.emoji) > 1 && person.emoji) {
|
||||
console.log(person.name, person.emoji);
|
||||
}
|
||||
}
|
||||
|
||||
people.map(checkEmojiLength);
|
||||
|
|
@ -111,6 +111,7 @@ module.exports.communicateValidationOutcome = async function (
|
|||
].join('\n');
|
||||
}
|
||||
|
||||
|
||||
const { GITHUB_TOKEN } = process.env;
|
||||
const { context } = github;
|
||||
if (!GITHUB_TOKEN || !context.payload.pull_request) {
|
||||
|
|
@ -120,13 +121,13 @@ module.exports.communicateValidationOutcome = async function (
|
|||
core.info(`Comment contents:\n${comment}`);
|
||||
return;
|
||||
}
|
||||
// TODO: Re-enable a way to comment on PRs that tests passed.
|
||||
// const pullRequestNumber = context.payload.pull_request.number;
|
||||
|
||||
const pullRequestNumber = context.payload.pull_request.number;
|
||||
|
||||
const octokit = new github.GitHub(GITHUB_TOKEN);
|
||||
await octokit.issues.createComment({
|
||||
...context.repo,
|
||||
issue_number: pullRequestNumber,
|
||||
body: comment,
|
||||
});
|
||||
// const octokit = new github.getOctokit(GITHUB_TOKEN);
|
||||
// await octokit.rest.pulls.createReviewComment({
|
||||
// ...context.repo,
|
||||
// pullRequestNumber,
|
||||
// body: comment,
|
||||
// });
|
||||
};
|
||||
|
|
|
|||
20
server.ts
Normal file
20
server.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
// Import path interpreted by the Remix compiler
|
||||
import * as build from "@remix-run/dev/server-build";
|
||||
import { createRequestHandler } from "@netlify/remix-edge-adapter";
|
||||
|
||||
export default createRequestHandler({
|
||||
build,
|
||||
// process.env.NODE_ENV is provided by Remix at compile time
|
||||
mode: process.env.NODE_ENV,
|
||||
});
|
||||
|
||||
export const config = {
|
||||
cache: "manual",
|
||||
path: "/*",
|
||||
// Pass all assets to the netlify asset server
|
||||
excluded_patterns: [
|
||||
'^\\/_assets\\/[^\\/]*$',
|
||||
'^\\/shared\\/[^\\/]*$',
|
||||
'^\\/**\\/[^\\/]*$',
|
||||
],
|
||||
};
|
||||
|
|
@ -1,28 +1,4 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
const BackToTopLink = styled.a`
|
||||
position: fixed;
|
||||
bottom: 1%;
|
||||
right: 1%;
|
||||
background: var(--pink);
|
||||
color: white;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
cursor: pointer;
|
||||
border-radius: 3px;
|
||||
padding: 1rem;
|
||||
transition: opacity 0.2s;
|
||||
opacity: 0;
|
||||
text-decoration: none;
|
||||
${props =>
|
||||
props.percent > 0.25 &&
|
||||
`
|
||||
opacity: 1;
|
||||
`}
|
||||
@media screen and (max-width: 500px) {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
|
||||
function useScrollPosition() {
|
||||
const [percent, setPercent] = useState(0);
|
||||
|
|
@ -49,8 +25,8 @@ function useScrollPosition() {
|
|||
export default function BackToTop() {
|
||||
const percent = useScrollPosition();
|
||||
return (
|
||||
<BackToTopLink href="#top" title="Back To Top" percent={percent}>
|
||||
<a className={`BackToTopLink ${percent > 0.25 ? 'Show' : ''}`} href="#top" title="Back To Top">
|
||||
↑
|
||||
</BackToTopLink>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,43 +1,29 @@
|
|||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { name } from 'country-emoji';
|
||||
import styled from 'styled-components';
|
||||
import { Tag, Tags } from './Topics';
|
||||
import * as icons from '../util/icons';
|
||||
import { useParams } from '@remix-run/react';
|
||||
|
||||
function useIntersectionObserver(ref) {
|
||||
const [isIntersecting, setIntersecting] = useState(false);
|
||||
|
||||
useEffect(function() {
|
||||
const observer = new IntersectionObserver(function([entry]) {
|
||||
console.log('Run once for every time its on screen');
|
||||
console.log(entry);
|
||||
});
|
||||
// Observe the element we want to observve
|
||||
observer.observe(ref.current);
|
||||
|
||||
return () => {
|
||||
observer.unobserve(ref.current);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export default function Person({ person, currentTag }) {
|
||||
export default function Person({ person }) {
|
||||
const url = new URL(person.url);
|
||||
const twitter = person.twitter ? `https://unavatar.io/${person.twitter.replace('@', '')}` : null;
|
||||
const website = `https://unavatar.io/${url.host}`;
|
||||
const unavatar = person.twitter ? `${twitter}?fallback=${website}` : website;
|
||||
const img = `https://images.weserv.nl/?url=${unavatar}&w=100&l=9&af&il&n=-1`;
|
||||
|
||||
const { tag: currentTag } = useParams();
|
||||
return (
|
||||
<PersonWrapper>
|
||||
<PersonInner>
|
||||
<div className="PersonWrapper" style={{ contentVisibility: "auto", containIntrinsicHeight: '560px' }}>
|
||||
<div className="PersonInner">
|
||||
<header>
|
||||
<img
|
||||
width="50"
|
||||
height="50"
|
||||
src={img}
|
||||
alt={person.name}
|
||||
onError={({ currentTarget }) => {
|
||||
currentTarget.onerror = null; // prevents looping
|
||||
currentTarget.src = "/default.png";
|
||||
}}
|
||||
loading="lazy"
|
||||
/>
|
||||
<h3>
|
||||
|
|
@ -57,15 +43,15 @@ export default function Person({ person, currentTag }) {
|
|||
</a>
|
||||
</header>
|
||||
<p>{person.description}</p>
|
||||
<Tags>
|
||||
<ul className="Tags">
|
||||
{person.tags.map(tag => (
|
||||
<Tag key={tag} as="li" currentTag={tag === currentTag} small>
|
||||
<li className={`Tag small ${tag === currentTag ? 'currentTag' : ''}`} key={tag}>
|
||||
{tag}
|
||||
</Tag>
|
||||
</li>
|
||||
))}
|
||||
</Tags>
|
||||
</PersonInner>
|
||||
<PersonDeets>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="PersonDeets">
|
||||
<span className="country" title={name(person.country)}>
|
||||
{person.country}
|
||||
</span>
|
||||
|
|
@ -85,7 +71,7 @@ export default function Person({ person, currentTag }) {
|
|||
)}
|
||||
|
||||
{person.twitter && (
|
||||
<TwitterHandle>
|
||||
<div className="TwitterHandle">
|
||||
<a
|
||||
href={`https://twitter.com/${person.twitter.replace('@', '')}`}
|
||||
target="_blank"
|
||||
|
|
@ -94,15 +80,14 @@ export default function Person({ person, currentTag }) {
|
|||
<span className="at">@</span>
|
||||
{person.twitter.replace('@', '')}
|
||||
</a>
|
||||
</TwitterHandle>
|
||||
</div>
|
||||
)}
|
||||
</PersonDeets>
|
||||
</PersonWrapper>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Person.propTypes = {
|
||||
currentTag: PropTypes.string,
|
||||
person: PropTypes.shape({
|
||||
github: PropTypes.string,
|
||||
name: PropTypes.string,
|
||||
|
|
@ -112,7 +97,7 @@ Person.propTypes = {
|
|||
tags: PropTypes.arrayOf(PropTypes.string),
|
||||
country: PropTypes.string,
|
||||
computer: PropTypes.oneOf(['apple', 'windows', 'linux']),
|
||||
phone: PropTypes.oneOf(['iphone', 'android', 'windowsphone']),
|
||||
phone: PropTypes.oneOf(['iphone', 'android', 'windowsphone', 'flipphone']),
|
||||
twitter(props, propName, componentName) {
|
||||
if (!/^@?(\w){1,15}$/.test(props[propName])) {
|
||||
return new Error(
|
||||
|
|
@ -123,97 +108,3 @@ Person.propTypes = {
|
|||
},
|
||||
}),
|
||||
};
|
||||
|
||||
// Component Styles
|
||||
const PersonWrapper = styled.div`
|
||||
border: 1px solid var(--vape);
|
||||
border-radius: 5.34334px;
|
||||
box-shadow: 10px -10px 0 var(--blue2);
|
||||
display: grid;
|
||||
grid-template-rows: 1fr auto auto;
|
||||
`;
|
||||
|
||||
const PersonInner = styled.div`
|
||||
padding: 2rem;
|
||||
h3 {
|
||||
margin: 0;
|
||||
a:visited {
|
||||
color: var(--purple);
|
||||
}
|
||||
}
|
||||
header {
|
||||
display: grid;
|
||||
grid-template-rows: auto auto;
|
||||
grid-template-columns: auto 1fr;
|
||||
grid-gap: 0 1rem;
|
||||
@media all and (max-width: 400px) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
img {
|
||||
grid-row: 1 / -1;
|
||||
background: var(--lightblue);
|
||||
font-size: 1rem;
|
||||
}
|
||||
.displayLink {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
text-decoration: none;
|
||||
color: var(--vape);
|
||||
letter-spacing: 1px;
|
||||
font-size: 1.2rem;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
:hover,
|
||||
:visited {
|
||||
color: var(--pink);
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const PersonDeets = styled.div`
|
||||
display: flex;
|
||||
border-top: 1px solid var(--vape);
|
||||
> * {
|
||||
flex: 1;
|
||||
border-left: 1px solid var(--vape);
|
||||
text-align: center;
|
||||
padding: 1rem;
|
||||
display: grid;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
grid-template-columns: auto auto;
|
||||
&:first-child {
|
||||
border-left: 0;
|
||||
}
|
||||
}
|
||||
a {
|
||||
color: var(--vape);
|
||||
}
|
||||
.country {
|
||||
font-size: 3rem;
|
||||
padding-top: 2rem;
|
||||
}
|
||||
.phone {
|
||||
padding: 0;
|
||||
}
|
||||
@media all and (max-width: 400px) {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
> *:nth-child(1),
|
||||
> *:nth-child(2) {
|
||||
/* lol */
|
||||
border-bottom: 1px solid var(--vape);
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const TwitterHandle = styled.span`
|
||||
font-size: 1.24323423426928098420394802rem;
|
||||
.at {
|
||||
color: var(--yellow);
|
||||
margin-right: 2px;
|
||||
}
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -1,138 +1,52 @@
|
|||
import React, { useCallback, useContext } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import FilterContext from '../context/FilterContext';
|
||||
import { Link, useParams, useRouteLoaderData } from '@remix-run/react';
|
||||
import * as icons from '../util/icons';
|
||||
|
||||
export default function Topics() {
|
||||
const { countries, tags, devices, currentTag, setCurrentTag } = useContext(
|
||||
FilterContext
|
||||
);
|
||||
|
||||
const handleKeyDown = useCallback(
|
||||
tagName => e => {
|
||||
if (e.keyCode === 13) {
|
||||
setCurrentTag(tagName);
|
||||
}
|
||||
},
|
||||
[setCurrentTag]
|
||||
);
|
||||
const { tags, countries, devices } = useRouteLoaderData("root");
|
||||
const params = useParams();
|
||||
const currentTag = params.tag || 'all';
|
||||
|
||||
return (
|
||||
<Tags>
|
||||
{tags.map(tag => (
|
||||
<Tag
|
||||
currentTag={tag.name === currentTag}
|
||||
htmlFor={`filter-${tag.name}`}
|
||||
key={`filter-${tag.name}`}
|
||||
clickable
|
||||
onKeyDown={handleKeyDown(tag.name)}
|
||||
tabIndex="0"
|
||||
<div className="Tags">
|
||||
{tags.map((tag) => (
|
||||
<Link
|
||||
prefetch="intent"
|
||||
key={`tag-${tag.name}`}
|
||||
to={
|
||||
tag.name === "all" ? "/" : `/like/${encodeURIComponent(tag.name)}`
|
||||
}
|
||||
className={`Tag ${currentTag === tag.name ? "currentTag" : ""}`}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
name="tag"
|
||||
id={`filter-${tag.name}`}
|
||||
value={tag.name}
|
||||
checked={tag.name === currentTag}
|
||||
onChange={e => setCurrentTag(e.currentTarget.value)}
|
||||
/>
|
||||
{tag.name}
|
||||
<TagCount>{tag.count}</TagCount>
|
||||
</Tag>
|
||||
<span className="TagCount">{tag.count}</span>
|
||||
</Link>
|
||||
))}
|
||||
|
||||
{countries.map(tag => (
|
||||
<Tag
|
||||
currentTag={tag.emoji === currentTag}
|
||||
htmlFor={`filter-${tag.name}`}
|
||||
{countries.map((tag) => (
|
||||
<Link
|
||||
to={`/like/${tag.emoji}`}
|
||||
prefetch="intent"
|
||||
className={`Tag ${currentTag === tag.emoji ? "currentTag" : ""}`}
|
||||
key={`filter-${tag.name}`}
|
||||
title={tag.name}
|
||||
clickable
|
||||
onKeyDown={handleKeyDown(tag.name)}
|
||||
tabIndex="0"
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
name="tag"
|
||||
id={`filter-${tag.name}`}
|
||||
value={tag.emoji}
|
||||
checked={tag.emoji === currentTag}
|
||||
onChange={e => setCurrentTag(e.currentTarget.value)}
|
||||
/>
|
||||
<TagEmoji>{tag.emoji}</TagEmoji>
|
||||
<TagCount>{tag.count}</TagCount>
|
||||
</Tag>
|
||||
<span className="TagEmoji">{tag.emoji}</span>
|
||||
<span className="TagCount">{tag.count}</span>
|
||||
</Link>
|
||||
))}
|
||||
|
||||
{devices.map(tag => (
|
||||
<Tag
|
||||
currentTag={tag.name === currentTag}
|
||||
htmlFor={`filter-${tag.name}`}
|
||||
{devices.map((tag) => (
|
||||
<Link
|
||||
to={`/like/${tag.name}`}
|
||||
className={`Tag ${currentTag === tag.name ? "currentTag" : ""}`}
|
||||
prefetch="intent"
|
||||
key={`filter-${tag.name}`}
|
||||
title={tag.name}
|
||||
clickable
|
||||
onKeyDown={handleKeyDown(tag.name)}
|
||||
tabIndex="0"
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
name="computer"
|
||||
id={`filter-${tag.name}`}
|
||||
value={tag.name}
|
||||
checked={tag.name === currentTag}
|
||||
onChange={e => setCurrentTag(e.currentTarget.value)}
|
||||
/>
|
||||
<img height="20px" src={icons[tag.name]} alt={tag.name} />
|
||||
<TagCount>{tag.count}</TagCount>
|
||||
</Tag>
|
||||
<span className="TagCount">{tag.count}</span>
|
||||
</Link>
|
||||
))}
|
||||
</Tags>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Component Styles
|
||||
const Tags = styled.ul`
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
`;
|
||||
|
||||
const Tag = styled.label`
|
||||
background: var(--pink);
|
||||
margin: 2px;
|
||||
border-radius: 3px;
|
||||
font-size: ${props => (props.small ? `1.2rem;` : `1.7rem;`)};
|
||||
padding: 5px;
|
||||
color: hsla(0, 100%, 100%, 0.8);
|
||||
transition: background-color 0.2s;
|
||||
cursor: ${props => (props.clickable ? 'pointer' : 'default')};
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
align-items: center;
|
||||
input {
|
||||
display: none;
|
||||
}
|
||||
${props =>
|
||||
props.currentTag &&
|
||||
`
|
||||
background: var(--yellow);
|
||||
color: hsla(0, 100%, 0%, 0.8);
|
||||
`}
|
||||
`;
|
||||
|
||||
const TagEmoji = styled.span`
|
||||
transform: scale(1.45);
|
||||
`;
|
||||
|
||||
const TagCount = styled.span`
|
||||
background: var(--blue);
|
||||
font-size: 1rem;
|
||||
color: white;
|
||||
padding: 2px;
|
||||
border-radius: 2px;
|
||||
margin-left: 5px;
|
||||
`;
|
||||
|
||||
export { Tag, Tags };
|
||||
|
|
|
|||
|
|
@ -1,35 +1,23 @@
|
|||
import React from 'react';
|
||||
import { Link } from 'gatsby';
|
||||
import PropTypes from 'prop-types';
|
||||
import Helmet from 'react-helmet';
|
||||
import styled from 'styled-components';
|
||||
import FavIcon from './FavIcon';
|
||||
|
||||
function Header({ siteTitle, siteDescription, siteUrl }) {
|
||||
|
||||
return (
|
||||
<HeaderWrapper className="header">
|
||||
<div className="header HeaderWrapper">
|
||||
<FavIcon />
|
||||
<Helmet>
|
||||
<html lang="en" amp />
|
||||
<title>{siteTitle}</title>
|
||||
<meta name="description" content={siteDescription} />
|
||||
<link rel="canonical" href={siteUrl} />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:creator" content="@wesbos" />
|
||||
<meta name="twitter:title" content={siteTitle} />
|
||||
<meta name="twitter:description" content={siteDescription} />
|
||||
<meta name="twitter:image" content={`${siteUrl}/twitter-card.png`} />
|
||||
</Helmet>
|
||||
<div>
|
||||
<h1 id="top">
|
||||
<Link to="/">/uses</Link>
|
||||
<a href="/">/uses</a>
|
||||
</h1>
|
||||
<p>
|
||||
A list of <code>/uses</code> pages detailing developer setups, gear,
|
||||
software and configs.
|
||||
</p>
|
||||
</div>
|
||||
</HeaderWrapper>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Header.propTypes = {
|
||||
|
|
@ -45,11 +33,3 @@ Header.defaultProps = {
|
|||
};
|
||||
|
||||
export default Header;
|
||||
|
||||
// Component Styles
|
||||
const HeaderWrapper = styled.header`
|
||||
text-align: center;
|
||||
h1 {
|
||||
font-size: 6rem;
|
||||
}
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -1,134 +1,41 @@
|
|||
/**
|
||||
* Layout component that queries for data
|
||||
* with Gatsby's useStaticQuery component
|
||||
*
|
||||
* See: https://www.gatsbyjs.org/docs/use-static-query/
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useStaticQuery, graphql } from 'gatsby';
|
||||
|
||||
import styled, { createGlobalStyle } from 'styled-components';
|
||||
import Header from './header';
|
||||
import 'normalize.css';
|
||||
|
||||
const Layout = ({ children }) => {
|
||||
const data = useStaticQuery(graphql`
|
||||
query SiteTitleQuery {
|
||||
site {
|
||||
siteMetadata {
|
||||
title
|
||||
description
|
||||
siteUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
export default function Layout({ children }) {
|
||||
return (
|
||||
<>
|
||||
<GlobalStyle />
|
||||
<Main>
|
||||
<Header
|
||||
siteTitle={data.site.siteMetadata.title}
|
||||
siteDescription={data.site.siteMetadata.description}
|
||||
siteUrl={data.site.siteMetadata.siteUrl}
|
||||
/>
|
||||
{children}
|
||||
<footer>
|
||||
<center ya-i-used-a-center-tag="sue me">
|
||||
<p>
|
||||
Made by <a href="https://wesbos.com">Wes Bos</a> with{' '}
|
||||
<a href="https://www.gatsbyjs.org">Gatsby</a> ©{' '}
|
||||
{new Date().getFullYear() - Math.floor(Math.random() * 777)}
|
||||
</p>
|
||||
<p>
|
||||
Source on{' '}
|
||||
<a href="https://github.com/wesbos/awesome-uses/">GitHub</a>. Add
|
||||
yourself!
|
||||
</p>
|
||||
<p>
|
||||
Icons from <a href="https://icons8.com">icons8.com</a>
|
||||
</p>
|
||||
<p>
|
||||
Domain provided by <a href="https://get.tech/">.Tech</a>
|
||||
</p>
|
||||
<p>
|
||||
Hosted on <a href="https://netlify.com">Netlify</a>
|
||||
</p>
|
||||
</center>
|
||||
</footer>
|
||||
</Main>
|
||||
</>
|
||||
<main className="Main">
|
||||
<Header />
|
||||
{children}
|
||||
<footer>
|
||||
<center ya-i-used-a-center-tag="sue me">
|
||||
<p>
|
||||
Made by <a href="https://wesbos.com">Wes Bos</a> with{" "}
|
||||
<a href="https://www.remix.run">Remix</a> ©{" "}
|
||||
{new Date().getFullYear()}
|
||||
</p>
|
||||
<p>
|
||||
Source on{" "}
|
||||
<a href="https://github.com/wesbos/awesome-uses/">GitHub</a>. Add
|
||||
yourself!
|
||||
</p>
|
||||
<p>
|
||||
Icons from <a href="https://icons8.com">icons8.com</a>
|
||||
</p>
|
||||
<p>
|
||||
Domain provided by <a href="https://get.tech/">.Tech</a>
|
||||
</p>
|
||||
<p>
|
||||
Hosted on <a href="https://netlify.com">Netlify</a>
|
||||
</p>
|
||||
<p suppressHydrationWarning>Rendered Fresh</p>
|
||||
</center>
|
||||
</footer>
|
||||
</main>
|
||||
);
|
||||
};
|
||||
|
||||
Layout.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
|
||||
export default Layout;
|
||||
|
||||
// Global Styles
|
||||
const GlobalStyle = createGlobalStyle`
|
||||
html {
|
||||
--purple: #b066ff;
|
||||
--blue: #203447;
|
||||
--lightblue: #1f4662;
|
||||
--blue2: #1C2F40;
|
||||
--yellow: #ffc600;
|
||||
--pink: #EB4471;
|
||||
--vape: #d7d7d7;
|
||||
background: var(--blue);
|
||||
color: var(--vape);
|
||||
font-family: 'Fira Mono', monospace;
|
||||
font-weight: 100;
|
||||
font-size: 10px;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
body {
|
||||
font-size: 2rem;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
h1,h2,h3,h4,h5,h6 {
|
||||
font-weight: 500;
|
||||
}
|
||||
a {
|
||||
color: var(--yellow);
|
||||
text-decoration-color: var(--pink);
|
||||
font-style: italic;
|
||||
}
|
||||
code {
|
||||
background: var(--lightblue);
|
||||
}
|
||||
::selection {
|
||||
background: var(--yellow);
|
||||
color: var(--blue);
|
||||
}
|
||||
|
||||
body::-webkit-scrollbar {
|
||||
width: 12px;
|
||||
}
|
||||
html {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: var(--yellow) var(--blue);
|
||||
}
|
||||
body::-webkit-scrollbar-track {
|
||||
background: var(--blue);
|
||||
}
|
||||
body::-webkit-scrollbar-thumb {
|
||||
background-color: var(--yellow) ;
|
||||
border-radius: 6px;
|
||||
border: 3px solid var(--blue);
|
||||
}
|
||||
`;
|
||||
|
||||
// Component Styles
|
||||
const Main = styled.main`
|
||||
display: grid;
|
||||
grid-gap: 3rem;
|
||||
max-width: 1900px;
|
||||
padding: 0 3rem;
|
||||
margin: 5rem auto;
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -1,53 +0,0 @@
|
|||
import React, { createContext, useState } from 'react';
|
||||
import { useStaticQuery, graphql } from 'gatsby';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const FilterContext = createContext();
|
||||
|
||||
const FilterProvider = function({ children }) {
|
||||
const [currentTag, setCurrentTag] = useState('all');
|
||||
|
||||
const { allTag, allCountry, allDevice } = useStaticQuery(graphql`
|
||||
query FilterQuery {
|
||||
allTag {
|
||||
nodes {
|
||||
name
|
||||
count
|
||||
}
|
||||
}
|
||||
allCountry {
|
||||
nodes {
|
||||
count
|
||||
emoji
|
||||
name
|
||||
}
|
||||
}
|
||||
allDevice {
|
||||
nodes {
|
||||
count
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
return (
|
||||
<FilterContext.Provider
|
||||
value={{
|
||||
tags: allTag.nodes,
|
||||
countries: allCountry.nodes,
|
||||
devices: allDevice.nodes,
|
||||
currentTag,
|
||||
setCurrentTag,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</FilterContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
FilterProvider.propTypes = {
|
||||
children: PropTypes.element,
|
||||
};
|
||||
|
||||
export default FilterContext;
|
||||
export { FilterProvider };
|
||||
329
src/data.js
329
src/data.js
|
|
@ -21,6 +21,30 @@
|
|||
* Keep this a commonjs export.
|
||||
*/
|
||||
module.exports = [
|
||||
{
|
||||
name: 'Vladimir Vo',
|
||||
description: 'Frontend developer with passion for great product design',
|
||||
url: 'https://vldmr.website/uses',
|
||||
twitter: '@v1in_',
|
||||
emoji: '🖖',
|
||||
country: '🇵🇱',
|
||||
computer: 'apple',
|
||||
phone: 'iphone',
|
||||
tags: [
|
||||
'Astro',
|
||||
'Front End',
|
||||
'Developer',
|
||||
'JavaScript',
|
||||
'TypeScript',
|
||||
'React',
|
||||
'Next',
|
||||
'JAMstack',
|
||||
'Netlify',
|
||||
'Vercel',
|
||||
'HTML',
|
||||
'CSS',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'uncenter',
|
||||
description: 'Very incompetent developer',
|
||||
|
|
@ -38,6 +62,48 @@ module.exports = [
|
|||
'Developer',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Donavon West',
|
||||
description: 'Spread Love {...❤️}',
|
||||
url: 'https://donavon.com/uses',
|
||||
twitter: '@donavon',
|
||||
emoji: '❤️',
|
||||
country: '🇺🇸',
|
||||
computer: 'apple',
|
||||
phone: 'android',
|
||||
tags: [
|
||||
'API',
|
||||
'Back End',
|
||||
'Developer',
|
||||
'Front End',
|
||||
'Full Stack',
|
||||
'Git',
|
||||
'GitHub',
|
||||
'GraphQL',
|
||||
'HTML/CSS',
|
||||
'JAMstack',
|
||||
'JavaScript',
|
||||
'macOS',
|
||||
'Markdown',
|
||||
'MDX',
|
||||
'Netlify',
|
||||
'Node.js',
|
||||
'npm',
|
||||
'Open Source Software',
|
||||
'React',
|
||||
'Remix',
|
||||
'REST',
|
||||
'Sass',
|
||||
'SEO',
|
||||
'Serverless',
|
||||
'Software Developer',
|
||||
'Software Engineer',
|
||||
'TypeScript',
|
||||
'VS Code',
|
||||
'Web Developer',
|
||||
'Web Development',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Justin Mahar',
|
||||
description: 'Extremely bald Software Architect & Content Creator',
|
||||
|
|
@ -148,6 +214,39 @@ module.exports = [
|
|||
'Maker',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Alex O'Reilly",
|
||||
description: 'Scientist turned Web developer from the Great White North.',
|
||||
url: 'https://alekzandriia.com/uses/',
|
||||
twitter: '@alekzandriia',
|
||||
// Allowing this multiple emoji because its cool
|
||||
emoji: '🥼➡️👩💻',
|
||||
country: '🇨🇦',
|
||||
computer: 'apple',
|
||||
phone: 'iphone',
|
||||
tags: [
|
||||
'Web Developer',
|
||||
'Developer',
|
||||
'Software Engineer',
|
||||
'Designer',
|
||||
'Full Stack',
|
||||
'Front End',
|
||||
'Backend',
|
||||
'Wordpress',
|
||||
'React',
|
||||
'Gatsby',
|
||||
'Javascript',
|
||||
'HTML',
|
||||
'CSS',
|
||||
'SEO',
|
||||
'Maker',
|
||||
'Problem Solver',
|
||||
'Artist',
|
||||
'Student',
|
||||
'Self Taught',
|
||||
'No CS Degree',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Martin Bean',
|
||||
description: 'Web developer and software engineer.',
|
||||
|
|
@ -184,6 +283,30 @@ module.exports = [
|
|||
computer: 'linux',
|
||||
tags: ['Student', 'Node.js', 'Javascript', 'Ubuntu'],
|
||||
},
|
||||
{
|
||||
name: 'Maicol Santos',
|
||||
description: 'Front End Developer.',
|
||||
url: 'https://maicolsantos.github.io/#/uses',
|
||||
emoji: '🤘🏻',
|
||||
country: '🇧🇷',
|
||||
computer: 'apple',
|
||||
phone: 'iphone',
|
||||
tags: [
|
||||
'JavaScript',
|
||||
'TypeScript',
|
||||
'React',
|
||||
'React Native',
|
||||
'Next',
|
||||
'Vue.js',
|
||||
'Angular',
|
||||
'AlpineJS',
|
||||
'Front End',
|
||||
'Redux',
|
||||
'React Query',
|
||||
'GraphQL',
|
||||
'Developer',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Carretta Riccardo',
|
||||
description: 'Software Developer & UX/UI Designer',
|
||||
|
|
@ -214,6 +337,35 @@ module.exports = [
|
|||
'Designer',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Josh Medeski',
|
||||
description: 'Full-stack developer and content creator.',
|
||||
url: 'https://www.joshmedeski.com/uses/',
|
||||
twitter: '@joshmedeski',
|
||||
emoji: '😄',
|
||||
country: '🇺🇸',
|
||||
computer: 'apple',
|
||||
phone: 'iphone',
|
||||
tags: [
|
||||
'Astro',
|
||||
'CSS',
|
||||
'Developer',
|
||||
'Fish shell',
|
||||
'Full Stack',
|
||||
'JAMstack',
|
||||
'Neovim',
|
||||
'Netlify',
|
||||
'Node.js',
|
||||
'React',
|
||||
'Remix',
|
||||
'Remote',
|
||||
'Tailwind CSS',
|
||||
'Teacher',
|
||||
'tmux',
|
||||
'TypeScript',
|
||||
'Vim',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Simon Rogers',
|
||||
description: 'Software Engineer',
|
||||
|
|
@ -303,6 +455,32 @@ module.exports = [
|
|||
'UX',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Edimar Calebe Castanho',
|
||||
description: 'A passionate embedded systems developer from Brazil',
|
||||
url: 'https://blog.calebe.dev.br/uses.html',
|
||||
emoji: '⚒️',
|
||||
country: '🇧🇷',
|
||||
computer: 'linux',
|
||||
phone: 'iphone',
|
||||
tags: [
|
||||
'C',
|
||||
'C++',
|
||||
'Python',
|
||||
'Node JS',
|
||||
'Back End',
|
||||
'Debian',
|
||||
'Linux',
|
||||
'FreeRTOS',
|
||||
'Emacs',
|
||||
'Git',
|
||||
'Github',
|
||||
'Gitlab',
|
||||
'DevOps',
|
||||
'Software Developer',
|
||||
'Embedded software developer',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Ihtisham Khan',
|
||||
description: 'Full-Stack Web Developer | Tech Enthusiast',
|
||||
|
|
@ -509,7 +687,7 @@ module.exports = [
|
|||
'Technologist, software creator, wannabe hacker. Father. Dog Lover.',
|
||||
url: 'https://codewithlove.blog/uses',
|
||||
twitter: '@amore_codes',
|
||||
emoji: '👨💻 ',
|
||||
emoji: '👨💻',
|
||||
country: '🇺🇸',
|
||||
computer: 'apple',
|
||||
phone: 'iphone',
|
||||
|
|
@ -1764,7 +1942,7 @@ module.exports = [
|
|||
'Web Developer, open-source enthusiast, gamer, and lifelong learner.',
|
||||
url: 'https://www.amrdiab.dev/uses',
|
||||
twitter: '@AmrHdiab',
|
||||
emoji: '🚀👨💻',
|
||||
emoji: '👨💻',
|
||||
country: '🇬🇧',
|
||||
computer: 'windows',
|
||||
phone: 'android',
|
||||
|
|
@ -1793,7 +1971,7 @@ module.exports = [
|
|||
'🧙♂️ Open Source Engineer at prestd, GitHub Star - 🏊♂️🚴♂️🏃♂️ Triathlete (IRONMAN distance) - 🌱 ᴘʟᴀɴᴛ-ʙᴀsᴇᴅ',
|
||||
url: 'https://avelino.run/uses',
|
||||
twitter: '@avelinorun',
|
||||
emoji: '🏊♂️🚴♂️🏃♂️',
|
||||
emoji: '🏊♂️',
|
||||
country: '🇧🇷',
|
||||
computer: 'apple',
|
||||
phone: 'iphone',
|
||||
|
|
@ -1813,7 +1991,7 @@ module.exports = [
|
|||
description: 'Product Designer. Photographer. Traveler.',
|
||||
url: 'https://desktopofsamuel.com/uses',
|
||||
twitter: '@desktopofsamuel',
|
||||
emoji: '🚀💻',
|
||||
emoji: '🚀',
|
||||
country: '🇭🇰',
|
||||
computer: 'apple',
|
||||
phone: 'iphone',
|
||||
|
|
@ -1918,7 +2096,7 @@ module.exports = [
|
|||
description:
|
||||
'Web Developer, Product Manager, Digital Marketer, always trying to learn more.',
|
||||
url: 'https://yourdigitalaid.com/uses/',
|
||||
emoji: '☕☕☕☕',
|
||||
emoji: '☕',
|
||||
twitter: '@William65692091',
|
||||
country: '🇨🇦',
|
||||
computer: 'windows',
|
||||
|
|
@ -3660,6 +3838,29 @@ module.exports = [
|
|||
'Ionic',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Filip Kalousek',
|
||||
description: 'Frontend Developer & Idea Maker',
|
||||
url: 'https://blog.filipkalousek.cz/uses/setup',
|
||||
country: '🇨🇿',
|
||||
twitter: 'kalousekf',
|
||||
emoji: '💡',
|
||||
computer: 'windows',
|
||||
phone: 'iphone',
|
||||
tags: [
|
||||
'Angular',
|
||||
'Deno',
|
||||
'TypeScript',
|
||||
'PostgreSQL',
|
||||
'Front End',
|
||||
'Material UI',
|
||||
'JavaScript',
|
||||
'Vue',
|
||||
'Fresh',
|
||||
'Figma',
|
||||
'MongoDB',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Agu Valeriani',
|
||||
description:
|
||||
|
|
@ -3770,6 +3971,32 @@ module.exports = [
|
|||
'PowerShell',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Dawit Mekonnen',
|
||||
description: 'Full stack developer and javascript enthusiast.',
|
||||
url: 'https://dawit.dev/uses',
|
||||
country: '🇪🇹',
|
||||
emoji: '🦖',
|
||||
computer: 'linux',
|
||||
phone: 'android',
|
||||
tags: [
|
||||
'Full Stack',
|
||||
'React',
|
||||
'Node.js',
|
||||
'TypeScript',
|
||||
'Next.js',
|
||||
'JavaScript',
|
||||
'express.js',
|
||||
'VS Code',
|
||||
'HTML',
|
||||
'CSS',
|
||||
'PostgreSQL',
|
||||
'Mongodb',
|
||||
'Graphql',
|
||||
'Docker',
|
||||
'Hyper',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Vincent Lejtzén',
|
||||
description:
|
||||
|
|
@ -4257,7 +4484,7 @@ module.exports = [
|
|||
'Fullstack Developer, Problemsolving, coffee and fancy terminaltricks!',
|
||||
url: 'https://github.com/JonasJore/dotfiles/blob/master/uses-tech.md',
|
||||
twitter: '@JonasJore',
|
||||
emoji: '🍕☕',
|
||||
emoji: '🍕',
|
||||
country: '🇳🇴',
|
||||
computer: 'linux',
|
||||
phone: 'android',
|
||||
|
|
@ -4277,7 +4504,7 @@ module.exports = [
|
|||
description: 'Fullstack Developer',
|
||||
url: 'https://marko-haberl.com/uses',
|
||||
twitter: '@marko_haberl',
|
||||
emoji: '🚀 💻',
|
||||
emoji: '🚀',
|
||||
country: '🇭🇷',
|
||||
computer: 'linux',
|
||||
phone: 'iphone',
|
||||
|
|
@ -4319,7 +4546,7 @@ module.exports = [
|
|||
description: 'Experienced Full Stack Software Engineer & Computers Lover',
|
||||
url: 'https://adelrosarioh.me/uses',
|
||||
twitter: '@adelrosarioh',
|
||||
emoji: '💻 💻 💻',
|
||||
emoji: '💻',
|
||||
country: '🇩🇴',
|
||||
computer: 'linux',
|
||||
phone: 'android',
|
||||
|
|
@ -5507,7 +5734,7 @@ module.exports = [
|
|||
description: 'Software Engineer focused on Web Technologies from India.',
|
||||
url: 'https://shubhambattoo.in/uses',
|
||||
twitter: '@Shubham_batt',
|
||||
emoji: '🖖🎧',
|
||||
emoji: '🎧',
|
||||
country: '🇮🇳',
|
||||
computer: 'linux',
|
||||
phone: 'android',
|
||||
|
|
@ -5602,7 +5829,7 @@ module.exports = [
|
|||
'Back end developer who likes to develop front end on free time 🤷♂️. And I also blog.',
|
||||
url: 'https://aaronuurman.com/uses',
|
||||
twitter: '@aaronuurman',
|
||||
emoji: '🍕🍺',
|
||||
emoji: '🍕',
|
||||
country: '🇪🇪',
|
||||
computer: 'linux',
|
||||
phone: 'android',
|
||||
|
|
@ -5691,7 +5918,7 @@ module.exports = [
|
|||
'Team lead, Experienced full-stack engineer & non-stop learner. :wq',
|
||||
url: 'https://www.notion.so/Things-Prakhil-uses-e995e61834c242f1b739be9f8819fb0c',
|
||||
twitter: '@Prakhil_tp',
|
||||
emoji: '🖮🌏🧘🔭',
|
||||
emoji: '🌏',
|
||||
country: '🇮🇳',
|
||||
computer: 'linux',
|
||||
phone: 'android',
|
||||
|
|
@ -5868,7 +6095,7 @@ module.exports = [
|
|||
'Full stack developer loving the Laravel ecosystem. Sometimes I write about it.',
|
||||
url: 'https://clintgwinter.com/uses',
|
||||
twitter: '@ClintWinter2',
|
||||
emoji: '🤓⛺',
|
||||
emoji: '⛺',
|
||||
country: '🇺🇸',
|
||||
computer: 'windows',
|
||||
phone: 'android',
|
||||
|
|
@ -7135,15 +7362,22 @@ module.exports = [
|
|||
},
|
||||
{
|
||||
name: 'Federico Vitale',
|
||||
description:
|
||||
'20yo, Self Taught FullStack Developer, Full Time. Bikes lover, Tech (obviously) enthusiast.',
|
||||
description: 'Software Engineer based in Rome',
|
||||
url: 'https://fedevitale.dev/uses',
|
||||
twitter: '@fedevitaledev',
|
||||
emoji: '✌️',
|
||||
country: '🇮🇹',
|
||||
phone: 'iphone',
|
||||
computer: 'apple',
|
||||
tags: ['Developer', 'JavaScript', 'Go', 'Rust', 'Java', 'Full Stack'],
|
||||
tags: [
|
||||
'Developer',
|
||||
'JavaScript',
|
||||
'Go',
|
||||
'Rust',
|
||||
'TypeScript',
|
||||
'React',
|
||||
'Swift',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Vishwasa Navada K',
|
||||
|
|
@ -7656,7 +7890,8 @@ module.exports = [
|
|||
},
|
||||
{
|
||||
name: 'Sunny',
|
||||
description: 'Programmer, designer, musician, photographer and video editor.',
|
||||
description:
|
||||
'Programmer, designer, musician, photographer and video editor.',
|
||||
url: 'https://sny.sh/#uses',
|
||||
emoji: '☀️',
|
||||
country: '🇩🇪',
|
||||
|
|
@ -8353,6 +8588,17 @@ module.exports = [
|
|||
'GraphQL',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Dmytro Litvinov',
|
||||
description: 'Full Stack Python developer from 🇺🇦',
|
||||
url: 'https://dmytrolitvinov.com/uses/',
|
||||
twitter: '@DmytroLitvinov',
|
||||
emoji: '🪵',
|
||||
country: '🇺🇦',
|
||||
computer: 'apple',
|
||||
phone: 'iphone',
|
||||
tags: ['Developer', 'Web Developer', 'Full Stack', 'Python', 'Django'],
|
||||
},
|
||||
{
|
||||
name: 'Braden Watkins',
|
||||
description: 'Student, Full Stack Developer, Lover of all things analog',
|
||||
|
|
@ -8608,6 +8854,35 @@ module.exports = [
|
|||
'CSS',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Adil Haddaoui',
|
||||
description: 'Full stack Developer',
|
||||
url: 'https://adilhaddaoui.com/uses',
|
||||
twitter: '@ADiLHADDAOUI',
|
||||
emoji: '👨💻',
|
||||
country: '🇲🇦',
|
||||
computer: 'apple',
|
||||
phone: 'iphone',
|
||||
tags: [
|
||||
'Full Stack',
|
||||
'Developer',
|
||||
'Javascript',
|
||||
'TypeScript',
|
||||
'React',
|
||||
'Next.js',
|
||||
'JAMStack',
|
||||
'Tech Lead',
|
||||
'Node.js',
|
||||
'Frontend',
|
||||
'MongoDB',
|
||||
'GraphQL',
|
||||
'CSS',
|
||||
'HTML',
|
||||
'Gatsby',
|
||||
'SQL',
|
||||
'MERN Stack',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Jorge Ruvalcaba',
|
||||
description:
|
||||
|
|
@ -10441,12 +10716,13 @@ module.exports = [
|
|||
emoji: '🙃',
|
||||
country: '🇬🇧',
|
||||
computer: 'windows',
|
||||
phone: 'android',
|
||||
phone: 'iphone',
|
||||
tags: [
|
||||
'Developer',
|
||||
'YouTuber',
|
||||
'JavaScript',
|
||||
'Svelte',
|
||||
'SvelteKit',
|
||||
'Sloths',
|
||||
'Blogger',
|
||||
'Speaker',
|
||||
|
|
@ -10553,7 +10829,7 @@ module.exports = [
|
|||
'Developer Advocate with a knack for public speaking & making videos',
|
||||
url: 'https://fred.dev/uses',
|
||||
twitter: '@fharper',
|
||||
emoji: '✌🤦♂️',
|
||||
emoji: '✌',
|
||||
country: '🇨🇦',
|
||||
computer: 'apple',
|
||||
phone: 'iphone',
|
||||
|
|
@ -11875,7 +12151,7 @@ module.exports = [
|
|||
name: 'Thomas Large',
|
||||
description: 'My name is Tom! I write code',
|
||||
url: 'https://tomlarge.dev/uses',
|
||||
emoji: ' 👨💻',
|
||||
emoji: '👨💻',
|
||||
country: '🏴',
|
||||
computer: 'apple',
|
||||
phone: 'iphone',
|
||||
|
|
@ -13490,6 +13766,17 @@ module.exports = [
|
|||
'Photographer',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Sean Boult',
|
||||
description: 'Full stack developer who likes ReactJS',
|
||||
url: 'https://boult.me/uses',
|
||||
twitter: '@Hacksore',
|
||||
emoji: '🫠',
|
||||
country: '🇺🇸',
|
||||
computer: 'apple',
|
||||
phone: 'iphone',
|
||||
tags: ['Full Stack', 'React', 'Typescript', 'Node.js', 'Hacking'],
|
||||
},
|
||||
{
|
||||
name: 'Kevin Woblick',
|
||||
description: 'I turn Pizza into Code and Photos',
|
||||
|
|
@ -13984,7 +14271,7 @@ module.exports = [
|
|||
'Javascript lover, FullStack enthusiast, React Learner (current), Pet lover',
|
||||
url: 'https://gist.github.com/lakshmipriyamukundan/ddd224306ce962f4f159f1065f0f0c67',
|
||||
twitter: '@lak_mee',
|
||||
emoji: ':😺 ',
|
||||
emoji: '😺',
|
||||
country: '🇮🇳',
|
||||
computer: 'linux',
|
||||
phone: 'android',
|
||||
|
|
@ -14119,7 +14406,7 @@ module.exports = [
|
|||
description: 'Developer, writer, creator. Solutions Architect @ Vercel.',
|
||||
url: 'https://leerob.io/uses',
|
||||
twitter: '@leeerob',
|
||||
emoji: '🏼🌴',
|
||||
emoji: '🌴',
|
||||
country: '🇺🇸',
|
||||
computer: 'apple',
|
||||
phone: 'iphone',
|
||||
|
|
|
|||
21
src/entry.client.tsx
Normal file
21
src/entry.client.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import { RemixBrowser } from '@remix-run/react';
|
||||
import { startTransition, StrictMode } from 'react';
|
||||
import { hydrateRoot } from 'react-dom/client';
|
||||
const hydrate = () => {
|
||||
startTransition(() => {
|
||||
hydrateRoot(
|
||||
document,
|
||||
<StrictMode>
|
||||
<RemixBrowser />
|
||||
</StrictMode>
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
if (window.requestIdleCallback) {
|
||||
window.requestIdleCallback(hydrate);
|
||||
} else {
|
||||
// Safari doesn't support requestIdleCallback
|
||||
// https://caniuse.com/requestidlecallback
|
||||
window.setTimeout(hydrate, 1);
|
||||
}
|
||||
81
src/entry.server.tsx
Normal file
81
src/entry.server.tsx
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
import type { EntryContext } from '@remix-run/node';
|
||||
import { RemixServer } from '@remix-run/react';
|
||||
import { renderToReadableStream } from 'react-dom/server';
|
||||
|
||||
const ABORT_DELAY = 5000;
|
||||
|
||||
export async function streamToText(stream: ReadableStream<Uint8Array>): Promise<string> {
|
||||
let result = '';
|
||||
const reader = stream.pipeThrough(new TextDecoderStream()).getReader();
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const { done, value } = await reader.read();
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
|
||||
result += value;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
type CachedResponse = {
|
||||
html: string;
|
||||
date: Date;
|
||||
}
|
||||
const cache = new Map<string, CachedResponse>();
|
||||
|
||||
export default async function handleRequest(
|
||||
request: Request,
|
||||
responseStatusCode: number,
|
||||
responseHeaders: Headers,
|
||||
remixContext: EntryContext
|
||||
) {
|
||||
// check if we have a cached response in memory
|
||||
const cachedResponse = cache.get(request.url);
|
||||
if (cachedResponse) {
|
||||
// console.log('Serving from cache', request.url);
|
||||
// if we have a cached response, check if it's less than 5 seconds old
|
||||
const now = new Date();
|
||||
const diff = now.getTime() - cachedResponse.date.getTime();
|
||||
if (true || diff < 5000) {
|
||||
// if it's less than 5 seconds old, return the cached response
|
||||
responseHeaders.set('Content-Type', 'text/html');
|
||||
return new Response(cachedResponse.html, {
|
||||
headers: responseHeaders,
|
||||
status: responseStatusCode,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let didError = false;
|
||||
const chunks: Uint8Array[] = [];
|
||||
|
||||
const body = await renderToReadableStream(
|
||||
<RemixServer context={remixContext} url={request.url} />,
|
||||
{
|
||||
onError: (error: unknown) => {
|
||||
didError = true;
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// tee the stream so we can cache it and send it to the client
|
||||
const [toReponse, toCache] = body.tee();
|
||||
|
||||
streamToText(toCache).then(html => {
|
||||
console.log('Caching', request.url);
|
||||
cache.set(request.url, {
|
||||
html: html.replace('Rendered Fresh', `Rendered from cache ${new Date().toISOString()}`),
|
||||
date: new Date(),
|
||||
});
|
||||
});
|
||||
|
||||
const headers = new Headers(responseHeaders);
|
||||
headers.set("Content-Type", "text/html");
|
||||
const response = new Response(toReponse, {
|
||||
headers,
|
||||
status: didError ? 500 : responseStatusCode,
|
||||
});
|
||||
return response;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 708 KiB After Width: | Height: | Size: 708 KiB |
|
|
@ -1,62 +0,0 @@
|
|||
import React, { useContext } from 'react';
|
||||
import { useStaticQuery, graphql } from 'gatsby';
|
||||
import styled from 'styled-components';
|
||||
import FilterContext from '../context/FilterContext';
|
||||
|
||||
import Layout from '../components/layout';
|
||||
import Person from '../components/Person';
|
||||
import Topics from '../components/Topics';
|
||||
import BackToTop from '../components/BackToTop';
|
||||
|
||||
function IndexPage() {
|
||||
const { currentTag } = useContext(FilterContext);
|
||||
const { allPerson } = useStaticQuery(graphql`
|
||||
query People {
|
||||
allPerson {
|
||||
nodes {
|
||||
computer
|
||||
country
|
||||
description
|
||||
emoji
|
||||
id
|
||||
name
|
||||
phone
|
||||
tags
|
||||
twitter
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
const people = allPerson.nodes.filter(
|
||||
person =>
|
||||
currentTag === 'all' ||
|
||||
person.tags.includes(currentTag) ||
|
||||
currentTag === person.country ||
|
||||
currentTag === person.computer ||
|
||||
currentTag === person.phone
|
||||
);
|
||||
return (
|
||||
<Layout>
|
||||
<Topics />
|
||||
<People>
|
||||
{people.map(person => (
|
||||
<Person key={person.name} person={person} currentTag={currentTag} />
|
||||
))}
|
||||
</People>
|
||||
<BackToTop />
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
export default IndexPage;
|
||||
|
||||
// Component Styles
|
||||
const People = styled.div`
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
|
||||
grid-gap: 5rem;
|
||||
@media all and (max-width: 400px) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
`;
|
||||
64
src/root.tsx
Normal file
64
src/root.tsx
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
import type { LinksFunction, MetaFunction } from '@remix-run/node';
|
||||
import {
|
||||
Links,
|
||||
LiveReload,
|
||||
Meta,
|
||||
Outlet,
|
||||
Scripts
|
||||
} from '@remix-run/react';
|
||||
import Layout from './components/layout';
|
||||
import styles from './styles.css';
|
||||
import { countries, devices, tags } from './util/stats';
|
||||
import twitterCard from './images/twitter-card.png';
|
||||
|
||||
export const links: LinksFunction = () => [
|
||||
{ rel: 'stylesheet', href: styles },
|
||||
];
|
||||
|
||||
export function loader() {
|
||||
return {
|
||||
tags: tags(),
|
||||
countries: countries(),
|
||||
devices: devices(),
|
||||
}
|
||||
}
|
||||
|
||||
const metaData = {
|
||||
description: `A list of /uses pages detailing developer setups.`,
|
||||
siteUrl: 'https://uses.tech',
|
||||
author: `@wesbos`,
|
||||
title: '/uses',
|
||||
}
|
||||
|
||||
export const meta: MetaFunction = () => ({
|
||||
charset: 'utf-8',
|
||||
title: '/uses',
|
||||
viewport: 'width=device-width,initial-scale=1',
|
||||
});
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<html lang="en">
|
||||
<head>
|
||||
<Meta />
|
||||
<link rel="icon" href="https://fav.farm/🖥" />
|
||||
<meta name="description" content={metaData.description} />
|
||||
<link rel="canonical" href={metaData.siteUrl} />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:creator" content="@wesbos" />
|
||||
<meta name="twitter:title" content={metaData.title} />
|
||||
<meta name="twitter:description" content={metaData.description} />
|
||||
<meta name="twitter:image" content={`https://uses.tech${twitterCard}`} />
|
||||
<Links />
|
||||
</head>
|
||||
<body>
|
||||
<Layout>
|
||||
<Outlet />
|
||||
{/* <ScrollRestoration /> */}
|
||||
<Scripts />
|
||||
<LiveReload />
|
||||
</Layout>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
27
src/routes/index.tsx
Normal file
27
src/routes/index.tsx
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import { useLoaderData, useParams } from '@remix-run/react';
|
||||
import { json, LoaderArgs } from '@remix-run/server-runtime';
|
||||
import React, { useContext } from 'react';
|
||||
import Topics from '../components/Topics';
|
||||
import BackToTop from '../components/BackToTop';
|
||||
import Person from '../components/Person';
|
||||
import { getPeople } from 'src/util/stats';
|
||||
|
||||
export async function loader({ params }: LoaderArgs) {
|
||||
const people = getPeople(params.tag);
|
||||
return {people};
|
||||
}
|
||||
|
||||
export default function Index() {
|
||||
const { people } = useLoaderData();
|
||||
return (
|
||||
<>
|
||||
<Topics />
|
||||
<div className="People">
|
||||
{people.map(person => (
|
||||
<Person key={person.name} person={person} />
|
||||
))}
|
||||
</div>
|
||||
<BackToTop />
|
||||
</>
|
||||
);
|
||||
}
|
||||
1
src/routes/like/$tag.tsx
Normal file
1
src/routes/like/$tag.tsx
Normal file
|
|
@ -0,0 +1 @@
|
|||
export { default, loader } from '../index';
|
||||
290
src/styles.css
Normal file
290
src/styles.css
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
/* Fonts */
|
||||
@font-face {
|
||||
font-family: 'Fira Mono';
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
src: url('./fonts/fira_mono-regular-webfont.woff2') format('woff2'),
|
||||
url('./fonts/fira_mono-regular-webfont.woff') format('woff');
|
||||
font-display: swap;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Fira Mono';
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
src: url('./fonts/fira_mono-regular_italic-webfont.woff2') format('woff2'), url('../src/fonts/fira_mono-regular_italic-webfont.woff') format('woff');
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
*, *:before, *:after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
/* Global Styles */
|
||||
:root {
|
||||
--purple: #b066ff;
|
||||
--blue: #203447;
|
||||
--lightblue: #1f4662;
|
||||
--blue2: #1C2F40;
|
||||
--yellow: #ffc600;
|
||||
--pink: #EB4471;
|
||||
--vape: #d7d7d7;
|
||||
background: var(--blue);
|
||||
color: var(--vape);
|
||||
font-family: 'Fira Mono', monospace;
|
||||
font-weight: 100;
|
||||
font-size: 10px;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
font-size: 2rem;
|
||||
overflow-y: scroll;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--yellow);
|
||||
text-decoration-color: var(--pink);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
code {
|
||||
background: var(--lightblue);
|
||||
}
|
||||
|
||||
::selection {
|
||||
background: var(--yellow);
|
||||
color: var(--blue);
|
||||
}
|
||||
|
||||
body::-webkit-scrollbar {
|
||||
width: 12px;
|
||||
}
|
||||
|
||||
html {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: var(--yellow) var(--blue);
|
||||
}
|
||||
|
||||
body::-webkit-scrollbar-track {
|
||||
background: var(--blue);
|
||||
}
|
||||
|
||||
body::-webkit-scrollbar-thumb {
|
||||
background-color: var(--yellow);
|
||||
border-radius: 6px;
|
||||
border: 3px solid var(--blue);
|
||||
}
|
||||
|
||||
|
||||
.PersonWrapper {
|
||||
border: 1px solid var(--vape);
|
||||
border-radius: 5.34334px;
|
||||
box-shadow: 10px -10px 0 var(--blue2);
|
||||
display: grid;
|
||||
grid-template-rows: 1fr auto auto;
|
||||
}
|
||||
|
||||
.PersonInner {
|
||||
padding: 2rem;
|
||||
|
||||
& h3 {
|
||||
margin: 0;
|
||||
|
||||
& a:visited {
|
||||
color: var(--purple);
|
||||
}
|
||||
}
|
||||
|
||||
& header {
|
||||
display: grid;
|
||||
grid-template-rows: auto auto;
|
||||
grid-template-columns: auto 1fr;
|
||||
grid-gap: 0 1rem;
|
||||
|
||||
@media all and (max-width: 400px) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
& img {
|
||||
grid-row: 1 / -1;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
& .displayLink {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
text-decoration: none;
|
||||
color: var(--vape);
|
||||
letter-spacing: 1px;
|
||||
font-size: 1.2rem;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
&:hover,
|
||||
&:visited {
|
||||
color: var(--pink);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.PersonDeets {
|
||||
display: flex;
|
||||
border-top: 1px solid var(--vape);
|
||||
|
||||
>* {
|
||||
flex: 1;
|
||||
border-left: 1px solid var(--vape);
|
||||
text-align: center;
|
||||
padding: 1rem;
|
||||
display: grid;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
grid-template-columns: auto auto;
|
||||
|
||||
&:first-child {
|
||||
border-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
& a {
|
||||
color: var(--vape);
|
||||
}
|
||||
|
||||
& .country {
|
||||
font-size: 3rem;
|
||||
padding-top: 2rem;
|
||||
}
|
||||
|
||||
& .phone {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@media all and (max-width: 400px) {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
|
||||
>*:nth-child(1),
|
||||
>*:nth-child(2) {
|
||||
/* lol */
|
||||
border-bottom: 1px solid var(--vape);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.TwitterHandle {
|
||||
font-size: 1.24323423426928098420394802rem;
|
||||
& .at {
|
||||
color: var(--yellow);
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.Tags {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.Tag {
|
||||
background: var(--pink);
|
||||
margin: 2px;
|
||||
border-radius: 3px;
|
||||
font-size: 1.7rem;
|
||||
text-decoration: none;
|
||||
&.small {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
padding: 5px;
|
||||
color: hsla(0, 100%, 100%, 0.8);
|
||||
transition: background-color 0.2s;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
align-items: center;
|
||||
|
||||
& input {
|
||||
display: none;
|
||||
}
|
||||
&.currentTag {
|
||||
background: var(--yellow);
|
||||
color: hsla(0, 100%, 0%, 0.8);
|
||||
}
|
||||
}
|
||||
|
||||
.TagEmoji {
|
||||
transform: scale(1.45);
|
||||
}
|
||||
|
||||
.TagCount {
|
||||
background: var(--blue);
|
||||
font-size: 1rem;
|
||||
color: white;
|
||||
padding: 2px;
|
||||
border-radius: 2px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.BackToTopLink {
|
||||
position: fixed;
|
||||
bottom: 1%;
|
||||
right: 1%;
|
||||
color: white;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
cursor: pointer;
|
||||
border-radius: 3px;
|
||||
padding: 1rem;
|
||||
transition: opacity 0.2s;
|
||||
opacity: 0;
|
||||
text-decoration: none;
|
||||
|
||||
&.Show {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 500px) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.HeaderWrapper {
|
||||
text-align: center;
|
||||
|
||||
& h1 {
|
||||
font-size: 6rem;
|
||||
}
|
||||
}
|
||||
|
||||
.Main {
|
||||
display: grid;
|
||||
grid-gap: 3rem;
|
||||
max-width: 1900px;
|
||||
padding: 0 3rem;
|
||||
margin: 5rem auto;
|
||||
}
|
||||
|
||||
.People {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
|
||||
grid-gap: 5rem;
|
||||
|
||||
@media all and (max-width: 400px) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
const { name } = require('country-emoji');
|
||||
const people = require('../data.js');
|
||||
import { name } from 'country-emoji';
|
||||
import people from '../data.js';
|
||||
type Person = typeof people[0];
|
||||
|
||||
function merge(prop) {
|
||||
return function (acc, obj) {
|
||||
function merge(prop: string) {
|
||||
return function (acc: any, obj: Record<any, any>) {
|
||||
// Remove duplicated values.
|
||||
const values = [...new Set(obj[prop])];
|
||||
return [...values, ...acc];
|
||||
|
|
@ -14,24 +15,24 @@ function countInstances(acc, tag) {
|
|||
return acc;
|
||||
}
|
||||
|
||||
function normalizeTag(tag) {
|
||||
export function normalizeTag(tag) {
|
||||
return (
|
||||
tag
|
||||
// Common mispellings currently seen in the data
|
||||
// Do we want to go this far?
|
||||
.replace(/frontend/i, 'Front End')
|
||||
.replace(/TailwindCSS/i, 'Tailwind CSS')
|
||||
.replace(/backend/i, 'Back End')
|
||||
.replace(/fullstack/i, 'Full Stack')
|
||||
.replace(/a11y/i, 'Accessibility')
|
||||
.replace(/next.?js/i, 'Next')
|
||||
.replace(/react.?js/i, 'React')
|
||||
|
||||
// Or is lowercase enough?
|
||||
.toLowerCase()
|
||||
);
|
||||
}
|
||||
|
||||
function countries() {
|
||||
export function countries() {
|
||||
const data = people
|
||||
.map((person) => ({
|
||||
name: name(person.country),
|
||||
|
|
@ -52,17 +53,17 @@ function countries() {
|
|||
|
||||
const sorted = Object.entries(data)
|
||||
.map(([, country]) => country)
|
||||
.sort((a, b) => b.count - a.count);
|
||||
.sort((a, b) => b.count - a.count)
|
||||
.filter(Boolean);
|
||||
|
||||
return sorted;
|
||||
}
|
||||
|
||||
function tags() {
|
||||
export function tags() {
|
||||
const allTags = people.reduce(merge('tags'), []);
|
||||
const counts = allTags.reduce(countInstances, {});
|
||||
// sort and filter for any tags that only have 1
|
||||
const tags = Object.entries(counts)
|
||||
.sort(([, countA], [, countB]) => countB - countA)
|
||||
// Only show the tag if this topic has 3 or more people in it
|
||||
.filter(([, count]) => count >= 3)
|
||||
.map(([name, count]) => ({ name, count }));
|
||||
|
|
@ -83,23 +84,60 @@ function tags() {
|
|||
delete lowercaseTagMap[normalizedName];
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
}, [])
|
||||
// Sort by name first
|
||||
.sort((a, b) => b.name.toLowerCase() > a.name.toLowerCase())
|
||||
// Sort by count
|
||||
.sort((a, b) => b.count - a.count);
|
||||
return [{ name: 'all', count: people.length }, ...normalizedTags];
|
||||
}
|
||||
|
||||
function devices() {
|
||||
export function devices() {
|
||||
|
||||
const all = [
|
||||
...people.map((person) => person.computer),
|
||||
...people.map((person) => person.phone),
|
||||
];
|
||||
].filter(Boolean);
|
||||
|
||||
return Object.entries(all.reduce(countInstances, {}))
|
||||
.map(([device, count]) => ({ name: device, count }))
|
||||
.sort((a, b) => b.count - a.count);
|
||||
.sort((a, b) => b.count - a.count)
|
||||
.map((device) => {
|
||||
return device;
|
||||
})
|
||||
}
|
||||
|
||||
exports.normalizeTag = normalizeTag;
|
||||
exports.countries = countries;
|
||||
exports.tags = tags;
|
||||
exports.devices = devices;
|
||||
function unique(arr: string[]) {
|
||||
return Array.from(new Set(arr));
|
||||
}
|
||||
|
||||
const normalizedTagMap = tags().reduce((acc, tag) => {
|
||||
const normalizedTag = normalizeTag(tag.name);
|
||||
acc[normalizedTag] = tag.name;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
export function getPeople(tag?: string) {
|
||||
return [...people]
|
||||
.sort(() => Math.random() - 0.5)
|
||||
.map((person) => {
|
||||
const normalizedPerson = {
|
||||
...person,
|
||||
// Clean out people that added basically the same tags twice
|
||||
tags: unique(
|
||||
person.tags.map((tag) => normalizedTagMap[normalizeTag(tag)] || tag)
|
||||
),
|
||||
};
|
||||
return {
|
||||
...normalizedPerson,
|
||||
id: `person-${normalizedPerson.name}`,
|
||||
};
|
||||
})
|
||||
.filter((person) => {
|
||||
if (!tag) {
|
||||
return true;
|
||||
}
|
||||
return person.tags.includes(tag) || person.country === tag || person.phone === tag || person.computer === tag;
|
||||
})
|
||||
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
/* Fonts */
|
||||
@font-face {
|
||||
font-family: 'Fira Mono';
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
src: url('../src/fonts/fira_mono-regular-webfont.woff2') format('woff2'),
|
||||
url('../src/fonts/fira_mono-regular-webfont.woff') format('woff');
|
||||
font-display: swap;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Fira Mono';
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
src: url('../src/fonts/fira_mono-regular_italic-webfont.woff2') format('woff2'), url('../src/fonts/fira_mono-regular_italic-webfont.woff') format('woff');
|
||||
font-display: swap;
|
||||
}
|
||||
19
tsconfig.json
Normal file
19
tsconfig.json
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"include": ["remix.env.d.ts", "./**/*", "**/*.ts", "**/*.tsx"],
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"target": "esnext",
|
||||
"baseUrl": ".",
|
||||
"allowJs": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "react-jsx",
|
||||
"noEmit": true,
|
||||
"resolveJsonModule": true
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue