Skip to content

Commit

Permalink
Добавление sa-router-spa из предыдущего задания
Browse files Browse the repository at this point in the history
  • Loading branch information
SergeyAkkuratov committed May 30, 2024
1 parent 079e5d0 commit 7839deb
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 50 deletions.
31 changes: 31 additions & 0 deletions .husky/_/husky.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/bin/sh
if [ -z "$husky_skip_init" ]; then
debug () {
if [ "$HUSKY_DEBUG" = "1" ]; then
echo "husky (debug) - $1"
fi
}

readonly hook_name="$(basename "$0")"
debug "starting $hook_name..."

if [ "$HUSKY" = "0" ]; then
debug "HUSKY env variable is set to 0, skipping hook"
exit 0
fi

if [ -f ~/.huskyrc ]; then
debug "sourcing ~/.huskyrc"
. ~/.huskyrc
fi

export readonly husky_skip_init=1
sh -e "$0" "$@"
exitCode="$?"

if [ $exitCode != 0 ]; then
echo "husky - $hook_name hook exited with code $exitCode (error)"
fi

exit $exitCode
fi
29 changes: 19 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
"test": "jest --passWithNoTests --coverage",
"lint": "prettier --check . && eslint .",
"lint:fix": "prettier --write . && eslint . --fix",
"build": "webpack --mode=development",
"dev": "webpack serve --open --mode=development"
"build": "webpack --mode=production",
"start": "webpack serve --open --mode=development"
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -42,5 +42,8 @@
"lint-staged": {
"*.js": "eslint --fix",
"*.{js,css,md,yml}": "prettier --write"
},
"dependencies": {
"sa-router-spa": "^1.0.1"
}
}
4 changes: 2 additions & 2 deletions src/localStorage.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
export function getHistoryList() {
const historyString = localStorage.getItem("history");
if (historyString !== null && historyString.length > 0) {
return historyString.split(" ");
return historyString.split(";");
}
return [];
}

export function setHistorySet(list) {
localStorage.setItem("history", list.join(" "));
localStorage.setItem("history", list.join(";"));
}
42 changes: 42 additions & 0 deletions src/pageTempaltes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import oopsImg from "./assets/oops.png";

export const mainTemplate = `
<div>
<div class="info-block">
<form id="weatherForm" class="form-block">
<input id="userInput" class="form-input" placeholder="Type city and press enter" required autofocus>
</form>
<div id="weather">
<img id="map"
src="${oopsImg}"
alt="Couldn't get image of map"></img>
</div>
<div id="info">
<span>Wait for city name</span>
</div>
</div>
<div id="history" class="history-block">
<span>History:</span>
</div>
</div>
<div class="bottom">
<a href="/about">About</a>
</div>
`;

export const aboutTemplate = `
<div align="center">
<h3>Приложение &quot;Прогноз погоды&quot;</h3>
<p>
Выполнение домашнего задания для лекции &quot;Современный инструментарий при разработке клиентских (и не только
приложений)&quot;
</p>
<h2>О проекте</h2>
<p>Приложение &quot;Прогноз погоды&quot; это Web приложение разработанное на языке JavaScript. Оно предназначено для
просмотра текущей погоды в конкретном городе.</p>
<p>Приложение показывает текущую температуру в градусах цельсия и общее состоянии погоды, обозначенное иконкой.</p>
<p>Так же приложение отображает компактную картинку с картой выбранного города.</p>
<a href="/">Main<a>
</div>
`;
11 changes: 11 additions & 0 deletions src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,14 @@
color: red;
cursor: pointer;
}

.bottom {
clear: both;
position: relative;
}

.bottom a {
position: absolute;
top: 50%;
left: 50%;
}
83 changes: 48 additions & 35 deletions src/weatherApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,34 @@
/* eslint-disable no-alert */
/* eslint no-param-reassign: ["error", { "props": false }] */
// eslint-disable-next-line import/no-self-import
import Router from "sa-router-spa";
import oopsImg from "./assets/oops.png";
import { getInfoByIP, getMap, getWeather } from "./externalRequests";
import { getHistoryList, setHistorySet } from "./localStorage";
import { mainTemplate, aboutTemplate } from "./pageTempaltes";

export default async function weatherApp(element) {
export default async function weatherApp(rootElement) {
const maxHistorylines = 10;
const historyList = [];
const router = new Router("history");

function showWeather(data) {
const weatherInfo = element.querySelector("#info");
const weatherInfo = rootElement.querySelector("#info");
weatherInfo.innerHTML = `<h1>${data.name}</h1>`;
weatherInfo.innerHTML += `<h2>Temperature: ${data.main.temp} C</h2>`;
weatherInfo.innerHTML += `<img src="http://openweathermap.org/img/wn/${data.weather[0].icon}@2x.png" alt="Couldn't load icon of weather">`;
}

function showMap(imgSource) {
if (imgSource) {
element.querySelector("#map").src = URL.createObjectURL(imgSource);
rootElement.querySelector("#map").src = URL.createObjectURL(imgSource);
} else {
element.querySelector("#map").src = oopsImg;
rootElement.querySelector("#map").src = oopsImg;
}
}

async function updateWeather(cityName, updateHistoryFlag) {
async function updateWeather(cityNameParam, updateHistoryFlag) {
const cityName = decodeURIComponent(cityNameParam);
const weather = await getWeather(cityName);
if (weather.cod === 200) {
if (updateHistoryFlag) await updateHistoryBlock(cityName);
Expand All @@ -38,8 +42,7 @@ export default async function weatherApp(element) {
}

function onclickHistoryLine(event) {
updateWeather(event.target.innerHTML, false);
updateHistoryBlock(event.target.innerHTML);
router.navigate(`/weather/${event.target.innerHTML}`);
}

function createHistoryParagraph(cityName) {
Expand All @@ -51,7 +54,7 @@ export default async function weatherApp(element) {
}

async function updateHistoryBlock(cityName) {
const historyElement = element.querySelector("#history");
const historyElement = rootElement.querySelector("#history");
if (historyList.includes(cityName)) {
historyList.splice(historyList.indexOf(cityName), 1);
historyList.unshift(cityName);
Expand All @@ -76,41 +79,51 @@ export default async function weatherApp(element) {

const ipInfo = await getInfoByIP();

element.innerHTML = `
<div class="info-block">
<form id="weatherForm" class="form-block">
<input id="userInput" class="form-input" placeholder="Type city and press enter" required autofocus>
</form>
<div id="weather">
<img id="map"
src="${oopsImg}"
alt="Couldn't get image of map"></img>
</div>
<div id="info">
<span>Wait for city name</span>
</div>
</div>
<div id="history" class="history-block">
<span>History:</span>
</div>`;
const localHistoryList = getHistoryList();
if (localHistoryList.length > 0) {
localHistoryList
.reverse()
.forEach((cityName) => updateHistoryBlock(cityName));
}
if (ipInfo.region) updateWeather(ipInfo.region);
rootElement.innerHTML = mainTemplate;

element
rootElement
.querySelector("#weatherForm")
.addEventListener("submit", async (event) => {
.addEventListener("submit", (event) => {
event.preventDefault();

// читаем значение из формы
const formElement = event.target;
const inputEl = formElement.querySelector("#userInput");
const cityName = inputEl.value;
inputEl.value = "";
updateWeather(cityName, true);
router.navigate(`/weather/${cityName}`);
});

rootElement.querySelectorAll("a").forEach((link) =>
link.addEventListener("click", (event) => {
event.preventDefault();
router.navigate(link.href);
}),
);

router.addRoute({
path: /^\/weather\/(?<cityName>.+)$/,
onEnter: async (params) => {
updateWeather(params.cityName, true);
},
});

router.addRoute({
path: "/about",
onEnter: () => {
rootElement.innerHTML = aboutTemplate;
},
onLeave: () => {
rootElement.innerHTML = mainTemplate;
},
});

const localHistoryList = getHistoryList();
if (localHistoryList.length > 0) {
localHistoryList
.reverse()
.forEach((cityName) => updateHistoryBlock(cityName));
}

if (ipInfo.city) router.navigate(`/weather/${ipInfo.city}`);
}
11 changes: 10 additions & 1 deletion webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,19 @@ module.exports = {
filename: "[name].js",
chunkFilename: "[name].chunk.js",
path: path.resolve(__dirname, "dist"),
publicPath: "/",
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/template.html",
favicon: "./src/assets/favicon.png",
filename: "./index.html",
}),
new HtmlWebpackPlugin({
template: "./src/template.html",
favicon: "./src/assets/favicon.png",
filename: "404.html",
}),
],
module: {
rules: [
Expand All @@ -28,7 +34,10 @@ module.exports = {
],
},
devServer: {
static: "./dist",
compress: true,
port: 9000,
watchFiles: ["dist/index.html"],
historyApiFallback: true,
},
optimization: {
runtimeChunk: "single",
Expand Down

0 comments on commit 7839deb

Please sign in to comment.