Wersja probna

powinno cos dzialac
This commit is contained in:
Witkopawel
2025-04-30 12:40:59 +02:00
parent 74b69f045d
commit 470ce72b6a
12 changed files with 332 additions and 141 deletions

View File

@@ -0,0 +1,89 @@
using Microsoft.AspNetCore.Mvc;
using System.Linq.Expressions;
using System.Reflection.Metadata;
using WebApp.Data;
using WebApp.Entities;
namespace WebApp.Controllers.Api
{
[ApiController]
[Route("api/events")]
public class EventsApiController : ControllerBase
{
private readonly ApplicationDbContext _context;
public EventsApiController(ApplicationDbContext context)
{
_context = context;
}
// GET: /api/events
[HttpGet]
public IActionResult GetAll()
{
var events = _context.Events.ToList();
return Ok(events);
}
// GET: /api/events/5
[HttpGet("{id}")]
public IActionResult GetById(int id)
{
var ev = _context.Events.Find(id);
if (ev == null)
return NotFound();
return Ok(ev);
}
// POST: /api/events
[HttpPost]
public IActionResult Create([FromBody] Event ev)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
ev.EventDate = DateTime.SpecifyKind(ev.EventDate, DateTimeKind.Utc);
_context.Events.Add(ev);
_context.SaveChanges();
return CreatedAtAction(nameof(GetById), new { id = ev.EventId }, ev);
}
// PUT: /api/events/5
[HttpPut("{id}")]
public IActionResult Update(int id, [FromBody] Event updated)
{
if (id != updated.EventId)
return BadRequest("ID w URL nie zgadza się z obiektem.");
var ev = _context.Events.Find(id);
if (ev == null)
return NotFound();
ev.Title = updated.Title;
ev.Description = updated.Description;
ev.Location = updated.Location;
ev.EventDate = updated.EventDate;
ev.OrganisationId = updated.OrganisationId;
_context.SaveChanges();
return NoContent();
}
// DELETE: /api/events/5
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
var ev = _context.Events.Find(id);
if (ev == null)
return NotFound();
_context.Events.Remove(ev);
_context.SaveChanges();
return NoContent();
}
}
}

View File

@@ -1,50 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using WebApp.Data;
using WebApp.Entities;
namespace WebApp.Controllers
{
public class EventsController : Controller
{
private readonly ApplicationDbContext _context;
public EventsController(ApplicationDbContext context)
{
_context = context;
}
public IActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Event ev)
{
if (ModelState.IsValid)
{
ev.EventDate = DateTime.SpecifyKind(ev.EventDate, DateTimeKind.Utc);
_context.Events.Add(ev);
await _context.SaveChangesAsync();
return RedirectToAction("Index", "Home");
}
return View(ev);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Delete(int id)
{
var ev = await _context.Events.FindAsync(id);
if (ev != null)
{
_context.Events.Remove(ev);
await _context.SaveChangesAsync();
}
return RedirectToAction("Index", "Home");
}
}
}

View File

@@ -30,6 +30,7 @@ else
} }
app.UseHttpsRedirection(); app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseStaticFiles(); app.UseStaticFiles();
app.UseRouting(); app.UseRouting();

View File

@@ -1,41 +0,0 @@
@model WebApp.Entities.Event
@{
ViewData["Title"] = "Create Event";
}
<h2>Create Event</h2>
<form asp-action="Create" method="post">
<div class="form-group">
<label asp-for="Title"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Location"></label>
<input asp-for="Location" class="form-control" />
<span asp-validation-for="Location" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Description"></label>
<textarea asp-for="Description" class="form-control"></textarea>
</div>
<div class="form-group">
<label asp-for="EventDate"></label>
<input asp-for="EventDate" type="datetime-local" class="form-control" />
<span asp-validation-for="EventDate" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="OrganisationId">OrganisationId (for debugging purposes)</label>
<input asp-for="OrganisationId" class="form-control" />
<span asp-validation-for="OrganisationId" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-primary">Save</button>
</form>
@section Scripts {
@{
await Html.RenderPartialAsync("_ValidationScriptsPartial");
}
}

View File

@@ -1,12 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace WebApp.Views.Events
{
public class CreateModel : PageModel
{
public void OnGet()
{
}
}
}

View File

@@ -1,24 +1,25 @@
document.addEventListener("DOMContentLoaded", () => { document.addEventListener("DOMContentLoaded", () => {
const deleteButtons = document.querySelectorAll(".delete-btn"); document.body.addEventListener("click", async (e) => {
const target = e.target as HTMLElement;
deleteButtons.forEach(button => { if (!target.matches(".delete-btn")) return;
button.addEventListener("click", async () => {
const id = (button as HTMLButtonElement).dataset.id;
if (!id) return;
const confirmed = confirm("Na pewno chcesz usunąć to wydarzenie?"); const id = target.getAttribute("data-id");
if (!confirmed) return; if (!id) return;
const response = await fetch(`/api/events/${id}`, { const confirmed = confirm("Na pewno chcesz usunąć to wydarzenie?");
method: "DELETE" if (!confirmed) return;
});
if (response.ok) { const response = await fetch(`/api/events/${id}`, {
const row = button.closest("tr");
if (row) row.remove(); method: "DELETE"
} else {
alert("Nie udało się usunąć wydarzenia.");
}
}); });
if (response.ok) {
const card = target.closest(".col");
if (card) card.remove();
} else {
alert("Nie udało się usunąć wydarzenia.");
}
}); });
}); });

41
WebApp/ts/eventList.ts Normal file
View File

@@ -0,0 +1,41 @@
document.addEventListener("DOMContentLoaded", async () => {
const container = document.getElementById("eventList");
if (!container) return;
try {
const res = await fetch("/api/events");
if (!res.ok) throw new Error("Błąd pobierania wydarzeń");
const events = await res.json();
if (events.length === 0) {
container.innerHTML = "<p class='text-muted'>Brak wydarzeń do wyświetlenia.</p>";
return;
}
for (const ev of events) {
const card = document.createElement("div");
card.className = "col";
card.innerHTML = `
<div class="card shadow-sm h-100">
<div class="card-body">
<h5 class="card-title">${ev.title}</h5>
<p class="card-text">
<strong>Miejsce:</strong> ${ev.location}<br/>
<strong>Data:</strong> ${new Date(ev.eventDate).toLocaleString()}<br/>
<strong>Organizacja ID:</strong> ${ev.organisationId}
</p>
<button class="btn btn-outline-danger delete-btn" data-id="${ev.eventId}">
🗑️ Usuń
</button>
</div>
</div>
`;
container.appendChild(card);
}
} catch (err) {
container.innerHTML = `<p class="text-danger">Błąd ładowania danych.</p>`;
console.error(err);
}
});

View File

@@ -0,0 +1,51 @@
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<title>Nowe wydarzenie</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="/css/style.css" />
</head>
<body class="bg-light">
<div class="container mt-5">
<h1 class="mb-4">Utwórz wydarzenie</h1>
<div class="form-group mb-2">
<label for="title">Tytuł</label>
<input id="title" class="form-control" />
</div>
<div class="form-group mb-2">
<label for="location">Lokalizacja</label>
<input id="location" class="form-control" />
</div>
<div class="form-group mb-2">
<label for="description">Opis</label>
<textarea id="description" class="form-control"></textarea>
</div>
<div class="form-group mb-2">
<label for="eventDate">Data</label>
<input id="eventDate" type="datetime-local" class="form-control" />
</div>
<div class="form-group mb-4">
<label for="organisationId">ID Organizacji</label>
<input id="organisationId" type="number" class="form-control" />
</div>
<div class="text-center">
<button class="button"><span>Zapisz</span><span>&#11166;</span></button>
</div>
</div>
<script type="module" src="/js/eventCreate.js"></script>
</body>
</html>

View File

@@ -0,0 +1,37 @@
.button {
border-radius: 4px;
background-color: #f4511e;
color: #FFFFFF;
text-align: center;
font-size: 28px;
padding: 20px 30px;
cursor: pointer;
position: relative;
transition: all 0.5s;
text-transform: uppercase;
border: none;
}
.button:hover {
background-color: rgb(189, 0, 0);
}
.button span:first-child {
padding-left: 10px;
transition: all 0.5s;
}
.button:hover span:first-child {
padding-left: 0px;
}
.button span:last-child {
opacity: 0;
transition: all 0.5s;
padding-left: 0px;
}
.button:hover span:last-child {
opacity: 1;
padding-left: 10px;
}

25
WebApp/wwwroot/index.html Normal file
View File

@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<title>Lista wydarzeń</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="/css/style.css" />
</head>
<body class="bg-light">
<div class="container mt-5">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="text-primary">📅 Wydarzenia</h1>
<a href="/create.html" class="btn btn-success">+ Dodaj nowe</a>
</div>
<div id="eventList" class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4">
</div>
</div>
<script type="module" src="/js/eventList.js"></script>
<script type="module" src="/js/eventDelete.js"></script>
</body>
</html>

View File

@@ -9,26 +9,26 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
}); });
}; };
document.addEventListener("DOMContentLoaded", () => { document.addEventListener("DOMContentLoaded", () => {
const deleteButtons = document.querySelectorAll(".delete-btn"); document.body.addEventListener("click", (e) => __awaiter(void 0, void 0, void 0, function* () {
deleteButtons.forEach(button => { const target = e.target;
button.addEventListener("click", () => __awaiter(void 0, void 0, void 0, function* () { if (!target.matches(".delete-btn"))
const id = button.dataset.id; return;
if (!id) const id = target.getAttribute("data-id");
return; if (!id)
const confirmed = confirm("Na pewno chcesz usunąć to wydarzenie?"); return;
if (!confirmed) const confirmed = confirm("Na pewno chcesz usunąć to wydarzenie?");
return; if (!confirmed)
const response = yield fetch(`/api/events/${id}`, { return;
method: "DELETE" const response = yield fetch(`/api/events/${id}`, {
}); method: "DELETE"
if (response.ok) { });
const row = button.closest("tr"); if (response.ok) {
if (row) const card = target.closest(".col");
row.remove(); if (card)
} card.remove();
else { }
alert("Nie udało się usunąć wydarzenia."); else {
} alert("Nie udało się usunąć wydarzenia.");
})); }
}); }));
}); });

View File

@@ -0,0 +1,49 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
document.addEventListener("DOMContentLoaded", () => __awaiter(void 0, void 0, void 0, function* () {
const container = document.getElementById("eventList");
if (!container)
return;
try {
const res = yield fetch("/api/events");
if (!res.ok)
throw new Error("Błąd pobierania wydarzeń");
const events = yield res.json();
if (events.length === 0) {
container.innerHTML = "<p class='text-muted'>Brak wydarzeń do wyświetlenia.</p>";
return;
}
for (const ev of events) {
const card = document.createElement("div");
card.className = "col";
card.innerHTML = `
<div class="card shadow-sm h-100">
<div class="card-body">
<h5 class="card-title">${ev.title}</h5>
<p class="card-text">
<strong>Miejsce:</strong> ${ev.location}<br/>
<strong>Data:</strong> ${new Date(ev.eventDate).toLocaleString()}<br/>
<strong>Organizacja ID:</strong> ${ev.organisationId}
</p>
<button class="btn btn-outline-danger delete-btn" data-id="${ev.eventId}">
🗑️ Usuń
</button>
</div>
</div>
`;
container.appendChild(card);
}
}
catch (err) {
container.innerHTML = `<p class="text-danger">Błąd ładowania danych.</p>`;
console.error(err);
}
}));