Commit 1f6d26a0 authored by Nikita Stavitskiy's avatar Nikita Stavitskiy

Initial commit

parents
bin/
obj/
/packages/
riderModule.iml
/_ReSharper.Caches/
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RiderProjectSettingsUpdater">
<option name="vcsConfiguration" value="2" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoGeneratedRunConfigurationManager">
<projectFile profileName="IIS Express">WebApplication10/WebApplication10.csproj</projectFile>
<projectFile profileName="http">WebApplication10/WebApplication10.csproj</projectFile>
<projectFile profileName="https">WebApplication10/WebApplication10.csproj</projectFile>
</component>
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="98968c1b-50bf-419a-b85b-aea52b53c206" name="Changes" comment="">
<change afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
<change afterPath="$PROJECT_DIR$/WebApplication10.sln" afterDir="false" />
<change afterPath="$PROJECT_DIR$/WebApplication10/Program.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/WebApplication10/Properties/launchSettings.json" afterDir="false" />
<change afterPath="$PROJECT_DIR$/WebApplication10/WebApplication10.csproj" afterDir="false" />
<change afterPath="$PROJECT_DIR$/WebApplication10/appsettings.Development.json" afterDir="false" />
<change afterPath="$PROJECT_DIR$/WebApplication10/appsettings.json" afterDir="false" />
<change afterPath="$PROJECT_DIR$/global.json" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="DpaMonitoringSettings">
<option name="autoShow" value="false" />
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="CSS File" />
<option value="JavaScript File" />
<option value="HTML File" />
</list>
</option>
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="ProjectColorInfo"><![CDATA[{
"associatedIndex": 1
}]]></component>
<component name="ProjectId" id="2iMtmi9EnvunKrndbhNdkwocvRD" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true">
<ConfirmationsSetting value="1" id="Add" />
</component>
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
".NET Launch Settings Profile.WebApplication10: http.executor": "Run",
"DefaultHtmlFileTemplate": "HTML File",
"RunOnceActivity.ShowReadmeOnStart": "true",
"git-widget-placeholder": "master",
"list.type.of.created.stylesheet": "CSS",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"settings.editor.selected.configurable": "preferences.lookFeel",
"vue.rearranger.settings.migration": "true"
},
"keyToStringList": {
"rider.external.source.directories": [
"C:\\Users\\ASUS\\AppData\\Roaming\\JetBrains\\Rider2024.1\\resharper-host\\DecompilerCache",
"C:\\Users\\ASUS\\AppData\\Roaming\\JetBrains\\Rider2024.1\\resharper-host\\SourcesCache",
"C:\\Users\\ASUS\\AppData\\Local\\Symbols\\src"
]
}
}]]></component>
<component name="RunManager" selected=".NET Launch Settings Profile.WebApplication10: http">
<configuration name="WebApplication10: IIS Express" type="LaunchSettings" factoryName=".NET Launch Settings Profile">
<option name="LAUNCH_PROFILE_PROJECT_FILE_PATH" value="$PROJECT_DIR$/WebApplication10/WebApplication10.csproj" />
<option name="LAUNCH_PROFILE_TFM" value="net7.0" />
<option name="LAUNCH_PROFILE_NAME" value="IIS Express" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="USE_MONO" value="0" />
<option name="RUNTIME_ARGUMENTS" value="" />
<option name="GENERATE_APPLICATIONHOST_CONFIG" value="1" />
<option name="SHOW_IIS_EXPRESS_OUTPUT" value="0" />
<option name="SEND_DEBUG_REQUEST" value="1" />
<option name="ADDITIONAL_IIS_EXPRESS_ARGUMENTS" value="" />
<method v="2">
<option name="Build" />
</method>
</configuration>
<configuration name="WebApplication10: http" type="LaunchSettings" factoryName=".NET Launch Settings Profile">
<option name="LAUNCH_PROFILE_PROJECT_FILE_PATH" value="$PROJECT_DIR$/WebApplication10/WebApplication10.csproj" />
<option name="LAUNCH_PROFILE_TFM" value="net7.0" />
<option name="LAUNCH_PROFILE_NAME" value="http" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="USE_MONO" value="0" />
<option name="RUNTIME_ARGUMENTS" value="" />
<option name="GENERATE_APPLICATIONHOST_CONFIG" value="1" />
<option name="SHOW_IIS_EXPRESS_OUTPUT" value="0" />
<option name="SEND_DEBUG_REQUEST" value="1" />
<option name="ADDITIONAL_IIS_EXPRESS_ARGUMENTS" value="" />
<method v="2">
<option name="Build" />
</method>
</configuration>
<configuration name="WebApplication10: https" type="LaunchSettings" factoryName=".NET Launch Settings Profile">
<option name="LAUNCH_PROFILE_PROJECT_FILE_PATH" value="$PROJECT_DIR$/WebApplication10/WebApplication10.csproj" />
<option name="LAUNCH_PROFILE_TFM" value="net7.0" />
<option name="LAUNCH_PROFILE_NAME" value="https" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="USE_MONO" value="0" />
<option name="RUNTIME_ARGUMENTS" value="" />
<option name="GENERATE_APPLICATIONHOST_CONFIG" value="1" />
<option name="SHOW_IIS_EXPRESS_OUTPUT" value="0" />
<option name="SEND_DEBUG_REQUEST" value="1" />
<option name="ADDITIONAL_IIS_EXPRESS_ARGUMENTS" value="" />
<method v="2">
<option name="Build" />
</method>
</configuration>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="98968c1b-50bf-419a-b85b-aea52b53c206" name="Changes" comment="" />
<created>1719312434870</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1719312434870</updated>
<workItem from="1719312436011" duration="9020000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="UnityProjectConfiguration" hasMinimizedUI="false" />
<component name="VcsManagerConfiguration">
<option name="CLEAR_INITIAL_COMMIT_MESSAGE" value="true" />
</component>
</project>
\ No newline at end of file

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebApplication10", "WebApplication10\WebApplication10.csproj", "{A14A7EA1-420A-4B54-B83C-ACCAF6BAFE3A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A14A7EA1-420A-4B54-B83C-ACCAF6BAFE3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A14A7EA1-420A-4B54-B83C-ACCAF6BAFE3A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A14A7EA1-420A-4B54-B83C-ACCAF6BAFE3A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A14A7EA1-420A-4B54-B83C-ACCAF6BAFE3A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/modules.xml
/contentModel.xml
/.idea.HttpServer.iml
/projectSettingsUpdater.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
bin/
obj/
/packages/
riderModule.iml
/_ReSharper.Caches/
.idea
*.db
\ No newline at end of file
namespace WebApplication10;
public class Book
{
public int Id { get; set; }
public string Title { get; set; } = "";
public string Author { get; set; } = "";
}
\ No newline at end of file
namespace WebApplication10;
public class BookShelf
{
private int _nextIdx = 0;
private Dictionary<int, Book> _books { get; set; } = new();
public BookShelf()
{
Add(new Book { Id = 0, Title = "The Alchemist", Author = "Paulo Coelho" });
Add(new Book { Id = 1, Title = "The Little Prince", Author = "Antoine de Saint-Exupéry" });
Add(new Book { Id = 2, Title = "The Hobbit", Author = "J. R. R. Tolkien"});
Add(new Book { Id = 3, Title = "Doctor Zhivago", Author = "Boris Pasternak"});
Add(new Book { Id = 4, Title = "The Fellowship Of The Ring", Author = "J. R. R. Tolkien"});
Add(new Book { Id = 5, Title = "The Name Of The Wind", Author = "Patrick Rothfuss"});
Add(new Book { Id = 6, Title = "The Alchemist", Author = "Paulo Coelho" });
Add(new Book { Id = 7, Title = "The Little Prince", Author = "Antoine de Saint-Exupéry" });
Add(new Book { Id = 8, Title = "The Hobbit", Author = "J. R. R. Tolkien"});
Add(new Book { Id = 9, Title = "Doctor Zhivago", Author = "Boris Pasternak"});
Add(new Book { Id = 10, Title = "The Fellowship Of The Ring", Author = "J. R. R. Tolkien"});
Add(new Book { Id = 11, Title = "The Name Of The Wind", Author = "Patrick Rothfuss"});
}
public IEnumerable<Book> GetAll()
{
return _books.Values.ToList();
}
public Book Add(Book book)
{
book.Id = _nextIdx;
_nextIdx++;
_books[book.Id] = book;
return book;
}
public bool Update(Book book)
{
if (!_books.ContainsKey(book.Id))
return false;
_books[book.Id] = book;
return true;
}
public void Delete(int id)
{
_books.Remove(id);
}
}
\ No newline at end of file
using Microsoft.AspNetCore.Mvc;
namespace WebApplication10.Controllers;
[ApiController]
[Route("[controller]")]
public class BooksController: ControllerBase
{
private readonly BookShelf _bookShelf;
public BooksController(BookShelf bookShelf)
{
_bookShelf = bookShelf;
}
[HttpGet]
[Route("all")]
public IEnumerable<Book> GetAll()
{
return _bookShelf.GetAll();
}
[HttpPost]
[Route("add")]
public IActionResult Add([FromBody] Book book)
{
var newBook = _bookShelf.Add(book);
return new OkObjectResult(newBook);
}
[HttpPut]
[Route("update")]
public IActionResult Update([FromBody] Book book)
{
var res = _bookShelf.Update(book);
return res ? new OkResult() : new BadRequestResult();
}
[HttpDelete]
[Route("delete/{id}")]
public IActionResult Delete(int id)
{
_bookShelf.Delete(id);
return new OkResult();
}
}
\ No newline at end of file
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Mvc;
namespace WebApplication10.Controllers;
[ApiController]
[Route("[controller]")]
public class UserController: ControllerBase
{
private readonly List<User> _users;
public UserController(List<User> users)
{
_users = users;
}
[HttpPost]
[Route("login")]
public IActionResult Login(User user)
{
User? findUser = _users.FirstOrDefault(u => u.Username == user.Username && u.Password == user.Password);
// если пользователь не найден, отправляем статусный код 401
if(findUser is null)
return Unauthorized();
var claims = new List<Claim>
{
new (ClaimTypes.Name, findUser.Username),
new (ClaimTypes.Role, findUser.Role)
};
ClaimsIdentity claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity));
return Ok(new {user = findUser.Username});
}
}
\ No newline at end of file
using WebApplication10;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<BookShelf>();
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
\ No newline at end of file
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:33821",
"sslPort": 44358
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5171",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7059;http://localhost:5171",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
namespace WebApplication10;
public class User
{
public int Id { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Role { get; set; }
}
\ No newline at end of file
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.9"/>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0"/>
</ItemGroup>
<ItemGroup>
<Content Update="wwwroot\test.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\style.css">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\scripts\script.js">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\index.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BookShelf</title>
<link rel="stylesheet" href="style.css">
<script src="scripts/script.js"></script>
</head>
<body>
</body>
</html>
\ No newline at end of file
const BookLibrary = (function () {
// Получение списка книг и рендер
function getAllBooksAndRender() {
fetch('/books/all')
.then(response => response.json())
.then(data => {
const targetElement = document.getElementById('booksList');
// Очищаем содержимое элемента списка книг
targetElement.innerHTML = '';
data.forEach(book => {
renderBook(targetElement, book);
});
})
.catch(error => {
console.error('Error fetching books:', error);
});
}
// Рендер отдельной книги
function renderBook(targetElement, book) {
// Общий контейнер для книги
const bookContainer = document.createElement('div');
bookContainer.classList.add('book-item');
// Блок описания книги
const descriptionBlock = document.createElement('div');
descriptionBlock.classList.add('book-description');
descriptionBlock.innerHTML = `
<strong>Title:</strong> ${book.title}<br>
<strong>Author:</strong> ${book.author}<br>
<strong>ID:</strong> ${book.id}
`;
bookContainer.appendChild(descriptionBlock);
// Блок кнопок
const buttonsBlock = document.createElement('div');
buttonsBlock.classList.add('book-buttons');
// Редактировать
const editButton = document.createElement('button');
editButton.textContent = 'Edit';
editButton.classList.add('edit-button');
editButton.addEventListener('click', () => editBook(book));
buttonsBlock.appendChild(editButton);
// Удалить
const deleteButton = document.createElement('button');
deleteButton.textContent = 'Delete';
deleteButton.classList.add('delete-button');
deleteButton.addEventListener('click', () => deleteBook(book.id));
buttonsBlock.appendChild(deleteButton);
bookContainer.appendChild(buttonsBlock);
targetElement.appendChild(bookContainer);
}
function deleteBook(bookId) {
const apiUrl = `/books/delete/${bookId}`; // URL для удаления книги по ID
fetch(apiUrl, {
method: 'DELETE'
})
.then(response => {
if (response.ok) {
alert(`Book with ID ${bookId} deleted successfully`);
// Обновляем список книг
getAllBooksAndRender();
} else {
alert(`Failed to delete book with ID ${bookId}`);
}
})
.catch(error => {
console.error('Error deleting book:', error);
alert(`Error deleting book with ID ${bookId}`);
});
}
function editBook(book) {
// Заполняем форму данными текущей книги
document.getElementById('editTitle').value = book.title;
document.getElementById('editAuthor').value = book.author;
// Устанавливаем атрибут data-book-id на форму для хранения ID книги
document.getElementById('editBookForm').setAttribute('data-book-id', book.id);
// Открываем модальное окно
document.getElementById('editBookModal').style.display = 'block';
}
function closeBookEdit() {
document.getElementById('editBookModal').style.display = 'none';
}
function saveEditedBook() {
// Получаем данные из формы
const bookId = document.getElementById('editBookForm').getAttribute('data-book-id');
const editedTitle = document.getElementById('editTitle').value;
const editedAuthor = document.getElementById('editAuthor').value;
// Отправляем данные на сервер (здесь пример с fetch)
fetch(`/books/update`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
id: bookId,
title: editedTitle,
author: editedAuthor
})
})
.then(response => {
if (response.ok) {
alert(`Book with ID ${bookId} edited successfully`);
closeBookEdit(); // Закрываем модальное окно
getAllBooksAndRender(); // Обновляем список книг
} else {
alert(`Failed to edit book with ID ${bookId}`);
}
})
.catch(error => {
console.error('Error editing book:', error);
alert(`Error editing book with ID ${bookId}`);
});
}
// Публичные методы
return {
GetAllBooksAndRender: () => {
getAllBooksAndRender();
},
CloseBookEdit: () => {
closeBookEdit();
},
SaveEditedBook: () => {
saveEditedBook();
}
};
})();
\ No newline at end of file
body {
font-family: Arial, sans-serif;
line-height: 1.6;
margin: 20px;
}
h1 {
text-align: center;
}
.book-item {
display: flex;
justify-content: space-between;
align-items: center;
border: 1px solid #ccc;
padding: 10px;
margin-bottom: 10px;
}
.books-list {
display: flex;
flex-direction: column;
margin-top: 20px;
}
.book-description {
flex: 1;
}
.book-buttons {
display: flex;
gap: 10px;
}
.modalBook {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0,0,0,0.4);
padding-top: 60px;
}
.modal-content {
background-color: #fefefe;
margin: auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);
}
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BookShelf</title>
<link rel="stylesheet" href="style.css">
<script src="scripts/script.js"></script>
</head>
<body>
<h1>List of Books in the Shelf</h1>
<div class="books-list" id="booksList">
<!-- Сюда будет загружаться список книг -->
</div>
<div id="editBookModal" class="modalBook">
<div class="modal-content">
<span class="close" onclick="BookLibrary.CloseBookEdit()">&times;</span>
<h2>Edit Book</h2>
<form id="editBookForm">
<label for="editTitle">Title:</label><br>
<input type="text" id="editTitle" name="editTitle" required><br>
<label for="editAuthor">Author:</label><br>
<input type="text" id="editAuthor" name="editAuthor" required><br><br>
<input type="submit" value="Save">
</form>
</div>
</div>
<script>
function saveEditedBook(event) {
event.preventDefault(); // Предотвращаем отправку формы по умолчанию
BookLibrary.SaveEditedBook();
}
document.getElementById('editBookForm').addEventListener('submit', saveEditedBook);
BookLibrary.GetAllBooksAndRender();
</script>
</body>
</html>
\ No newline at end of file
{
"sdk": {
"version": "7.0.0",
"rollForward": "latestMinor",
"allowPrerelease": false
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment