Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Final #33

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/components/pop-up-message.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export default {

html: `
<div class="pop-up-message hidden hidden-animation" id="pop-up-message">Текст уведомления</div>
`,

showMessage(messageText: string) {
const messageElement = document.getElementById('pop-up-message') as HTMLElement;
messageElement.textContent = messageText;
messageElement.classList.remove('hidden');
setTimeout(() => messageElement.classList.remove('hidden-animation'), 100);
setTimeout(() => {
messageElement.classList.add('hidden-animation');
setTimeout (()=> messageElement.classList.add('hidden'), 300);
}, 2000);
},
};
20 changes: 18 additions & 2 deletions src/components/search/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import debounce from '../debounce';
export default {
html: `
<div class="search search-grid">
<input type="text" placeholder="Здесь будет поиск" class="search-input" id="search-input">
<input type="text" placeholder="Поиск" class="search-input" id="search-input">
<ul class="search-results hidden" id="search-results">
<ul class="search-results-cities" id="search-results-cities"></ul>
<ul class="search-results-places" id="search-results-places"></ul>
Expand Down Expand Up @@ -74,6 +74,14 @@ export default {
const listItem = target.closest('LI');
if (listItem) {
Search.cityId = Number(listItem.querySelector('city')!.textContent);
inputSearch.removeEventListener('input', () => {
searchResults.classList.add('hidden');
const query = inputSearch.value.trim();
if (query) {
searchResults.classList.remove('hidden');
}
debouncedSearch(query);
});
router.goto('/home');
}
}
Expand All @@ -84,6 +92,14 @@ export default {
const listItem = target.closest('LI');
if (listItem) {
const itemId = listItem.querySelector('a')!.href.split('/').pop();
inputSearch.removeEventListener('input', () => {
searchResults.classList.add('hidden');
const query = inputSearch.value.trim();
if (query) {
searchResults.classList.remove('hidden');
}
debouncedSearch(query);
});
router.goto(`/places/${itemId}`);
}
}
Expand All @@ -97,7 +113,7 @@ export default {
const debouncedSearch = debounce(search, 300);

const searchResults = document.getElementById('search-results') as HTMLElement;
inputSearch.addEventListener('input', (event) => {
inputSearch.addEventListener('input', () => {
searchResults.classList.add('hidden');
const query = inputSearch.value.trim();
if (query) {
Expand Down
21 changes: 16 additions & 5 deletions src/pages/create-trip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import User from '../utils/user';
import logoImage from '../static/logo trip.svg';
import footer from '../components/footer';
import backButton from '../static/back button white.svg';
import popUpMessage from '../components/pop-up-message';

export default {
/**
Expand All @@ -15,6 +16,7 @@ export default {
*/
html:
`
${popUpMessage.html}
<img src="${logoImage}" alt="Логотип" class="logo-image" id="home-logo">
<main>
<div class="create-trip-block">
Expand All @@ -30,9 +32,6 @@ export default {
<input class="border" type="date" id="startDate" name="startDate">
<label class="create-trip-text">Дата конца</label>
<input class="border" type="date" id="endDate" name="endDate">
<label class="create-trip-text checkbox-button">
<input type="checkbox" id="private-trip" name="private-trip"> Приватная поездка
</label>
<button class="create-trip-button">Создать поездку</button>
</form>
</div>
Expand Down Expand Up @@ -65,14 +64,26 @@ export default {
const formDescription = (document.getElementById('description') as HTMLInputElement);
const formStartDate = (document.getElementById('startDate') as HTMLInputElement);
const formEndDate = (document.getElementById('endDate') as HTMLInputElement);
const formPrivateTrip = (document.getElementById('private-trip') as HTMLInputElement);
const createTripForm = document.getElementById('create-trip-form') as HTMLElement;
const errorMessage = document.getElementById('error-message') as HTMLElement;

createTripForm.addEventListener('submit', async (event) => {
event.preventDefault();
try {
const res = await Api.postCreateTrip(Number(User.id), formName.value, 1, formDescription.value, formStartDate.value, formEndDate.value, formPrivateTrip.checked);
if (formStartDate.value === '' || formEndDate.value === '' || formName.value === '' || formDescription.value === '') {
popUpMessage.showMessage('Заполните поля');
return;
}
if (formStartDate.value > formEndDate.value) {
popUpMessage.showMessage('Некорректная дата');
return;
}

const tripsRes = await Api.postCreateTrip(Number(User.id), formName.value, 1, formDescription.value, formStartDate.value, formEndDate.value, false);
if (!tripsRes.ok) {
popUpMessage.showMessage('Ошибка создания поездки');
return;
}
await router.goto('/mytrips');
} catch (e) {
errorMessage.textContent = 'Ошибка создания поездки';
Expand Down
34 changes: 23 additions & 11 deletions src/pages/edit-trip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import User from '../utils/user';
import logoImage from '../static/logo trip.svg';
import footer from '../components/footer';
import backButton from '../static/back button white.svg';
import popUpMessage from '../components/pop-up-message';

export default {
/**
Expand All @@ -15,6 +16,7 @@ export default {
*/
html:
`
${popUpMessage.html}
<img src="${logoImage}" alt="Логотип" class="logo-image" id="home-logo">
<main>
<div class="create-trip-block">
Expand All @@ -30,9 +32,6 @@ export default {
<input class="border" type="date" id="startDate" name="startDate">
<label class="create-trip-text">Дата конца</label>
<input class="border" type="date" id="endDate" name="endDate">
<label class="create-trip-text checkbox-button">
<input type="checkbox" id="private-trip" name="private-trip"> Приватная поездка
</label>
<button class="create-trip-button">Изменить поездку</button>
</form>
</div>
Expand Down Expand Up @@ -65,23 +64,36 @@ export default {
const resTrip = await Api.getTrip(itemId);

const formName = (document.getElementById('name') as HTMLInputElement);
formName.value = resTrip.data.name;
formName.value = resTrip.data.trip.name;
const formDescription = (document.getElementById('description') as HTMLInputElement);
formDescription.value = resTrip.data.description;
formDescription.value = resTrip.data.trip.description;
const formStartDate = (document.getElementById('startDate') as HTMLInputElement);
formStartDate.value = resTrip.data.startDate;
let tempDate = resTrip.data.trip.startDate.split('.');
formStartDate.value = `${tempDate[2]}-${tempDate[1]}-${tempDate[0]}`;
const formEndDate = (document.getElementById('endDate') as HTMLInputElement);
formEndDate.value = resTrip.data.endDate;
const formPrivateTrip = (document.getElementById('private-trip') as HTMLInputElement);
formPrivateTrip.checked = resTrip.data.private;
tempDate = resTrip.data.trip.endDate.split('.');
formEndDate.value = `${tempDate[2]}-${tempDate[1]}-${tempDate[0]}`;
const createTripForm = document.getElementById('create-trip-form') as HTMLElement;
const errorMessage = document.getElementById('error-message') as HTMLElement;

createTripForm.addEventListener('submit', async (event) => {
event.preventDefault();
try {
const res = await Api.putTrip(itemId, Number(User.id), formName.value, 1, formDescription.value, formStartDate.value, formEndDate.value, formPrivateTrip.checked);
await router.goto(`/trips/${itemId}`);
if (formStartDate.value === '' || formEndDate.value === '' || formName.value === '' || formDescription.value === '') {
popUpMessage.showMessage('Заполните поля');
return;
}
if (formStartDate.value > formEndDate.value) {
popUpMessage.showMessage('Некорректная дата');
return;
}

const tripsRes = await Api.putTrip(itemId, Number(User.id), formName.value, 1, formDescription.value, formStartDate.value, formEndDate.value, false);
if (!tripsRes.ok) {
popUpMessage.showMessage('Ошибка редактирования поездки');
return;
}
await router.goto('/mytrips');
} catch (e) {
errorMessage.textContent = 'Ошибка создания поездки';
errorMessage.classList.add('visible');
Expand Down
31 changes: 29 additions & 2 deletions src/pages/homePage/attractions-load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,35 @@ export default async function attractionsLoad(placeGallery: HTMLButtonElement, r
// Загрузка достопримечательностей
const attractionsResponse = await Api.getAttractions(Search.limit, Search.offset, Search.cityId, Search.categoryId, Search.filterId);
const attractions = attractionsResponse.data;
const galleryElement = document.getElementById('gallery') as HTMLElement;
galleryElement.innerHTML = galleryTemplate({ attractions });

// Логика построчного разбиения на три колонки
let columnPlaces1 = [];
let columnPlaces2 = [];
let columnPlaces3 = [];

for (let i = 0; i < attractions.length - 1; i++) {
switch (i % 3) {
case 0:
columnPlaces1.push(attractions[i]);
break;
case 1:
columnPlaces2.push(attractions[i]);
break;
case 2:
columnPlaces3.push(attractions[i]);
break;
}
}

const column1 = document.getElementById('place-column-1') as HTMLElement;
const column2 = document.getElementById('place-column-2') as HTMLElement;
const column3 = document.getElementById('place-column-3') as HTMLElement;
let finalResultAttractions = columnPlaces1;
column1.innerHTML = galleryTemplate({ finalResultAttractions });
finalResultAttractions = columnPlaces2;
column2.innerHTML = galleryTemplate({ finalResultAttractions });
finalResultAttractions = columnPlaces3;
column3.innerHTML = galleryTemplate({ finalResultAttractions });

placeGallery.addEventListener('click', (event) => {
const target = event.target as HTMLElement;
Expand Down
7 changes: 7 additions & 0 deletions src/pages/homePage/categoryButtonMount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ import attractionsLoad from './attractions-load';

export default async function categoryButtonMount(categoryId: number, placeGallery: HTMLButtonElement, router: Router, button: HTMLButtonElement) {
Search.categoryId === categoryId ? Search.categoryId = -1 : Search.categoryId = categoryId;

if (Search.categoryActiveElement && Search.categoryActiveElement !== button) {
Search.categoryActiveElement.classList.remove('active');
}

button.classList.toggle('active');
Search.categoryActiveElement = button;

await attractionsLoad(placeGallery, router);
};
2 changes: 1 addition & 1 deletion src/pages/homePage/home.hbs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{#each attractions}}
{{#each finalResultAttractions}}
<li class="gallery-item">
<a href="/places/{{id}}"></a>
<img src="{{imagePath}}" alt="{{name}}">
Expand Down
13 changes: 12 additions & 1 deletion src/pages/homePage/home.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ export default {
<div class="filter" id="rating-filter">по рейтингу</div>
<div class="filter" id="popularity-filter">по популярности</div>
</div>
<ul class="gallery" id="gallery"></ul>
<div class="gallery" id="gallery">
<ul class="place-column" id="place-column-1"></ul>
<ul class="place-column" id="place-column-2"></ul>
<ul class="place-column" id="place-column-3"></ul>
</div>
</div>
</main>
${footer.html}
Expand Down Expand Up @@ -111,24 +115,31 @@ export default {
switch (Search.categoryId) {
case 1:
categoryOneButton.classList.add('active');
Search.categoryActiveElement = categoryOneButton;
break;
case 2:
categoryTwoButton.classList.add('active');
Search.categoryActiveElement = categoryTwoButton;
break;
case 3:
categoryThreeButton.classList.add('active');
Search.categoryActiveElement = categoryThreeButton;
break;
case 4:
categoryFourButton.classList.add('active');
Search.categoryActiveElement = categoryFourButton;
break;
case 5:
categoryFiveButton.classList.add('active');
Search.categoryActiveElement = categoryFiveButton;
break;
case 6:
categorySixButton.classList.add('active');
Search.categoryActiveElement = categorySixButton;
break;
case 7:
categorySevenButton.classList.add('active');
Search.categoryActiveElement = categorySevenButton;
break;
}

Expand Down
7 changes: 5 additions & 2 deletions src/pages/placePage/place.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import reviewsLoad from './reviews-load';
import User from '../../utils/user';
import galleryCategoriesTemplate from './categories.hbs';
import Search from '../../utils/search-memory';
import popUpMessage from '../../components/pop-up-message';

export default {
html:
`${header.html}
${popUpMessage.html}
<main>
<div class="place-block">
<div class="place-image grid-place-image">
Expand Down Expand Up @@ -140,15 +142,16 @@ export default {

reviewFormButton.addEventListener('click', async () => {
if (!reviewFormText.value) {
popUpMessage.showMessage('Пустой отзыв - не круто. Напишите о своих впечатлениях!');
return;
}
if (Number(formRatingInput.value) < 1 || Number(formRatingInput.value) > 5) {
alert('Некорректный рейтинг');
popUpMessage.showMessage('Введите оценку от 1 до 5');
return;
}
const res = await Api.postReview(Number(User.id), itemId, reviewFormText.value, Number(formRatingInput.value));
if (!res.ok) {
console.log('Ошибка отправки отзыва');
popUpMessage.showMessage('Вы уже оставили отзыв!');
}
await reviewsLoad(itemId, router);
});
Expand Down
24 changes: 8 additions & 16 deletions src/pages/profilePage/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {emailRegex} from '../../components/validation';
import footer from '../../components/footer';
import backButton from '../../static/back button white.svg';
import userMount from '../../components/user-mount';
import closeButton from '../../static/close icon.svg';
import popUpMessage from '../../components/pop-up-message';

export default {
/**
Expand All @@ -22,9 +22,7 @@ export default {
*/
html: `
<img src="${logoImage}" alt="Логотип" class="logo-image" id="logo-image">
<div class="error-window-message hidden hidden-animation" id="error-window-message">Ошибка загрузки аватарки
<img src="${closeButton}" class="error-close-button" id="error-close-button">
</div>
${popUpMessage.html}
<main>
<div class="background-profile">
<div class="user-block">
Expand Down Expand Up @@ -114,14 +112,6 @@ export default {
avatar.src = resProfile.data.avatarPath ?
`/avatars/${resProfile.data.avatarPath}` : defaultAvatar;

const errorWindowMessage = document.getElementById('error-window-message') as HTMLElement;
const errorCloseButton = document.getElementById('error-close-button') as HTMLButtonElement;

errorCloseButton.addEventListener('click', () => {
errorWindowMessage.classList.add('hidden-animation');
setTimeout(() => errorWindowMessage.classList.add('hidden'), 300);
});

avatar.addEventListener('click', () => {
const avatarInputElement = document.createElement('input') as HTMLInputElement;
avatarInputElement.type = 'file';
Expand All @@ -135,14 +125,16 @@ export default {
reader.addEventListener('load', async () => {
const basedAvatar = String(reader.result ? reader.result : '');
if (!basedAvatar) {
errorWindowMessage.classList.remove('hidden');
setTimeout(() => errorWindowMessage.classList.remove('hidden-animation'), 100);
popUpMessage.showMessage('Ошибка загрузки аватарки');
return;
}
const res = await Api.putAvatar(User.id, basedAvatar);
if (res.status === 413) {
popUpMessage.showMessage('Слишком большое фото');
return;
}
if (!res.ok) {
errorWindowMessage.classList.remove('hidden');
setTimeout(() => errorWindowMessage.classList.remove('hidden-animation'), 100);
popUpMessage.showMessage('Ошибка загрузки аватарки');
return;
}
await this.mount(router);
Expand Down
8 changes: 4 additions & 4 deletions src/pages/profilePage/profileAchievements.hbs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{{#each achievements}}
<li class="gallery-item-achievements">
<img src="{{../defaultAchievementIcon}}" alt="Значок достижения" class="gallery-item-achievements-img">
<div class="gallery-item-achievements-name">Название</div>
<div class="gallery-item-achievements-progressbar">54/10</div>
<li class="gallery-item-achievements" id="achievement-{{id}}">
<img src="/achievements/{{ iconPath }}" alt="Значок достижения" class="gallery-item-achievements-img">
<div class="gallery-item-achievements-name">{{ name }}</div>
<!-- <div class="gallery-item-achievements-progressbar"></div>-->
</li>
{{/each}}
Loading