Skip to content

Commit

Permalink
UI app addition
Browse files Browse the repository at this point in the history
  • Loading branch information
sadanandpai committed Jul 14, 2024
1 parent 7d4045f commit 550caa9
Show file tree
Hide file tree
Showing 26 changed files with 1,061 additions and 68 deletions.
9 changes: 5 additions & 4 deletions .env.local
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
VITE_PATH=frontend-mini-challenges
VITE_HOST_URL=http://localhost:6010/
VITE_JS_APP_URL=http://localhost:6011/
VITE_REACT_APP_URL=http://localhost:6012/
VITE_VUE_APP_URL=http://localhost:6013/
VITE_NG_APP_URL=http://localhost:6014/
VITE_CSS_APP_URL=http://localhost:6011/
VITE_JS_APP_URL=http://localhost:6012/
VITE_REACT_APP_URL=http://localhost:6013/
VITE_VUE_APP_URL=http://localhost:6014/
VITE_NG_APP_URL=http://localhost:6015/
24 changes: 24 additions & 0 deletions apps/css/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
19 changes: 19 additions & 0 deletions apps/css/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "@fmc/css",
"private": true,
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"build-baseless": "tsc && vite build --base=/css/",
"preview": "vite preview"
},
"devDependencies": {
"typescript": "^5.2.2",
"vite": "^5.3.1"
},
"dependencies": {
"@fmc/data": "*"
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="../../logo.svg" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<script src="../../helpers/header.js" type="module"></script>
</head>
Expand Down
File renamed without changes.
55 changes: 55 additions & 0 deletions apps/css/src/helpers/dom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
export const create1DFragment = (m, { type = 'div', ...properties }) => {
const fragment = document.createDocumentFragment();

for (let i = 0; i < m; i++) {
const element = createElement(type, { ...properties, dataset: { x: i } });
fragment.appendChild(element);
}

return fragment;
};

export const create2DFragment = (m, n, { type = 'div', ...properties }) => {
const fragment = document.createDocumentFragment();

for (let i = 0; i < m; i++) {
const row = createElement('div');
for (let j = 0; j < n; j++) {
const element = createElement(type, { ...properties, dataset: { x: i, y: j } });
row.appendChild(element);
idx++;
}
fragment.appendChild(row);
}

return fragment;
};

export const createGridFragment = (m, n, { type = 'div', ...properties }) => {
const fragment = document.createDocumentFragment();
let idx = 0;
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
const element = createElement(type, { ...properties, dataset: { x: i, y: j, idx } });
fragment.appendChild(element);
idx++;
}
}

return fragment;
};

export const createElement = (type = 'div', properties) => {
const element = document.createElement(type);
Object.entries(properties).forEach(([key, value]) => {
if (typeof value === 'object') {
Object.entries(value).forEach(([subKey, subValue]) => {
element[key][subKey] = subValue;
});
return;
}

element[key] = value;
});
return element;
};
34 changes: 34 additions & 0 deletions apps/css/src/helpers/header.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import '@fmc/shared-styles/theme';
import '@fmc/shared-styles/base';
import '@fmc/shared-styles/components';
import '@fmc/shared-styles/utilities';
import './navbar.ts';
import { cssChallenges } from '@fmc/data/content';

const metaUTF = document.createElement('meta');
metaUTF.setAttribute('charset', 'UTF-8');

const metaName = document.createElement('meta');
metaName.setAttribute('name', 'viewport');
metaName.setAttribute('content', 'width=device-width, initial-scale=1.0');

const metaHTTP = document.createElement('meta');
metaHTTP.setAttribute('http-equiv', 'X-UA-Compatible');
metaHTTP.setAttribute('content', 'IE=edge');

const favIcon = document.createElement('link');
favIcon.setAttribute('rel', 'icon');
favIcon.setAttribute('type', 'image/svg+xml');
favIcon.setAttribute(
'href',
'https://github.com/sadanandpai/frontend-mini-challenges/raw/main/shared/assets/core/logo.png'
);

// Add all tags to the head
const headTags = [metaUTF, metaName, metaHTTP, favIcon];
headTags.forEach((tag) => document.head.prepend(tag));

// Add title
const challengeLink = window.location.pathname.split('/challenges/')[1].slice(0, -1);
const challenge = cssChallenges.get(challengeLink);
document.title = challenge.title;
46 changes: 46 additions & 0 deletions apps/css/src/helpers/navbar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { cssChallenges } from '@fmc/data/content';
import { logo } from '@fmc/assets/images';
import '@fmc/shared-styles/navbar';

const { VITE_PATH, VITE_HOST_URL, DEV } = import.meta.env;
const backURL = DEV ? `${VITE_HOST_URL}${VITE_PATH}/#/css/` : `/${VITE_PATH}/#/css/`;
const homeURL = DEV ? `${VITE_HOST_URL}${VITE_PATH}/` : `/${VITE_PATH}/`;

const challengeLink = window.location.pathname.split('/challenges/')[1].slice(0, -1);
const challenge = cssChallenges.get(challengeLink)!;

const navbar = document.createElement('nav');
navbar.classList.add('challenge-navbar');
navbar.innerHTML = `
<div class="left">
<a href=${backURL} class="back">
&lt;
</a>
<a class="logo" href=${homeURL}>
<img src=${logo} alt="logo" />
</a>
</div>
<h1>${challenge.title}</h1>
<div class="right">
${
challenge?.youtube
? `
<a slot="icon" href=${challenge.youtube} target="blank" class="youtube">
<img src="https://cdn-icons-png.flaticon.com/256/1384/1384060.png" alt="youtube solution" />
</a>
`
: ''
}
<a href="https://github.com/sadanandpai/frontend-mini-challenges/" target="blank">
<img
src="https://cdn-icons-png.flaticon.com/512/25/25231.png"
alt="github repo"
class="github"
/>
</a>
</div>
`;

document.body.prepend(navbar);
1 change: 1 addition & 0 deletions apps/css/src/vite-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="vite/client" />
8 changes: 8 additions & 0 deletions apps/css/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"allowJs": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"]
},
"include": ["src"]
}
21 changes: 21 additions & 0 deletions apps/css/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { defineConfig } from 'vite';
import { cssChallenges } from '../../shared/data/content/index';

const challengesPath = [...cssChallenges.values()].map(
(challenge) => `./src/challenges/${challenge.link}/index.html`
);

// https://vitejs.dev/config/
export default defineConfig({
build: {
rollupOptions: {
input: ['./src/helpers/navbar.ts', ...challengesPath],
},
},
server: {
port: 6011,
strictPort: true,
},
base: '/frontend-mini-challenges/css/',
logLevel: 'silent',
});
44 changes: 25 additions & 19 deletions apps/host/src/components/modules/home/hero/hero.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
import { coverTransparent, jsImg, reactImg, vueImg, angularImg } from '@fmc/assets/images';
import { coverTransparent, cssImg, jsImg, reactImg, vueImg, angularImg } from '@fmc/assets/images';
import styles from './hero.module.scss';
import { HashLink } from 'react-router-hash-link';

const allImg = [
{
title: 'css',
imgSrc: cssImg,
},
{
title: 'JS',
imgSrc: jsImg,
},
{
title: 'react',
imgSrc: reactImg,
},
{
title: 'vue',
imgSrc: vueImg,
},
{
title: 'angular',
imgSrc: angularImg,
},
];

function Hero() {
const allImg = [
{
title: 'JS',
imgSrc: jsImg,
},
{
title: 'react',
imgSrc: reactImg,
},
{
title: 'vue',
imgSrc: vueImg,
},
{
title: 'angular',
imgSrc: angularImg,
},
];
return (
<main className={styles.hero}>
<div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { generateLeaderboardData } from '@/helpers/leaderboard';
import { jsImg, reactImg, vueImg, angularImg, cssImg } from '@fmc/assets/images';
import classes from './leaderboard.module.scss';
import { jsImg, reactImg, vueImg, angularImg } from '@fmc/assets/images';

function cn(...classnames: string[]) {
return classnames.join(' ');
}

const techStackImgs = new Map([
['css', cssImg],
['js', jsImg],
['react', reactImg],
['vue', vueImg],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ table.leaderboardTable {

.contributionTableCell {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-columns: repeat(6, 1fr);

.techStackDiv {
font-size: 14px;
Expand Down
2 changes: 2 additions & 0 deletions apps/host/src/helpers/leaderboard.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
contributors,
angularChallenges,
cssChallenges,
jsChallenges,
reactChallenges,
vueChallenges,
Expand Down Expand Up @@ -45,6 +46,7 @@ export function updateContributions(
export const generateLeaderboardData = (): Map<string, LeaderboardEntry> => {
const developerContributions: Map<string, DeveloperContributions> = new Map();
const techChallengesMap = new Map([
['css', cssChallenges],
['js', jsChallenges],
['react', reactChallenges],
['vue', vueChallenges],
Expand Down
32 changes: 28 additions & 4 deletions apps/host/src/pages/challenges.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,41 @@ import { useNavigate, useParams } from 'react-router-dom';
import Navbar from '@/components/common/navbar/navbar';
import ScrollBtn from '@/components/common/scroll-to-top/scroll-btn';
import ChallengeGrid from '@/components/modules/challenges/challenge-grid/challenge-grid';
import { angularImg, jsImg, reactImg, vueImg } from '@fmc/assets/images';
import { angularChallenges, jsChallenges, reactChallenges, vueChallenges } from '@fmc/data/content';
import { angularImg, jsImg, reactImg, cssImg, vueImg } from '@fmc/assets/images';
import {
angularChallenges,
jsChallenges,
reactChallenges,
cssChallenges,
vueChallenges,
} from '@fmc/data/content';

const { VITE_PATH, VITE_JS_APP_URL, VITE_REACT_APP_URL, VITE_VUE_APP_URL, VITE_NG_APP_URL, DEV } =
import.meta.env;
const {
VITE_PATH,
VITE_CSS_APP_URL,
VITE_JS_APP_URL,
VITE_REACT_APP_URL,
VITE_VUE_APP_URL,
VITE_NG_APP_URL,
DEV,
} = import.meta.env;

const cssLinkPrefix = DEV ? `${VITE_CSS_APP_URL}${VITE_PATH}` : `/${VITE_PATH}`;
const jsLinkPrefix = DEV ? `${VITE_JS_APP_URL}${VITE_PATH}` : `/${VITE_PATH}`;
const reactLinkPrefix = DEV ? `${VITE_REACT_APP_URL}${VITE_PATH}` : `/${VITE_PATH}`;
const vueLinkPrefix = DEV ? `${VITE_VUE_APP_URL}${VITE_PATH}` : `/${VITE_PATH}`;
const angularPrefix = DEV ? `${VITE_NG_APP_URL}${VITE_PATH}` : `/${VITE_PATH}`;

const techMap = new Map([
[
'css',
{
title: 'CSS',
challenges: cssChallenges,
link: cssLinkPrefix + '/css/src/challenges/',
imgSrc: cssImg,
},
],
[
'javascript',
{
Expand Down
2 changes: 1 addition & 1 deletion apps/javascript/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default defineConfig({
},
},
server: {
port: 6011,
port: 6012,
strictPort: true,
},
base: '/frontend-mini-challenges/javascript/',
Expand Down
2 changes: 1 addition & 1 deletion apps/react/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default defineConfig({
},
},
server: {
port: 6012,
port: 6013,
strictPort: true,
},
base: '/frontend-mini-challenges/react/',
Expand Down
Loading

0 comments on commit 550caa9

Please sign in to comment.