Skip to content

Commit

Permalink
Create the app and it's working
Browse files Browse the repository at this point in the history
  • Loading branch information
abduvik committed Apr 26, 2022
1 parent d7bc29d commit b815e91
Show file tree
Hide file tree
Showing 17 changed files with 190 additions and 24 deletions.
10 changes: 10 additions & 0 deletions courses/.jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2016",
"jsx": "preserve",
"baseUrl": "./src",
"checkJs": true
},
"exclude": ["node_modules", "**/node_modules/*"]
}
17 changes: 16 additions & 1 deletion courses/frontend-architecture/src/app.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
import { CharactersDetailsContainer } from './containers/CharactersDetailsContainer/CharactersDetailsContainer';
import { CharactersListContainer } from './containers/CharactersListContainer/CharactersListContainer';
import { dependencies } from './dependencies';
import { create } from './utils/renderer';

export const App = (DI) => {
console.log(DI);
const router = DI.getDependency(dependencies.router);

router.setRoutePageRender('/', () => CharactersListContainer(DI));
router.setRoutePageRender('/character/.*', () =>
CharactersDetailsContainer(DI)
);
router.setNotFoundPage(() =>
create('div', { innerText: 'Page Not Found! Try another route :)' })
);

return router.renderFromRouter();
};
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { create } from '../../utils/renderer';

export const CharacterDetails = (name, link, imgUrl) => {
export const CharacterDetails = ({ name, link, imageUrl }) => {
return create('div', {}, [
create('div', {}, [
create('span', { innerText: 'Character Name:' }),
create('span', { innerText: name }),
]),
create('img', { src: imgUrl }),
create('div', {}, [create('img', { src: imageUrl })]),
create('a', { innerText: 'More details', href: link }),
]);
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { create } from '../../utils/renderer';

export const CharacterItem = (name) => {
return create('li', {}, [
create('span', { innerText: 'Name' }),
create('span', { innerText: 'Name: ' }),
create('span', { innerText: name }),
]);
};
2 changes: 1 addition & 1 deletion courses/frontend-architecture/src/config/env.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const EnvironmentConfigs = () => {
return {
endpoint: 'https://api.disneyapi.dev/characters',
endpoint: 'https://api.disneyapi.dev',
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { CharacterDetails } from '../../components/CharacterDetails/CharacterDetails';
import { dependencies } from '../../dependencies';
import { create, onMountedFactory } from '../../utils/renderer';

const onMounted = onMountedFactory();

export const CharactersDetailsContainer = (DI) => {
const charactersStore = DI.getDependency(dependencies.charactersStore);
const router = DI.getDependency(dependencies.router);
const currentRoute = router.getCurrentRoute();
const characterId = currentRoute.replace('/character/', '');

onMounted(() => charactersStore.fetchCharacter(characterId));

const character = charactersStore.characters[characterId];

console.log(character);

return character
? create('div', {}, [
create('a', { innerText: '<- back home', href: '/' }),
create('a', { href: `/character/${character._id}` }, [
CharacterDetails({
name: character.name,
url: character.url,
imageUrl: character.imageUrl,
}),
]),
])
: create('div');
};
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { CharacterItem } from '../../components/CharacterItem';
import { dependencies } from '../../dependencies';
import { create, onMountedFactory } from '../../utils/renderer';

const onMounted = onMountedFactory();

export const CharactersListContainer = (DI) => {
const charactersStore = DI.getDependency(dependencies.charactersStore);

onMounted(() => charactersStore.fetchCharacters());

const characters = Object.values(charactersStore.characters);

return create('div', {}, [
create('div', { innerText: 'List of Disney Characters' }),
create(
'ul',
{},
characters.map((character) =>
create('a', { href: `/character/${character._id}` }, [
CharacterItem(character.name),
])
)
),
]);
};
Empty file.
30 changes: 30 additions & 0 deletions courses/frontend-architecture/src/dependencies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { DependencyContainer } from './stores/dependencyContainer.store';
import { ApiAdapter } from './adapters/apiAdapter';
import { EnvironmentConfigs } from './config/env';
import { RouterStore } from './stores/router.store';
import { CharactersApiService } from './services/CharactersApi.service';
import { CharactersStore } from './stores/Characters.store';

const dependenciesContainer = new DependencyContainer();

const dependencies = {
env: Symbol('env'),
api: Symbol('api'),
router: Symbol('router'),
charactersService: Symbol('charactersService'),
charactersStore: Symbol('charactersStore'),
};

const env = EnvironmentConfigs();
const api = new ApiAdapter(env);
const router = new RouterStore();
const charactersService = new CharactersApiService(api);
const charactersStore = new CharactersStore(charactersService);

dependenciesContainer.add(dependencies.env, env);
dependenciesContainer.add(dependencies.api, api);
dependenciesContainer.add(dependencies.router, router);
dependenciesContainer.add(dependencies.charactersService, charactersService);
dependenciesContainer.add(dependencies.charactersStore, charactersStore);

export { dependencies, dependenciesContainer };
14 changes: 2 additions & 12 deletions courses/frontend-architecture/src/index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
import { ApiAdapter } from './adapters/apiAdapter';
import { EnvironmentConfigs } from './config/env';
import { App } from './app';
import { DependencyContainer } from './stores/dependencyContainer.store';

const dependenciesContainer = new DependencyContainer();

const env = EnvironmentConfigs();
const api = new ApiAdapter(env);

dependenciesContainer.add(env);
dependenciesContainer.add(api);
import { dependenciesContainer } from './dependencies';

const renderApp = () => {
// unmount the app
Expand All @@ -28,4 +18,4 @@ const renderApp = () => {
window.addEventListener('load', renderApp);

// The could be replaced with a logic to do a rerender
document.addEventListener('click', renderApp);
document.addEventListener('rerenderView', renderApp);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export class CharactersApiService {
constructor(api) {
this.api = api;
}

all() {
return this.api.get('/characters');
}

getCharacter(id) {
return this.api.get(`/characters/${id}`);
}
}
27 changes: 27 additions & 0 deletions courses/frontend-architecture/src/stores/Characters.store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { rerender } from '../utils/renderer';

export class CharactersStore {
constructor(charactersApiService) {
this.charactersApi = charactersApiService;
this.characters = {};
}

fetchCharacters() {
this.charactersApi.all().then((response) => {
response.data.forEach((character) => {
this.characters[character._id] = character;
});
rerender();
});
}

fetchCharacter(id) {
this.charactersApi.getCharacter(id).then((character) => {
this.characters = {
...this.characters,
[character._id]: character,
};
rerender();
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export class DependencyContainer {
this.container[key] = dependency;
}

get(key) {
getDependency(key) {
return this.container[key];
}
}
19 changes: 13 additions & 6 deletions courses/frontend-architecture/src/stores/router.store.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
export class RouterStore {
constructor() {
this.routeMaps = {};
this.routes = [];
this.NotFoundPageRenderer = () => document.createElement('div');
}

getRoute() {
getCurrentRoute() {
return window.location.pathname;
}

Expand All @@ -13,14 +13,21 @@ export class RouterStore {
}

setRoutePageRender(route, renderer) {
this.routeMaps[route] = renderer;
this.routes.push({
matcher: new RegExp(`^${route}$`),
renderer,
});
}

renderFromRouter() {
const currentRoute = this.getRoute();
const currentRoute = this.getCurrentRoute();

const renderer = this.routeMaps[currentRoute] || this.NotFoundPageRenderer;
const matchedRenderer = this.routes.find(({ matcher }) => {
return matcher.test(currentRoute);
});

return renderer();
return matchedRenderer
? matchedRenderer.renderer()
: this.NotFoundPageRenderer();
}
}
15 changes: 15 additions & 0 deletions courses/frontend-architecture/src/utils/renderer.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
export const onMountedFactory = () => {
let isCalled = false;
return (fun) => {
if (!isCalled) {
isCalled = true;
return fun();
}
};
};

export const create = (element, props = {}, children = []) => {
const elementEl = document.createElement(element);
Object.keys(props).forEach((propKey) => {
Expand All @@ -10,3 +20,8 @@ export const create = (element, props = {}, children = []) => {

return elementEl;
};

export const rerender = () => {
const event = new CustomEvent('rerenderView');
document.dispatchEvent(event);
};
2 changes: 2 additions & 0 deletions courses/frontend-architecture/webpack.dev.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
entry: './src/index.js',
devtool: 'eval-source-map',
mode: 'development',
devServer: {
static: {
Expand All @@ -23,6 +24,7 @@ module.exports = {
extensions: ['.js'],
},
output: {
publicPath: '/',
path: path.resolve(__dirname, 'dist'),
filename: 'app.[hash].js',
},
Expand Down

0 comments on commit b815e91

Please sign in to comment.