Startpunkten
12
.config/dotnet-tools.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"dotnet-ef": {
|
||||
"version": "5.0.10",
|
||||
"commands": [
|
||||
"dotnet-ef"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
62
.gitignore
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
|
||||
## Build results
|
||||
bin/
|
||||
obj/
|
||||
out/
|
||||
.idea/
|
||||
|
||||
## Visual Studio cache/options
|
||||
.vs/
|
||||
*.user
|
||||
*.suo
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
## ASP.NET Core
|
||||
appsettings.Development.json
|
||||
appsettings.Local.json
|
||||
appsettings.*.json
|
||||
|
||||
## Sensitive data
|
||||
*.pfx
|
||||
*.snk
|
||||
secrets.json
|
||||
|
||||
## NuGet
|
||||
*.nupkg
|
||||
*.snupkg
|
||||
packages/
|
||||
.nuget/packages/
|
||||
|
||||
## Logs
|
||||
*.log
|
||||
logs/
|
||||
|
||||
## IIS
|
||||
_IISExpress/
|
||||
*.vspscc
|
||||
|
||||
## Rider / JetBrains
|
||||
.idea/
|
||||
*.DotSettings.user
|
||||
|
||||
## Resharper
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
|
||||
## Node / Frontend
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
dist/
|
||||
wwwroot/lib/
|
||||
|
||||
## Coverage & analysis
|
||||
coverage/
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
## Temporary files
|
||||
*.tmp
|
||||
*.temp
|
||||
~$*
|
||||
161
Controllers/LoginController.cs
Normal file
@@ -0,0 +1,161 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using PersonSport.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authentication; //För autentisering med Claims
|
||||
using Microsoft.AspNetCore.Authentication.Cookies; //För autentisering med Claims
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using System.Security.Cryptography;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
namespace PersonSport.Controllers {
|
||||
|
||||
[Authorize]
|
||||
public class LoginController : Controller {
|
||||
|
||||
[AllowAnonymous]
|
||||
public IActionResult Index() {
|
||||
return View();
|
||||
}
|
||||
|
||||
public IActionResult ShowAdmins() {
|
||||
List<Admin> administratorer = new();
|
||||
|
||||
using (var db = new IdrottContext()) {
|
||||
administratorer = db.Administratorer.ToList();
|
||||
ViewBag.antal = db.Administratorer.Count();
|
||||
}
|
||||
|
||||
return View(administratorer);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult CreateAdmin() {
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult CreateAdmin(Admin nyAdmin) {
|
||||
try {
|
||||
|
||||
nyAdmin.Password = Sha256_hash(nyAdmin.Password);
|
||||
|
||||
if (ModelState.IsValid) {
|
||||
using (var db = new IdrottContext()) {
|
||||
// Kolla om namnet är upptaget
|
||||
var antal = db.Administratorer.Where(s => s.Username == nyAdmin.Username).Count();
|
||||
if (antal == 0) {
|
||||
db.Add(nyAdmin);
|
||||
db.SaveChanges();
|
||||
}
|
||||
else {
|
||||
TempData["Meddelande"] = "Administratören finns redan. Välj ett annat namn.";
|
||||
}
|
||||
}
|
||||
return RedirectToAction(nameof(ShowAdmins));
|
||||
}
|
||||
}
|
||||
catch (Exception) {
|
||||
throw;
|
||||
}
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
public IActionResult DeleteAdmin(int id) {
|
||||
var admin = new Admin() { AdminId = id };
|
||||
|
||||
using (var db = new IdrottContext()) {
|
||||
int antalAdmins = db.Administratorer.Count();
|
||||
if (antalAdmins <= 1) {
|
||||
TempData["TooFewAdmins"] = "Det måste finnas minst 1 Administratör kvar.";
|
||||
}
|
||||
else {
|
||||
db.Attach(admin);
|
||||
db.Remove(admin);
|
||||
db.SaveChanges();
|
||||
}
|
||||
}
|
||||
|
||||
return RedirectToAction(nameof(ShowAdmins));
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult EditAdmin(int id) {
|
||||
Admin ny = new();
|
||||
|
||||
if (ModelState.IsValid) {
|
||||
using var db = new IdrottContext(); var admin = db.Administratorer.Where(p => p.AdminId == id).FirstOrDefault();
|
||||
ny.AdminId = admin.AdminId;
|
||||
ny.Username = admin.Username;
|
||||
db.SaveChanges();
|
||||
}
|
||||
return View(ny);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult EditAdmin(Admin updated) {
|
||||
if (ModelState.IsValid) {
|
||||
using (var db = new IdrottContext()) {
|
||||
var up = db.Administratorer.Where(p => p.AdminId == updated.AdminId).FirstOrDefault();
|
||||
|
||||
up.AdminId = updated.AdminId;
|
||||
up.Username = updated.Username;
|
||||
up.Password = Sha256_hash(updated.Password);
|
||||
db.SaveChanges();
|
||||
}
|
||||
return RedirectToAction(nameof(ShowAdmins));
|
||||
}
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
[AllowAnonymous]
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> CheckLogin(Admin attKolla, string returnUrl = null) {
|
||||
|
||||
using var db = new IdrottContext(); // Kolla uppgifterna mot DB
|
||||
// Lösenordet krypteras med SHA-256
|
||||
var loginAttempt = db.Administratorer.Where(p => p.Username == attKolla.Username && p.Password == Sha256_hash(attKolla.Password)).FirstOrDefault();
|
||||
|
||||
if (loginAttempt == null) {
|
||||
// Om de inte stämmer; skicka tillbaka till Login-sidan
|
||||
TempData["msg"] = "Inloggningen inte godkänd.";
|
||||
TempData["hint"] = "Tips: Testa 'admin' och 'password'";
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
else {
|
||||
var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
identity.AddClaim(new Claim(ClaimTypes.Name, attKolla.Username));
|
||||
|
||||
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity));
|
||||
if (returnUrl != null)
|
||||
return Redirect(returnUrl);
|
||||
else
|
||||
return RedirectToAction("Index", "Start");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IActionResult> Logout() {
|
||||
await HttpContext.SignOutAsync(
|
||||
CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
return RedirectToAction("Index", "Start");
|
||||
}
|
||||
|
||||
[AllowAnonymous]
|
||||
public static String Sha256_hash(string value) {
|
||||
StringBuilder sb = new();
|
||||
|
||||
using (var hash = SHA256.Create()) {
|
||||
Encoding enc = Encoding.UTF8;
|
||||
Byte[] result = hash.ComputeHash(enc.GetBytes(value));
|
||||
|
||||
foreach (Byte b in result)
|
||||
sb.Append(b.ToString("x2"));
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
229
Controllers/PersonController.cs
Normal file
@@ -0,0 +1,229 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using PersonSport.Models;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
namespace PersonSport.Controllers {
|
||||
|
||||
[Authorize]
|
||||
public class PersonController : Controller {
|
||||
private const int FileNameLength = 8;
|
||||
|
||||
private readonly IWebHostEnvironment Environment;
|
||||
|
||||
public PersonController(IWebHostEnvironment _environment) {
|
||||
Environment = _environment;
|
||||
}
|
||||
|
||||
public IActionResult Index(string sortOrder) {
|
||||
List<Person> personer = new();
|
||||
|
||||
using (var db = new IdrottContext()) {
|
||||
personer = sortOrder switch {
|
||||
"PersonId" => db.Personer.OrderBy(p => p.PersonId).ToList(),
|
||||
"PersonNamn" => db.Personer.OrderBy(p => p.PersonNamn).ToList(),
|
||||
"Epost" => db.Personer.OrderBy(p => p.Epost).ToList(),
|
||||
"Alder" => db.Personer.OrderBy(p => p.Alder).ToList(),
|
||||
"StartDatum" => db.Personer.OrderBy(p => p.StartDatum).ToList(),
|
||||
_ => db.Personer.OrderBy(p => p.PersonId).ToList(),
|
||||
};
|
||||
}
|
||||
|
||||
return View(personer);
|
||||
}
|
||||
|
||||
/* *********************************************************
|
||||
* Function: Search()
|
||||
* -----------------------------------------
|
||||
* Sammanfattning: Söker i databasen efter en viss post genom
|
||||
* att söka efter namn eller e-postadress.
|
||||
* Skapar en lista av personer och sparar undan söksträngen.
|
||||
* Populerar listan genom ett lambda-uttryck som motsvarade söksträngen.
|
||||
* Denna lista av personer skickas slutligen till Vyn.
|
||||
* ****************************************************** */
|
||||
[HttpPost]
|
||||
public IActionResult Search(IFormCollection fc) {
|
||||
string search = fc["search"];
|
||||
|
||||
List<Person> personer = new();
|
||||
|
||||
using (var db = new IdrottContext()) {
|
||||
personer = db.Personer.Where(p => p.PersonNamn.ToLower().Contains(search.ToLower()) || p.Epost.ToLower().Contains(search.ToLower())).ToList();
|
||||
}
|
||||
|
||||
return View(personer);
|
||||
}
|
||||
|
||||
[AllowAnonymous]
|
||||
[HttpGet]
|
||||
public IActionResult Create() {
|
||||
return View();
|
||||
}
|
||||
|
||||
[AllowAnonymous]
|
||||
[HttpPost]
|
||||
public IActionResult Create(IFormCollection fc) {
|
||||
Person person = new();
|
||||
try {
|
||||
person.PersonNamn = fc["PersonNamn"];
|
||||
person.Epost = fc["Epost"];
|
||||
person.Visningsbild = fc["Visningsbild"];
|
||||
person.Alder = int.Parse(fc["Alder"]);
|
||||
|
||||
if (person.Visningsbild != "") {
|
||||
person.Visningsbild = Request.Form.Files[0].FileName;
|
||||
IFormFileCollection files = Request.Form.Files;
|
||||
long size = files.Sum(f => f.Length);
|
||||
string BaseURL = this.Environment.WebRootPath + @"\images\userphoto\";
|
||||
|
||||
foreach (var formFile in files) {
|
||||
string localFileName = DateTime.UtcNow.Ticks.ToString()[FileNameLength..] + ".jpg";
|
||||
var filePath = BaseURL + localFileName;
|
||||
person.Visningsbild = localFileName;
|
||||
|
||||
// Kontrollerar så att den valda filen är en bildfil
|
||||
if (formFile.ContentType == "image/jpeg" || formFile.ContentType == "image/jpg" || formFile.ContentType == "image/png" || formFile.ContentType == "image/gif") {
|
||||
if (formFile.Length > 0) {
|
||||
using var stream = new FileStream(filePath, FileMode.Create); formFile.CopyTo(stream);
|
||||
}
|
||||
else
|
||||
ViewBag.e = "Där där bilden är 0 bytes. Måste vara lite tråkig eller?";
|
||||
}
|
||||
else
|
||||
ViewBag.e = "Det där var ingen bildfil";
|
||||
}
|
||||
}
|
||||
else
|
||||
person.Visningsbild = "noimage.jpg";
|
||||
if (ModelState.IsValid) {
|
||||
person.StartDatum = DateTime.Now;
|
||||
using (var db = new IdrottContext()) {
|
||||
db.Add(person);
|
||||
db.SaveChanges();
|
||||
}
|
||||
TempData["MeddelandeSuccess"] = "Medlemmen är tillagd i systemet.";
|
||||
return RedirectToAction("Index", "Start");
|
||||
}
|
||||
}
|
||||
catch (Exception) {
|
||||
throw;
|
||||
}
|
||||
TempData["MeddelandeFail"] = "Kunde inte lägga till personen.";
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
|
||||
public IActionResult Delete(int id) {
|
||||
try {
|
||||
var person = new Person() { PersonId = id };
|
||||
|
||||
using (var db = new IdrottContext()) {
|
||||
db.Attach(person);
|
||||
db.Remove(person);
|
||||
db.SaveChanges();
|
||||
}
|
||||
TempData["MeddelandeSuccess"] = "Medlemmen är borttagen ur systemet.";
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
catch (Exception) {
|
||||
TempData["MeddelandeFail"] = "Kunde inte ta bort personen.";
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Edit(int id) {
|
||||
Person p = new();
|
||||
try {
|
||||
using (var db = new IdrottContext()) {
|
||||
var person = db.Personer.Where(p => p.PersonId == id).FirstOrDefault();
|
||||
p.PersonId = person.PersonId;
|
||||
p.PersonNamn = person.PersonNamn;
|
||||
p.Epost = person.Epost;
|
||||
p.Alder = person.Alder;
|
||||
p.Visningsbild = person.Visningsbild;
|
||||
|
||||
db.SaveChanges();
|
||||
}
|
||||
return View(p);
|
||||
}
|
||||
catch (Exception) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult Edit(IFormCollection fc) {
|
||||
Person person = new();
|
||||
bool bytaBild = false;
|
||||
|
||||
try {
|
||||
person.PersonId = int.Parse(fc["PersonId"]);
|
||||
person.PersonNamn = fc["PersonNamn"];
|
||||
person.Epost = fc["Epost"];
|
||||
person.Visningsbild = fc["Visningsbild"];
|
||||
person.Alder = int.Parse(fc["Alder"]);
|
||||
|
||||
if (person.Visningsbild == "")
|
||||
bytaBild = false;
|
||||
else
|
||||
bytaBild = true;
|
||||
|
||||
if (bytaBild) {
|
||||
person.Visningsbild = Request.Form.Files[0].FileName;
|
||||
IFormFileCollection files = Request.Form.Files;
|
||||
long size = files.Sum(f => f.Length);
|
||||
string BaseURL = this.Environment.WebRootPath + @"\images\userphoto\";
|
||||
|
||||
foreach (var formFile in files) {
|
||||
string localFileName = DateTime.UtcNow.Ticks.ToString()[FileNameLength..] + ".jpg";
|
||||
var filePath = BaseURL + localFileName;
|
||||
person.Visningsbild = localFileName;
|
||||
|
||||
// Kontrollerar så att den valda filen är en bildfil
|
||||
if (formFile.ContentType == "image/jpeg" || formFile.ContentType == "image/jpg" || formFile.ContentType == "image/png" || formFile.ContentType == "image/gif") {
|
||||
if (formFile.Length > 0) {
|
||||
using var stream = new FileStream(filePath, FileMode.Create);
|
||||
formFile.CopyTo(stream);
|
||||
}
|
||||
else
|
||||
ViewBag.e = "Där där bilden är 0 bytes. Måste vara lite tråkig eller?";
|
||||
}
|
||||
else
|
||||
ViewBag.e = "Det där var ingen bildfil";
|
||||
}
|
||||
}
|
||||
else
|
||||
person.Visningsbild = "noimage.jpg";
|
||||
|
||||
if (ModelState.IsValid) {
|
||||
using (var db = new IdrottContext()) {
|
||||
var up = db.Personer.Where(p => p.PersonId == person.PersonId).FirstOrDefault();
|
||||
up.PersonId = person.PersonId;
|
||||
up.PersonNamn = person.PersonNamn;
|
||||
up.Epost = person.Epost;
|
||||
up.Alder = person.Alder;
|
||||
if (bytaBild)
|
||||
up.Visningsbild = person.Visningsbild;
|
||||
|
||||
db.SaveChanges();
|
||||
}
|
||||
TempData["MeddelandeSuccess"] = "Medlemmen är editerat med de nya uppgifterna.";
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
}
|
||||
catch (Exception) {
|
||||
throw;
|
||||
}
|
||||
TempData["MeddelandeFail"] = "Kunde inte editera personen.";
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
119
Controllers/PersonSportController.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using PersonSport.Models;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
namespace PersonSport.Controllers {
|
||||
|
||||
[Authorize]
|
||||
public class PersonSportController : Controller {
|
||||
public IActionResult Index(int? sportens_id = 1) {
|
||||
var db = new IdrottContext();
|
||||
|
||||
ViewBag.AllaSporter = db.Sporter.ToList();
|
||||
|
||||
ViewBag.sportens_id = sportens_id;
|
||||
ViewBag.SportNamn = db.Sporter
|
||||
.Where(a => a.SportId == sportens_id)
|
||||
.Select(a => a.SportNamn).Single();
|
||||
|
||||
ViewBag.PersonerIValdSport = (from pers in db.Personer
|
||||
where pers.PersonSporter.Any(c => c.SportId == sportens_id)
|
||||
select pers).ToList();
|
||||
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Enroll() {
|
||||
List<Person> personer = new();
|
||||
List<Sport> sporter = new();
|
||||
|
||||
using (var db = new IdrottContext()) {
|
||||
personer = db.Personer.ToList();
|
||||
}
|
||||
|
||||
using (var db = new IdrottContext()) {
|
||||
sporter = db.Sporter.ToList();
|
||||
}
|
||||
|
||||
ViewBag.personer = personer;
|
||||
ViewBag.sporter = sporter;
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult Enroll(IFormCollection fc) {
|
||||
try {
|
||||
int valtNamn = int.Parse(fc["Namn"]);
|
||||
int valdSport = int.Parse(fc["Sport"]);
|
||||
|
||||
using (var db = new IdrottContext()) {
|
||||
PersonSport.Models.PersonSport ps = new() { PersonId = valtNamn, SportId = valdSport };
|
||||
db.Add(ps);
|
||||
db.SaveChanges();
|
||||
}
|
||||
TempData["MeddelandeSuccess"] = "Medlemmen är tillagd i sporten.";
|
||||
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
catch (Exception) {
|
||||
TempData["MeddelandeFail"] = "Kunde inte lägga till medlemmen i sporten.";
|
||||
return View("/Start/Error");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
public IActionResult Deroll() {
|
||||
List<Person> personer = new();
|
||||
|
||||
using (var db = new IdrottContext()) {
|
||||
personer = db.Personer.ToList();
|
||||
}
|
||||
|
||||
return View(personer);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult DerollSport(IFormCollection fc) {
|
||||
try {
|
||||
int valdPersonId = int.Parse(fc["PersonId"]);
|
||||
|
||||
using (var db = new IdrottContext()) {
|
||||
ViewBag.SportForValdPerson = (from sport in db.Sporter
|
||||
where sport.PersonSporter.Any(c => c.PersonId == valdPersonId)
|
||||
select sport).ToList();
|
||||
}
|
||||
ViewBag.PersonId = valdPersonId;
|
||||
return View();
|
||||
}
|
||||
catch (FormatException) {
|
||||
|
||||
return RedirectToAction(nameof(Index));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult DerollDone(IFormCollection fc) {
|
||||
try {
|
||||
int valtPersonId = int.Parse(fc["PersonId"]);
|
||||
int valtSportId = int.Parse(fc["SportId"]);
|
||||
|
||||
using (var db = new IdrottContext()) {
|
||||
PersonSport.Models.PersonSport ps = new() { PersonId = valtPersonId, SportId = valtSportId };
|
||||
db.Remove(ps);
|
||||
db.SaveChanges();
|
||||
}
|
||||
TempData["MeddelandeSuccess"] = "Medlemmen är borttagen från sporten.";
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
catch (FormatException) {
|
||||
TempData["MeddelandeFail"] = "Kunde inte ta bort medlemmen från sporten";
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
236
Controllers/SportController.cs
Normal file
@@ -0,0 +1,236 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using PersonSport.Models;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
namespace PersonSport.Controllers {
|
||||
[Authorize]
|
||||
public class SportController : Controller {
|
||||
private const int FileNameLength = 8;
|
||||
|
||||
private readonly IWebHostEnvironment Environment;
|
||||
|
||||
public SportController(IWebHostEnvironment _environment) {
|
||||
Environment = _environment;
|
||||
}
|
||||
|
||||
|
||||
public IActionResult Index() {
|
||||
List<Sport> sporter = new();
|
||||
|
||||
using (var db = new IdrottContext()) {
|
||||
sporter = db.Sporter.ToList();
|
||||
}
|
||||
|
||||
return View(sporter);
|
||||
}
|
||||
|
||||
|
||||
[AllowAnonymous]
|
||||
public IActionResult Utbud() {
|
||||
List<Sport> sporter = new();
|
||||
|
||||
using (var db = new IdrottContext()) {
|
||||
sporter = db.Sporter.ToList();
|
||||
}
|
||||
|
||||
return View(sporter);
|
||||
}
|
||||
|
||||
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Create() {
|
||||
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult Create(IFormCollection fc) {
|
||||
Sport sport = new();
|
||||
try {
|
||||
sport.SportNamn = fc["SportNamn"];
|
||||
sport.Ingress = fc["Ingress"];
|
||||
sport.DetaljText = fc["DetaljText"];
|
||||
sport.Traningstider = fc["Traningstider"];
|
||||
sport.Bakgrundsbild = fc["Bakgrundsbild"];
|
||||
|
||||
if (sport.Bakgrundsbild != "") {
|
||||
sport.Bakgrundsbild = Request.Form.Files[0].FileName;
|
||||
IFormFileCollection files = Request.Form.Files;
|
||||
long size = files.Sum(f => f.Length);
|
||||
string BaseURL = this.Environment.WebRootPath + @"\images\sport\";
|
||||
|
||||
foreach (var formFile in files) {
|
||||
string localFileName = DateTime.UtcNow.Ticks.ToString()[FileNameLength..] + ".jpg";
|
||||
var filePath = BaseURL + localFileName;
|
||||
sport.Bakgrundsbild = localFileName;
|
||||
|
||||
// Kontrollerar så att den valda filen är en bildfil
|
||||
if (formFile.ContentType == "image/jpeg" || formFile.ContentType == "image/jpg" || formFile.ContentType == "image/png" || formFile.ContentType == "image/gif") {
|
||||
if (formFile.Length > 0) {
|
||||
using var stream = new FileStream(filePath, FileMode.Create); formFile.CopyTo(stream);
|
||||
}
|
||||
else
|
||||
ViewBag.e = "Där där bilden är 0 bytes. Måste vara lite tråkig eller?";
|
||||
}
|
||||
else
|
||||
ViewBag.e = "Det där var ingen bildfil";
|
||||
}
|
||||
}
|
||||
else
|
||||
sport.Bakgrundsbild = "noimage.jpg";
|
||||
if (ModelState.IsValid) {
|
||||
using (var db = new IdrottContext()) {
|
||||
db.Add(sport);
|
||||
db.SaveChanges();
|
||||
}
|
||||
TempData["MeddelandeSuccess"] = "Sporten är tillagd i systemet.";
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
}
|
||||
catch (Exception) {
|
||||
throw;
|
||||
}
|
||||
TempData["MeddelandeFail"] = "Kunde inte lägga till sporten.";
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
public IActionResult Delete(int id) {
|
||||
try {
|
||||
var sport = new Sport() { SportId = id };
|
||||
|
||||
using (var db = new IdrottContext()) {
|
||||
db.Attach(sport);
|
||||
db.Remove(sport);
|
||||
db.SaveChanges();
|
||||
}
|
||||
TempData["MeddelandeSuccess"] = "Sporten är borttagen ur systemet.";
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
catch (Exception) {
|
||||
TempData["MeddelandeFail"] = "Kunde inte ta bort sporten.";
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Edit(int id) {
|
||||
Sport p = new();
|
||||
try {
|
||||
using (var db = new IdrottContext()) {
|
||||
var sport = db.Sporter.Where(p => p.SportId == id).FirstOrDefault();
|
||||
p.SportId = sport.SportId;
|
||||
p.SportNamn = sport.SportNamn;
|
||||
p.Ingress = sport.Ingress;
|
||||
p.DetaljText = sport.DetaljText;
|
||||
p.Traningstider = sport.Traningstider;
|
||||
p.Bakgrundsbild = sport.Bakgrundsbild;
|
||||
db.SaveChanges();
|
||||
}
|
||||
return View(p);
|
||||
}
|
||||
catch (Exception) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult Edit(IFormCollection fc) {
|
||||
Sport sport = new();
|
||||
bool bytaBild = false;
|
||||
|
||||
try {
|
||||
sport.SportId = int.Parse(fc["SportId"]);
|
||||
sport.SportNamn = fc["SportNamn"];
|
||||
sport.Ingress = fc["Ingress"];
|
||||
sport.DetaljText = fc["DetaljText"];
|
||||
sport.Traningstider = fc["Traningstider"];
|
||||
sport.Bakgrundsbild = fc["Bakgrundsbild"];
|
||||
|
||||
if (sport.Bakgrundsbild == "")
|
||||
bytaBild = false;
|
||||
else
|
||||
bytaBild = true;
|
||||
|
||||
if (bytaBild) {
|
||||
sport.Bakgrundsbild = Request.Form.Files[0].FileName;
|
||||
IFormFileCollection files = Request.Form.Files;
|
||||
long size = files.Sum(f => f.Length);
|
||||
string BaseURL = this.Environment.WebRootPath + @"\images\sport\";
|
||||
|
||||
foreach (var formFile in files) {
|
||||
string localFileName = DateTime.UtcNow.Ticks.ToString()[FileNameLength..] + ".jpg";
|
||||
var filePath = BaseURL + localFileName;
|
||||
sport.Bakgrundsbild = localFileName;
|
||||
|
||||
// Kontrollerar så att den valda filen är en bildfil
|
||||
if (formFile.ContentType == "image/jpeg" || formFile.ContentType == "image/jpg" || formFile.ContentType == "image/png" || formFile.ContentType == "image/gif") {
|
||||
if (formFile.Length > 0) {
|
||||
using var stream = new FileStream(filePath, FileMode.Create); formFile.CopyTo(stream);
|
||||
}
|
||||
else
|
||||
ViewBag.e = "Där där bilden är 0 bytes. Måste vara lite tråkig eller?";
|
||||
}
|
||||
else
|
||||
ViewBag.e = "Det där var ingen bildfil";
|
||||
}
|
||||
}
|
||||
else
|
||||
sport.Bakgrundsbild = "nosport.jpg";
|
||||
|
||||
if (ModelState.IsValid) {
|
||||
using (var db = new IdrottContext()) {
|
||||
var up = db.Sporter.Where(p => p.SportId == sport.SportId).FirstOrDefault();
|
||||
|
||||
up.SportId = sport.SportId;
|
||||
up.SportNamn = sport.SportNamn;
|
||||
up.Ingress = sport.Ingress;
|
||||
up.DetaljText = sport.DetaljText;
|
||||
up.Traningstider = sport.Traningstider;
|
||||
|
||||
if (bytaBild)
|
||||
up.Bakgrundsbild = sport.Bakgrundsbild;
|
||||
|
||||
db.SaveChanges();
|
||||
}
|
||||
TempData["MeddelandeSuccess"] = "Sporten är uppdaterad med de nya uppgifterna.";
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
}
|
||||
catch (Exception) {
|
||||
throw;
|
||||
}
|
||||
TempData["MeddelandeFail"] = "Kunde inte editera sporten.";
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
[AllowAnonymous]
|
||||
[HttpGet]
|
||||
public IActionResult Details(int id) {
|
||||
Sport s = new();
|
||||
try {
|
||||
using (var db = new IdrottContext()) {
|
||||
var valdSport = db.Sporter.Where(p => p.SportId == id).FirstOrDefault();
|
||||
s.SportId = valdSport.SportId;
|
||||
s.SportNamn = valdSport.SportNamn;
|
||||
s.Ingress = valdSport.Ingress;
|
||||
s.DetaljText = valdSport.DetaljText;
|
||||
s.Traningstider = valdSport.Traningstider;
|
||||
s.Bakgrundsbild = valdSport.Bakgrundsbild;
|
||||
}
|
||||
ViewBag.metaAbstract = s.Ingress;
|
||||
ViewBag.metaImage = "https://sportpalatset.se/images/sport/" + s.Bakgrundsbild;
|
||||
return View(s);
|
||||
}
|
||||
catch (Exception) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
79
Controllers/StartController.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Net;
|
||||
using System.Net.Mail;
|
||||
using PersonSport.Models;
|
||||
|
||||
|
||||
namespace PersonSport.Controllers {
|
||||
public class StartController : Controller {
|
||||
|
||||
public IActionResult Index() {
|
||||
return View();
|
||||
}
|
||||
public IActionResult Priser() {
|
||||
return View();
|
||||
}
|
||||
public IActionResult Kurser() {
|
||||
return View();
|
||||
}
|
||||
public IActionResult Receptionen() {
|
||||
return View();
|
||||
}
|
||||
public IActionResult Oppettider() {
|
||||
return View();
|
||||
}
|
||||
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult SendMail(IFormCollection fc) {
|
||||
MailViewModel mvm = new();
|
||||
|
||||
if (ModelState.IsValid) {
|
||||
string formFrom = fc["Epost"];
|
||||
string formSubject = fc["Subject"];
|
||||
string formMessage = fc["Message"];
|
||||
|
||||
|
||||
string to = "christian.ohlsson@gmail.com"; // Mottagarens e-postadress
|
||||
string from = "imcoh@hv.se"; // Avsändarens e-postadress
|
||||
|
||||
string mailIntro = "<h3>Detta är ett meddelande från formuläret på SportPalatset</h3>"
|
||||
+ "Avsändare: <b>" + formFrom + "</b><br />"
|
||||
+ "Meddelandet lyder:<br /><br />";
|
||||
|
||||
string mailEnd = "<br /><br /><br /><br />"
|
||||
+ "-------------------------------------------------------------"
|
||||
+ "<p>Tänk på miljön och skriv inte ut detta mail</p>"
|
||||
+ "<img src='https://crille.org/sportpalatsetlogo.png' alt='Logo'>";
|
||||
|
||||
MailMessage message = new(from, to);
|
||||
|
||||
message.Subject = formSubject;
|
||||
message.Body = mailIntro + formMessage + mailEnd;
|
||||
message.BodyEncoding = Encoding.UTF8;
|
||||
message.IsBodyHtml = true;
|
||||
SmtpClient client = new("smtp.live.com", 587); // Outlook smtp
|
||||
NetworkCredential basicCredential1 = new("imcoh@hv.se", "s3jsVYQc3Bs2N4MN");
|
||||
client.EnableSsl = true;
|
||||
client.UseDefaultCredentials = false;
|
||||
client.Credentials = basicCredential1;
|
||||
try {
|
||||
TempData["MeddelandeSuccess"] = "Ditt meddelande har skickats till SportPalatset.";
|
||||
client.Send(message);
|
||||
}
|
||||
|
||||
catch (Exception) {
|
||||
throw;
|
||||
}
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
else {
|
||||
TempData["MeddelandeFail"] = "Mailet har inte skickats";
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
Data/PersonSport.db
Normal file
1
Data/PersonSport.sqbpro
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><sqlb_project><db path="C:\Users\ChristianOhlsson(HV)\OneDrive - Högskolan Väst\skola\Databasteknik och webbaserade system [Umeå HT21]\Projektarbete\PersonSport\Data\PersonSport.db" readonly="0" foreign_keys="1" case_sensitive_like="0" temp_store="0" wal_autocheckpoint="1000" synchronous="2"/><attached/><window><main_tabs open="structure browser pragmas query" current="1"/></window><tab_structure><column_width id="0" width="300"/><column_width id="1" width="0"/><column_width id="2" width="100"/><column_width id="3" width="2708"/><column_width id="4" width="0"/><expanded_item id="0" parent="1"/><expanded_item id="1" parent="1"/><expanded_item id="2" parent="1"/><expanded_item id="3" parent="1"/></tab_structure><tab_browse><current_table name="4,15:mainAdministratorer"/><default_encoding codec=""/><browse_table_settings><table schema="main" name="Administratorer" show_row_id="0" encoding="" plot_x_axis="" unlock_view_pk="_rowid_"><sort/><column_widths><column index="1" value="61"/><column index="2" value="72"/><column index="3" value="300"/></column_widths><filter_values/><conditional_formats/><row_id_formats/><display_formats/><hidden_columns/><plot_y_axes/><global_filter/></table></browse_table_settings></tab_browse><tab_sql><sql name="SQL 1"></sql><current_tab id="0"/></tab_sql></sqlb_project>
|
||||
156
Migrations/20211013071744_Initial.Designer.cs
generated
Normal file
@@ -0,0 +1,156 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using PersonSport.Models;
|
||||
|
||||
namespace PersonSport.Migrations
|
||||
{
|
||||
[DbContext(typeof(IdrottContext))]
|
||||
[Migration("20211013071744_Initial")]
|
||||
partial class Initial
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "5.0.10");
|
||||
|
||||
modelBuilder.Entity("PersonSport.Models.Admin", b =>
|
||||
{
|
||||
b.Property<int>("AdminId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasMaxLength(80)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Username")
|
||||
.IsRequired()
|
||||
.HasMaxLength(40)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("AdminId");
|
||||
|
||||
b.ToTable("Administratorer");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PersonSport.Models.Person", b =>
|
||||
{
|
||||
b.Property<int>("PersonId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Alder")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Epost")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("PersonNamn")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("StartDatum")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Visningsbild")
|
||||
.HasMaxLength(80)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("PersonId");
|
||||
|
||||
b.ToTable("Personer");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PersonSport.Models.PersonSport", b =>
|
||||
{
|
||||
b.Property<int>("PersonId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("SportId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("StartDatum")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("PersonId", "SportId");
|
||||
|
||||
b.HasIndex("SportId");
|
||||
|
||||
b.ToTable("PersonSport");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PersonSport.Models.Sport", b =>
|
||||
{
|
||||
b.Property<int>("SportId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Bakgrundsbild")
|
||||
.IsRequired()
|
||||
.HasMaxLength(60)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DetaljText")
|
||||
.HasMaxLength(2000)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Ingress")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("SportNamn")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Traningstider")
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("SportId");
|
||||
|
||||
b.ToTable("Sporter");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PersonSport.Models.PersonSport", b =>
|
||||
{
|
||||
b.HasOne("PersonSport.Models.Person", "Person")
|
||||
.WithMany("PersonSporter")
|
||||
.HasForeignKey("PersonId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PersonSport.Models.Sport", "Sport")
|
||||
.WithMany("PersonSporter")
|
||||
.HasForeignKey("SportId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Person");
|
||||
|
||||
b.Navigation("Sport");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PersonSport.Models.Person", b =>
|
||||
{
|
||||
b.Navigation("PersonSporter");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PersonSport.Models.Sport", b =>
|
||||
{
|
||||
b.Navigation("PersonSporter");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
104
Migrations/20211013071744_Initial.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace PersonSport.Migrations
|
||||
{
|
||||
public partial class Initial : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Administratorer",
|
||||
columns: table => new
|
||||
{
|
||||
AdminId = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Username = table.Column<string>(type: "TEXT", maxLength: 40, nullable: false),
|
||||
Password = table.Column<string>(type: "TEXT", maxLength: 80, nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Administratorer", x => x.AdminId);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Personer",
|
||||
columns: table => new
|
||||
{
|
||||
PersonId = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
PersonNamn = table.Column<string>(type: "TEXT", maxLength: 50, nullable: false),
|
||||
Epost = table.Column<string>(type: "TEXT", maxLength: 50, nullable: false),
|
||||
Alder = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
StartDatum = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||
Visningsbild = table.Column<string>(type: "TEXT", maxLength: 80, nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Personer", x => x.PersonId);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Sporter",
|
||||
columns: table => new
|
||||
{
|
||||
SportId = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
SportNamn = table.Column<string>(type: "TEXT", maxLength: 50, nullable: false),
|
||||
Bakgrundsbild = table.Column<string>(type: "TEXT", maxLength: 60, nullable: false),
|
||||
Ingress = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false),
|
||||
DetaljText = table.Column<string>(type: "TEXT", maxLength: 2000, nullable: true),
|
||||
Traningstider = table.Column<string>(type: "TEXT", maxLength: 200, nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Sporter", x => x.SportId);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "PersonSport",
|
||||
columns: table => new
|
||||
{
|
||||
PersonId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
SportId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
StartDatum = table.Column<DateTime>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_PersonSport", x => new { x.PersonId, x.SportId });
|
||||
table.ForeignKey(
|
||||
name: "FK_PersonSport_Personer_PersonId",
|
||||
column: x => x.PersonId,
|
||||
principalTable: "Personer",
|
||||
principalColumn: "PersonId",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_PersonSport_Sporter_SportId",
|
||||
column: x => x.SportId,
|
||||
principalTable: "Sporter",
|
||||
principalColumn: "SportId",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_PersonSport_SportId",
|
||||
table: "PersonSport",
|
||||
column: "SportId");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Administratorer");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "PersonSport");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Personer");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Sporter");
|
||||
}
|
||||
}
|
||||
}
|
||||
154
Migrations/IdrottContextModelSnapshot.cs
Normal file
@@ -0,0 +1,154 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using PersonSport.Models;
|
||||
|
||||
namespace PersonSport.Migrations
|
||||
{
|
||||
[DbContext(typeof(IdrottContext))]
|
||||
partial class IdrottContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "5.0.10");
|
||||
|
||||
modelBuilder.Entity("PersonSport.Models.Admin", b =>
|
||||
{
|
||||
b.Property<int>("AdminId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasMaxLength(80)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Username")
|
||||
.IsRequired()
|
||||
.HasMaxLength(40)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("AdminId");
|
||||
|
||||
b.ToTable("Administratorer");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PersonSport.Models.Person", b =>
|
||||
{
|
||||
b.Property<int>("PersonId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Alder")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Epost")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("PersonNamn")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("StartDatum")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Visningsbild")
|
||||
.HasMaxLength(80)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("PersonId");
|
||||
|
||||
b.ToTable("Personer");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PersonSport.Models.PersonSport", b =>
|
||||
{
|
||||
b.Property<int>("PersonId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("SportId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("StartDatum")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("PersonId", "SportId");
|
||||
|
||||
b.HasIndex("SportId");
|
||||
|
||||
b.ToTable("PersonSport");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PersonSport.Models.Sport", b =>
|
||||
{
|
||||
b.Property<int>("SportId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Bakgrundsbild")
|
||||
.IsRequired()
|
||||
.HasMaxLength(60)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DetaljText")
|
||||
.HasMaxLength(2000)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Ingress")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("SportNamn")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Traningstider")
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("SportId");
|
||||
|
||||
b.ToTable("Sporter");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PersonSport.Models.PersonSport", b =>
|
||||
{
|
||||
b.HasOne("PersonSport.Models.Person", "Person")
|
||||
.WithMany("PersonSporter")
|
||||
.HasForeignKey("PersonId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PersonSport.Models.Sport", "Sport")
|
||||
.WithMany("PersonSporter")
|
||||
.HasForeignKey("SportId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Person");
|
||||
|
||||
b.Navigation("Sport");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PersonSport.Models.Person", b =>
|
||||
{
|
||||
b.Navigation("PersonSporter");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PersonSport.Models.Sport", b =>
|
||||
{
|
||||
b.Navigation("PersonSporter");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
18
Models/Admin.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace PersonSport.Models {
|
||||
public class Admin {
|
||||
[Required]
|
||||
public int AdminId { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "Du måste ange ett användarnamn")]
|
||||
[StringLength(40, MinimumLength = 2, ErrorMessage = "Användarnamnet måste vara mellan 2 och 40 tecken")]
|
||||
public string Username { get; set; }
|
||||
|
||||
|
||||
[Required(ErrorMessage = "Du måste ange ett lösenord")]
|
||||
[DataType(DataType.Password)]
|
||||
[StringLength(80, MinimumLength=6, ErrorMessage="Lösenordet måste vara minst 6 tecken.")]
|
||||
public string Password { get; set; }
|
||||
}
|
||||
}
|
||||
7
Models/ErrorViewModel.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace PersonSport.Models {
|
||||
public class ErrorViewModel {
|
||||
public string RequestId { get; set; }
|
||||
|
||||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||
}
|
||||
}
|
||||
35
Models/IdrottContext.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
namespace PersonSport.Models {
|
||||
public class IdrottContext : DbContext {
|
||||
public DbSet<Person> Personer { get; set; }
|
||||
public DbSet<Sport> Sporter { get; set; }
|
||||
public DbSet<Admin> Administratorer { get; set; }
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder options)
|
||||
// Azure
|
||||
// => options.UseSqlite("FileName=C:/Users/ChristianOhlsson(HV)/OneDrive - Högskolan Väst/skola/Databasteknik och webbaserade system [Umeå HT21]/Projektarbete/PersonSport/Data/PersonSport.db");
|
||||
// Lokalt
|
||||
=> options.UseSqlite("DataSource=./Data/PersonSport.db");
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder) {
|
||||
modelBuilder.Entity<PersonSport>()
|
||||
.HasKey(c => new { c.PersonId, c.SportId });
|
||||
|
||||
modelBuilder.Entity<Person>()
|
||||
.HasMany(c => c.PersonSporter);
|
||||
|
||||
modelBuilder.Entity<Sport>()
|
||||
.HasMany(c => c.PersonSporter);
|
||||
|
||||
// Tar bort "ON DELETE CASCADE" så att inte sporten försvinner om sista personen
|
||||
// som utövar den gör det.
|
||||
base.OnModelCreating(modelBuilder);
|
||||
foreach (var relationship in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys())) {
|
||||
relationship.DeleteBehavior = DeleteBehavior.Restrict;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
21
Models/MailViewModel.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace PersonSport.Models {
|
||||
public class MailViewModel {
|
||||
[Required(ErrorMessage = "Du måste ange din e-postadress så vi kan kontakta dig")]
|
||||
[StringLength(50, MinimumLength = 6, ErrorMessage = "Din epost-adress måste vara minst 6 tecken och max 50 tecken")]
|
||||
[Display(Name = "Din E-postadress")]
|
||||
[RegularExpression(@"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$", ErrorMessage = "Felaktig e-postadress")]
|
||||
public string Epost { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "Du måste ange ditt ärende")]
|
||||
[StringLength(50, MinimumLength = 3, ErrorMessage = "Ditt ärende måste vara minst 3 tecken och max 50 tecken")]
|
||||
[Display(Name = "Ärende")]
|
||||
public string Subject { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "Du måste skriva vad det gäller")]
|
||||
[StringLength(500, MinimumLength = 5, ErrorMessage="Ditt meddelande måste vara minst 5 tecken och max 500 tecken")]
|
||||
[Display(Name = "Meddelande")]
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
||||
36
Models/Person.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace PersonSport.Models {
|
||||
public class Person {
|
||||
[Required]
|
||||
public int PersonId { get; set; }
|
||||
|
||||
[Required(ErrorMessage ="Du måste ange ditt namn")]
|
||||
[StringLength(50, MinimumLength = 3, ErrorMessage = "Namnet måste vara mellan 3 och 50 tecken")]
|
||||
[Display(Name = "Ditt namn")]
|
||||
public string PersonNamn { get; set; }
|
||||
|
||||
[Required(ErrorMessage="Du måste ange din e-postadress")]
|
||||
[StringLength(50, MinimumLength = 6)]
|
||||
[Display(Name = "Din E-postadress")]
|
||||
[RegularExpression(@"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$", ErrorMessage = "Felaktig e-postadress")]
|
||||
public string Epost { get; set; }
|
||||
|
||||
[Required(ErrorMessage="Du måste ange hur många år du är")]
|
||||
[Range(8, 99, ErrorMessage = "Din ålder måste vara mellan 8 och 99 år")]
|
||||
[Display(Name = "Ålder")]
|
||||
public int Alder { get; set; }
|
||||
|
||||
[Display(Name = "Registrerad")]
|
||||
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-d}")]
|
||||
[DataType(DataType.DateTime)]
|
||||
public DateTime StartDatum { get; set; }
|
||||
|
||||
[StringLength(80, MinimumLength = 3, ErrorMessage = "Bildens namn måste vara mellan 3 och 80 tecken")]
|
||||
public string Visningsbild { get; set; }
|
||||
|
||||
public virtual ICollection<PersonSport> PersonSporter { get; set; }
|
||||
}
|
||||
}
|
||||
20
Models/PersonSport.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace PersonSport.Models {
|
||||
public class PersonSport {
|
||||
[Key, Column(Order = 1)]
|
||||
public int PersonId { get; set; }
|
||||
|
||||
[Key, Column(Order = 2)]
|
||||
public int SportId { get; set; }
|
||||
|
||||
[DataType(DataType.Date)]
|
||||
public DateTime StartDatum { get; set; }
|
||||
|
||||
public virtual Person Person { get; set; }
|
||||
|
||||
public virtual Sport Sport { get; set; }
|
||||
}
|
||||
}
|
||||
34
Models/Sport.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace PersonSport.Models {
|
||||
public class Sport {
|
||||
[Required]
|
||||
public int SportId { get; set; }
|
||||
|
||||
[Required(ErrorMessage="Du måste ange sportens namn")]
|
||||
[StringLength(50, MinimumLength = 3, ErrorMessage = "Namnet måste vara mellan 3 och 50 tecken")]
|
||||
[Display(Name = "Namn på sporten")]
|
||||
public string SportNamn { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "Du måste välja en bild för webbsidan")]
|
||||
[StringLength(60, MinimumLength = 3, ErrorMessage = "Bildens namn måste vara mellan 3 och 60 tecken")]
|
||||
[Display(Name = "Stor bakgrundsbild")]
|
||||
public string Bakgrundsbild { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "Du måste skriva en ingresstext")]
|
||||
[StringLength(200, MinimumLength = 10, ErrorMessage = "Din ingress-text måste vara mellan 10 och 200 tecken")]
|
||||
[Display(Name = "Ingresstext")]
|
||||
public string Ingress { get; set; }
|
||||
|
||||
[StringLength(2000)]
|
||||
[Display(Name = "Detaljerad text")]
|
||||
public string DetaljText { get; set; }
|
||||
|
||||
[StringLength(200)]
|
||||
[Display(Name = "Träningstider")]
|
||||
public string Traningstider { get; set; }
|
||||
|
||||
public virtual ICollection<PersonSport> PersonSporter { get; set; }
|
||||
}
|
||||
}
|
||||
23
PersonSport.csproj
Normal file
@@ -0,0 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="EntityFramework" Version="6.4.4" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.11" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.11" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.11" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.11">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="5.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Data\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
25
PersonSport.sln
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.31702.278
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PersonSport", "PersonSport.csproj", "{ECAC1C40-BD93-408C-8820-FAC230779619}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{ECAC1C40-BD93-408C-8820-FAC230779619}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{ECAC1C40-BD93-408C-8820-FAC230779619}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{ECAC1C40-BD93-408C-8820-FAC230779619}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{ECAC1C40-BD93-408C-8820-FAC230779619}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {557145B7-E0D6-41AA-A112-BC4FA6D775CE}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
16
Program.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace PersonSport {
|
||||
public class Program {
|
||||
public static void Main(string[] args) {
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureWebHostDefaults(webBuilder => {
|
||||
webBuilder.UseStartup<Startup>();
|
||||
});
|
||||
}
|
||||
}
|
||||
30
Properties/PublishProfiles/sportpalatset - Web Deploy.pubxml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
|
||||
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<WebPublishMethod>MSDeploy</WebPublishMethod>
|
||||
<ResourceId>/subscriptions/04503b37-5476-437e-91f0-db13b29af319/resourceGroups/PersonSport20211012092753ResourceGroup/providers/Microsoft.Web/sites/sportpalatset</ResourceId>
|
||||
<ResourceGroup>PersonSport20211012092753ResourceGroup</ResourceGroup>
|
||||
<PublishProvider>AzureWebSite</PublishProvider>
|
||||
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
|
||||
<LastUsedPlatform>Any CPU</LastUsedPlatform>
|
||||
<SiteUrlToLaunchAfterPublish>https://sportpalatset.azurewebsites.net</SiteUrlToLaunchAfterPublish>
|
||||
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
|
||||
<ExcludeApp_Data>False</ExcludeApp_Data>
|
||||
<ProjectGuid>ecac1c40-bd93-408c-8820-fac230779619</ProjectGuid>
|
||||
<MSDeployServiceURL>sportpalatset.scm.azurewebsites.net:443</MSDeployServiceURL>
|
||||
<DeployIisAppPath>sportpalatset</DeployIisAppPath>
|
||||
<RemoteSitePhysicalPath />
|
||||
<SkipExtraFilesOnServer>True</SkipExtraFilesOnServer>
|
||||
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
|
||||
<EnableMSDeployBackup>True</EnableMSDeployBackup>
|
||||
<EnableMsDeployAppOffline>True</EnableMsDeployAppOffline>
|
||||
<UserName>$sportpalatset</UserName>
|
||||
<_SavePWD>True</_SavePWD>
|
||||
<_DestinationType>AzureWebSite</_DestinationType>
|
||||
<InstallAspNetCoreSiteExtension>False</InstallAspNetCoreSiteExtension>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
28
Properties/launchSettings.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:46988",
|
||||
"sslPort": 44370
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"PersonSport": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": "true",
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "https://localhost:5001;http://localhost:5000",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"mssql1": {
|
||||
"type": "mssql",
|
||||
"connectionId": "",
|
||||
"suggestion": "true",
|
||||
"ignored": "true"
|
||||
}
|
||||
}
|
||||
}
|
||||
54
Startup.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies; // För inloggning med Claims
|
||||
|
||||
namespace PersonSport {
|
||||
public class Startup {
|
||||
public Startup(IConfiguration configuration) {
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
public IConfiguration Configuration { get; }
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services) {
|
||||
services.AddControllersWithViews();
|
||||
|
||||
// Lägg till stöd för loginfunktionen. OBS LoginPath!
|
||||
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
|
||||
.AddCookie(options => { options.LoginPath = "/Login/Index/"; });
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
|
||||
if (env.IsDevelopment()) {
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
else {
|
||||
app.UseExceptionHandler("/Start/Error");
|
||||
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
||||
app.UseHsts();
|
||||
}
|
||||
|
||||
// Gör att sidan använder sig av autentisering med Claims
|
||||
app.UseAuthentication();
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
// Sidan ska även använda sig av Authorization
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseEndpoints(endpoints => {
|
||||
endpoints.MapControllerRoute(
|
||||
name: "default",
|
||||
pattern: "{controller=Start}/{action=Index}/{id?}");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
6
TODO.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
https://sportpalatset.azurewebsites.net/
|
||||
|
||||
- Pluggen WebDeveloper till FF för att kolla alla sidors syntax
|
||||
- URL-rewrite på Details så att det blir /karate och inte /1
|
||||
- Kolla validator på allt
|
||||
|
||||
27
Views/Login/CreateAdmin.cshtml
Normal file
@@ -0,0 +1,27 @@
|
||||
@model Admin
|
||||
@{
|
||||
ViewData["Title"] = "Lägg till administratör";
|
||||
}
|
||||
<h2 class="text-center mt-3 mb-4">@ViewData["Title"]</h2>
|
||||
<div class="container">
|
||||
|
||||
<form action="/Login/CreateAdmin" method="post">
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.Username" class="control-label"></label>
|
||||
<input type="text" class="form-control" asp-for="Username" tabindex="1" placeholder="Username">
|
||||
<span asp-validation-for="Username" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.Password" class="control-label"></label>
|
||||
<input type="password" class="form-control" asp-for="Password" tabindex="2" placeholder="Password">
|
||||
<span asp-validation-for="Password" class="text-danger"></span>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Skapa admin</button>
|
||||
</form>
|
||||
<p>@ViewBag.error</p>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
||||
|
||||
30
Views/Login/EditAdmin.cshtml
Normal file
@@ -0,0 +1,30 @@
|
||||
@model Admin
|
||||
@{
|
||||
ViewData["Title"] = "Editera administratör";
|
||||
}
|
||||
|
||||
<h2 class="text-center mt-3 mb-4">@ViewData["Title"]</h2>
|
||||
<div class="container">
|
||||
<form action="/Login/EditAdmin" method="post">
|
||||
<input type="hidden" asp-for="AdminId" value="@Model.AdminId" />
|
||||
<div class="form-group">
|
||||
<label asp-for="Username" class="control-label"></label>
|
||||
<input type="text" class="form-control" asp-for="Username" tabindex="1">
|
||||
<span asp-validation-for="Username" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.Password" class="control-label"></label>
|
||||
<input type="password" class="form-control" asp-for="Password" tabindex="2">
|
||||
<span asp-validation-for="Password" class="text-danger"></span>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary mb-5">Editera admin</button>
|
||||
</form>
|
||||
<p>@ViewBag.error</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
||||
|
||||
29
Views/Login/Index.cshtml
Normal file
@@ -0,0 +1,29 @@
|
||||
@model Admin
|
||||
@{
|
||||
ViewData["Title"] = "Logga in";
|
||||
}
|
||||
|
||||
<h2 class="text-center mt-3 mb-4">@ViewData["Title"]</h2>
|
||||
<div class="container mb-5">
|
||||
<div class="myLoginForm card p-4">
|
||||
<form action="~/Login/CheckLogin" method="post">
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.Username" class="control-label"></label>
|
||||
<input type="text" class="form-control" asp-for="Username" tabindex="1" placeholder="Username">
|
||||
<span asp-validation-for="Username" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.Password" class="control-label"></label>
|
||||
<input type="password" class="form-control" asp-for="Password" tabindex="2" placeholder="Password">
|
||||
<span asp-validation-for="Password" class="text-danger"></span>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Logga in</button>
|
||||
</form>
|
||||
|
||||
<p class="text-danger mt-3">@TempData["msg"]</p>
|
||||
<p class="text-primary mt-3" ">@TempData["hint"]</p>
|
||||
</div>
|
||||
</div>
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
||||
55
Views/Login/ShowAdmins.cshtml
Normal file
@@ -0,0 +1,55 @@
|
||||
@model List<Admin>
|
||||
@{
|
||||
ViewData["Title"] = "Här finns alla administratörer";
|
||||
}
|
||||
|
||||
<h2 class="text-center mt-3 mb-4">@ViewData["Title"]</h2>
|
||||
<p class="lead text-center">Det är bra om alla i receptionen är registrerade som administratör.</p>
|
||||
|
||||
@if (TempData.ContainsKey("Meddelande")) {
|
||||
<div class="alert alert-danger alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<strong>Skapades inte!</strong> @TempData["Meddelande"]
|
||||
</div>
|
||||
}
|
||||
else @if (TempData.ContainsKey("TooFewAdmins")) {
|
||||
<div class="alert alert-danger alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<strong>Togs inte bort!</strong> @TempData["TooFewAdmins"]
|
||||
</div>
|
||||
}
|
||||
|
||||
<a asp-action="CreateAdmin" asp-controller="Login" class="btn btn-success mb-3">Skapa ny administratör</a>
|
||||
|
||||
<div class="container mb-5">
|
||||
@if (Model.Count() >= 1) {
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Administratör</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var admin in Model) {
|
||||
<tr>
|
||||
<td>@admin.Username</td>
|
||||
<td>
|
||||
<a asp-action="DeleteAdmin" asp-controller="Login" asp-route-Id="@admin.AdminId">Ta bort</a> |
|
||||
<a asp-action="EditAdmin" asp-controller="Login" asp-route-Id="@admin.AdminId">Editera</a>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
}
|
||||
</div>
|
||||
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
||||
|
||||
|
||||
|
||||
38
Views/Person/Create.cshtml
Normal file
@@ -0,0 +1,38 @@
|
||||
@model Person
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Lägg till ny medlem";
|
||||
}
|
||||
|
||||
<h2 class="text-center mt-3 mb-4">@ViewData["Title"]</h2>
|
||||
|
||||
<div class="container mb-5">
|
||||
<form action="Create" method="post" enctype="multipart/form-data">
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.PersonNamn" class="control-label"></label>
|
||||
<input type="text" class="form-control" asp-for="PersonNamn" tabindex="1" placeholder="Ditt namn">
|
||||
<span asp-validation-for="PersonNamn" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.Epost" class="control-label"></label>
|
||||
<input type="text" class="form-control" asp-for="Epost" tabindex="2" placeholder="ditt.namn@adress.com">
|
||||
<span asp-validation-for="Epost" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.Alder" class="control-label"></label>
|
||||
<input type="number" class="form-control" asp-for="Alder" tabindex="3" placeholder="Ange din ålder">
|
||||
<span asp-validation-for="Alder" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.Visningsbild" class="control-label"></label>
|
||||
<input type="file" class="form-control" asp-for="Visningsbild" tabindex="4">
|
||||
<span asp-validation-for="Visningsbild" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary mt-3">@ViewData["Title"]</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
||||
36
Views/Person/Edit.cshtml
Normal file
@@ -0,0 +1,36 @@
|
||||
@model Person
|
||||
@{
|
||||
ViewData["Title"] = "Editera en person";
|
||||
}
|
||||
<h2 class="text-center mt-3 mb-4">@ViewData["Title"]</h2>
|
||||
|
||||
<div class="container">
|
||||
<form action="Edit" method="post" enctype="multipart/form-data">
|
||||
<input type="hidden" asp-for="PersonId" value="@Model.PersonId" />
|
||||
<div class="form-group">
|
||||
<label>Namn</label>
|
||||
<input type="text" class="form-control" asp-for="PersonNamn" tabindex="1">
|
||||
<span asp-validation-for="PersonNamn" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Epost" class="control-label"></label>
|
||||
<input type="text" class="form-control" asp-for="Epost" tabindex="2" placeholder="ditt.namn@adress.com">
|
||||
<span asp-validation-for="Epost" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Alder" class="control-label"></label>
|
||||
<input type="number" class="form-control" asp-for="Alder" tabindex="3" placeholder="Ange din ålder">
|
||||
<span asp-validation-for="Alder" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.Visningsbild" class="control-label"></label>
|
||||
<input type="file" class="form-control" asp-for="Visningsbild" tabindex="4">
|
||||
<span asp-validation-for="Visningsbild" class="text-danger"></span>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Spara ändringar</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
||||
77
Views/Person/Index.cshtml
Normal file
@@ -0,0 +1,77 @@
|
||||
@model List<Person>
|
||||
@{
|
||||
ViewData["Title"] = "Mina medlemmar";
|
||||
}
|
||||
@if (TempData.ContainsKey("MeddelandeSuccess")) {
|
||||
<div class="alert alert-success alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<strong>Allt klart!</strong> @TempData["MeddelandeSuccess"]
|
||||
</div>
|
||||
}
|
||||
else if (TempData.ContainsKey("MeddelandeFail")) {
|
||||
<div class="alert alert-danger alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<strong>Något gick fel.</strong> @TempData["MeddelandeFail"]
|
||||
</div>
|
||||
}
|
||||
|
||||
<h2 class="text-center mt-3 mb-4">@ViewData["Title"]</h2>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<a href="/Person/Create" class="btn btn-success mb-5">Skapa ny medlem</a>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<form asp-action="Search" method="post">
|
||||
<div class="form-group">
|
||||
<label class="control-label">
|
||||
<input name="search" id="search" class="form-control" tabindex="1" placeholder="Namn eller E-post" />
|
||||
</label>
|
||||
<input type="submit" value="Sök" class="btn btn-primary" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container mb-5">
|
||||
@if (Model.Count() >= 0) {
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>@Html.ActionLink("Id", "Index", null, new { sortOrder = "PersonId" })</th>
|
||||
<th>@Html.ActionLink("Namn", "Index", null, new { sortOrder = "PersonNamn" })</th>
|
||||
<th>@Html.ActionLink("E-post", "Index", null, new { sortOrder = "Epost" })</th>
|
||||
<th>@Html.ActionLink("Ålder", "Index", null, new { sortOrder = "Alder" })</th>
|
||||
<th>@Html.ActionLink("Registrerad", "Index", null, new { sortOrder = "StartDatum" })</th>
|
||||
<th>Visningsbild</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var person in Model) {
|
||||
<tr>
|
||||
<td>@person.PersonId</td>
|
||||
<td>@person.PersonNamn</td>
|
||||
<td>@person.Epost</td>
|
||||
<td>@person.Alder</td>
|
||||
<td>@person.StartDatum</td>
|
||||
<td><img src="~/images/userphoto/@person.Visningsbild" alt="@person.PersonNamn" class="visningsbild" /></td>
|
||||
<td>
|
||||
<a asp-action="Delete" asp-controller="Person" asp-route-Id="@person.PersonId">Ta bort</a> |
|
||||
<a asp-action="Edit" asp-controller="Person" asp-route-Id="@person.PersonId">Editera</a>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
}
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
||||
|
||||
65
Views/Person/Search.cshtml
Normal file
@@ -0,0 +1,65 @@
|
||||
@model List<Person>
|
||||
@{
|
||||
ViewData["Title"] = "Sökresultat";
|
||||
}
|
||||
|
||||
<h2 class="text-center mt-3 mb-4">@ViewData["Title"]</h2>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<a href="/Person/Create" class="btn btn-success mb-5">Skapa ny medlem</a>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<form asp-action="Search" method="post">
|
||||
<div class="form-group">
|
||||
<label class="control-label">
|
||||
<input name="search" id="search" class="form-control" tabindex="1" placeholder="Namn eller E-post" />
|
||||
</label>
|
||||
<input type="submit" value="Sök" class="btn btn-primary" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container mb-5">
|
||||
@if (Model.Count() >= 0) {
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>Namn</th>
|
||||
<th>Epost</th>
|
||||
<th>Alder</th>
|
||||
<th>Registrerad</th>
|
||||
<th>Visningsbild</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var person in Model) {
|
||||
<tr>
|
||||
<td>@person.PersonId</td>
|
||||
<td>@person.PersonNamn</td>
|
||||
<td>@person.Epost</td>
|
||||
<td>@person.Alder</td>
|
||||
<td>@person.StartDatum</td>
|
||||
<td><img src="~/images/userphoto/@person.Visningsbild" alt="@person.PersonNamn" class="visningsbild" /></td>
|
||||
<td>
|
||||
<a asp-action="Delete" asp-controller="Person" asp-route-Id="@person.PersonId">Ta bort</a> |
|
||||
<a asp-action="Edit" asp-controller="Person" asp-route-Id="@person.PersonId">Editera</a>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
}
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
||||
|
||||
28
Views/PersonSport/Deroll.cshtml
Normal file
@@ -0,0 +1,28 @@
|
||||
@model List<Person>
|
||||
@{
|
||||
ViewData["Title"] = "Steg 1: Välj person";
|
||||
}
|
||||
|
||||
|
||||
<div class="container mb-5">
|
||||
<h2 class="text-center mt-3 mb-4">@ViewData["Title"]</h2>
|
||||
<form asp-action="DerollSport" method="post">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="input-group mb-3">
|
||||
<select name="PersonId" class="custom-select" tabindex="1">
|
||||
<option selected>Välj medlem</option>
|
||||
@foreach (var person in Model) {
|
||||
<option value="@person.PersonId">@person.PersonNamn</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary mt-3">Vidare till nästa steg</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
||||
30
Views/PersonSport/DerollSport.cshtml
Normal file
@@ -0,0 +1,30 @@
|
||||
@model List<Person>
|
||||
@{
|
||||
ViewData["Title"] = "...och vilken sport ska denne sluta med?";
|
||||
}
|
||||
|
||||
<div class="container mb-5">
|
||||
<h2 class="text-center mt-3 mb-4">@ViewData["Title"]</h2>
|
||||
|
||||
<form asp-action="DerollDone" method="post">
|
||||
<input type="hidden" name="PersonId" value="@ViewBag.PersonId" />
|
||||
<div class="col">
|
||||
<div class="input-group mb-3">
|
||||
<select name="SportId" class="custom-select" tabindex="1">
|
||||
<option selected>Välj sport</option>
|
||||
@foreach (var sport in ViewBag.SportForValdPerson) {
|
||||
<option value="@sport.SportId">@sport.SportNamn</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary mt-3">Avregistrera från aktivitet</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
||||
|
||||
|
||||
|
||||
40
Views/PersonSport/Enroll.cshtml
Normal file
@@ -0,0 +1,40 @@
|
||||
@model IEnumerable<Person>
|
||||
@{
|
||||
ViewData["Title"] = "Registrera medlem i aktivitet";
|
||||
}
|
||||
|
||||
<h2 class="text-center mt-3 mb-4">@ViewData["Title"]</h2>
|
||||
|
||||
<div class="container mb-5">
|
||||
<h4 class="mt-4 mb-4">Vem ska börja träna vad?</h4>
|
||||
|
||||
<form asp-action="Enroll" method="post">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="input-group mb-3">
|
||||
<select name="Namn" class="custom-select" tabindex="1">
|
||||
<option selected>Välj medlem</option>
|
||||
@foreach (var namn in ViewBag.personer) {
|
||||
<option value="@namn.PersonId">@namn.PersonNamn</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="input-group mb-3">
|
||||
<select name="Sport" class="custom-select" tabindex="2">
|
||||
<option selected>Välj sport</option>
|
||||
@foreach (var sport in ViewBag.sporter) {
|
||||
<option value="@sport.SportId">@sport.SportNamn</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary mt-3">@ViewData["Title"]</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
||||
57
Views/PersonSport/Index.cshtml
Normal file
@@ -0,0 +1,57 @@
|
||||
@{
|
||||
ViewData["Title"] = "Klicka på en sport för att se vilka som utövar den";
|
||||
}
|
||||
|
||||
<h2 class="text-center mt-3 mb-4">@ViewData["Title"]</h2>
|
||||
|
||||
@if (TempData.ContainsKey("MeddelandeSuccess")) {
|
||||
<div class="alert alert-success alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<strong>Allt klart!</strong> @TempData["MeddelandeSuccess"]
|
||||
</div>
|
||||
}
|
||||
else if (TempData.ContainsKey("MeddelandeFail")) {
|
||||
<div class="alert alert-danger alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<strong>Något gick fel.</strong> @TempData["MeddelandeFail"]
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="container mb-5">
|
||||
<div class="text-center mb-3">
|
||||
@foreach (var sp in ViewBag.AllaSporter) {
|
||||
<span class="btn btn-light text-black-50">
|
||||
@Html.ActionLink((string)sp.SportNamn, "Index", new { sportens_id = sp.SportId })
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
<h2 class="text-center">@ViewBag.SportNamn</h2>
|
||||
@if (ViewBag.PersonerIValdSport != null && ViewBag.PersonerIValdSport.Count >= 1) {
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr class="d-flex">
|
||||
<th class="col-2">Person-Id</th>
|
||||
<th class="col-6">Personens namn</th>
|
||||
<th class="col-4">Startade</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in ViewBag.PersonerIValdSport) {
|
||||
<tr class="d-flex">
|
||||
<td class="col-2">@item.PersonId</td>
|
||||
<td class="col-6">@item.PersonNamn</td>
|
||||
<td class="col-4">@item.StartDatum</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
else {
|
||||
<p class="lead text-center mt-5 mb-5">Det finns ingen som utövar det där...</p>
|
||||
}
|
||||
</div>
|
||||
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
||||
25
Views/Shared/Error.cshtml
Normal file
@@ -0,0 +1,25 @@
|
||||
@model ErrorViewModel
|
||||
@{
|
||||
ViewData["Title"] = "Error";
|
||||
}
|
||||
|
||||
<h1 class="text-danger">Error.</h1>
|
||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||
|
||||
@if (Model.ShowRequestId)
|
||||
{
|
||||
<p>
|
||||
<strong>Request ID:</strong> <code>@Model.RequestId</code>
|
||||
</p>
|
||||
}
|
||||
|
||||
<h3>Development Mode</h3>
|
||||
<p>
|
||||
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
|
||||
</p>
|
||||
<p>
|
||||
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
|
||||
It can result in displaying sensitive information from exceptions to end users.
|
||||
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
|
||||
and restarting the app.
|
||||
</p>
|
||||
28
Views/Shared/_Footer.cshtml
Normal file
@@ -0,0 +1,28 @@
|
||||
<div class="row myFooter pt-5 pb-5">
|
||||
<div class="col-sm">
|
||||
<h5>© 2021 - SportPalatset</h5>
|
||||
<p class="m-0">Storgatan 1</p>
|
||||
<p class="m-0">432 10 Staden</p>
|
||||
<p class="m-0">Tel. 0123-10 20 30</p>
|
||||
<p class="m-0">Fax. 0123-30 40 50</p>
|
||||
<p class="m-0"><a href="mailto:info@sportpalatset.se">info@sportpalatset.se</a></p>
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<h5>Länkar</h5>
|
||||
<a href="/Person/Create" class="mb-1">Bli medlem</a><br />
|
||||
<a href="/Sport/Utbud" class="mb-1">Utbudet</a><br />
|
||||
<a href="/Start/Priser" class="mb-1">Priser</a><br />
|
||||
<a href="/Start/Kurser" class="mb-1">Kurser</a><br />
|
||||
<a href="/Start/Receptionen" class="mb-1">Receptionen</a><br />
|
||||
<a href="/Start/Oppettider" class="mb-1">Öppettider</a><br />
|
||||
</div>
|
||||
<div class="col-sm social">
|
||||
<h5>Sociala medier</h5>
|
||||
<p class="m-1 mb-4">Hitta oss i våra kanaler! Vi lägger ut nya bilder hela tiden.</p>
|
||||
<i class="fab fa-facebook-square"></i>
|
||||
<i class="fab fa-twitter-square"></i>
|
||||
<i class="fab fa-instagram-square"></i>
|
||||
<i class="fab fa-tiktok"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
67
Views/Shared/_Layout.cshtml
Normal file
@@ -0,0 +1,67 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- Observera att detta är en skoluppgift och inte något -->
|
||||
<!-- som används på riktigt. -->
|
||||
<!-- Sidan är skapad för en kurs på Umeå Universitet av -->
|
||||
<!-- Christian Ohlsson 2021-10-10 -->
|
||||
<!-- -------------------------------------------------------- -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<!-- Lite meta-element för visning på vanliga webben -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="keywords" content="sport, palatset, sportpalatset, staden, yoga, karate, bandy" />
|
||||
<meta name="description" content="Här kan du träna på många olika sporter och delta i kurser." />
|
||||
@if (ViewBag.metaAbstract != null) {
|
||||
<meta name="abstract" content="@ViewBag.metaAbstract" />
|
||||
}
|
||||
@if (ViewBag.metaImage != null) {
|
||||
<meta name="image" content="@ViewBag.metaImage" />
|
||||
}
|
||||
<meta name="referrer" content="no-referrer">
|
||||
|
||||
<!-- Lite meta-element enligt Social Graph -->
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content="SportPalatset - Din träningsanläggning i Staden" />
|
||||
<meta property="og:description" content="Här kan du träna på många olika sporter och delta i kurser." />
|
||||
<meta property="og:url" content="https://sportpalatset.se/" />
|
||||
<meta property="og:site_name" content="SportPalatset" />
|
||||
<meta property="og:image" content="https://sportpalatset.se/images/Logo.png" />
|
||||
|
||||
<!-- Lite meta-element för Twitterläsare -->
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:creator" content="SportPalatset" />
|
||||
<meta name="twitter:image" content="https://sportpalatset.se/images/Logo.png" />
|
||||
<meta name="twitter:site" content="SportPalatset" />
|
||||
|
||||
<title>@ViewData["Title"] - PersonSport</title>
|
||||
<link rel='stylesheet' href='https://fonts.googleapis.com/css2?family=Raleway:wght@300&family=Oswald&display=swap'>
|
||||
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.css" />
|
||||
<link rel="stylesheet" href="~/css/site.css" />
|
||||
<link rel="stylesheet" href="~/css/crille.css" />
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-0">
|
||||
<partial name="_Menu" />
|
||||
</nav>
|
||||
</header>
|
||||
<div class="container">
|
||||
<main role="main" class="pb-3">
|
||||
@RenderBody()
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<footer class="border-top">
|
||||
<div class="container-fluid bg-dark">
|
||||
<div class="container">
|
||||
<partial name="_Footer" />
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<script src="~/lib/jquery/dist/jquery.min.js"></script>
|
||||
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="~/js/site.js" asp-append-version="true"></script>
|
||||
@await RenderSectionAsync("Scripts", required: false)
|
||||
</body>
|
||||
</html>
|
||||
54
Views/Shared/_Menu.cshtml
Normal file
@@ -0,0 +1,54 @@
|
||||
<div class="container">
|
||||
<a class="navbar-brand" asp-area="" asp-controller="Start" asp-action="Index">
|
||||
<img src="/images/Logo.png" height="80" alt="Logo" class="minLogotyp mr-1">
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
|
||||
aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
|
||||
<ul class="navbar-nav flex-grow-1">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-dark btn btn-light mr-2" asp-area="" asp-controller="Sport" asp-action="Utbud">Utbud</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-dark btn btn-light mr-2" asp-area="" asp-controller="Start" asp-action="Priser">Priser</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-dark btn btn-light mr-2" asp-area="" asp-controller="Start" asp-action="Kurser">Kurser</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-dark btn btn-light mr-2" asp-area="" asp-controller="Start" asp-action="Receptionen">Receptionen</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-dark btn btn-light mr-2" asp-area="" asp-controller="Start" asp-action="Oppettider">Öppettider</a>
|
||||
</li>
|
||||
</ul>
|
||||
@if (Context.User.Identity.IsAuthenticated) {
|
||||
<div class="dropdown show">
|
||||
<a class="btn bg-info dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Hantera
|
||||
</a>
|
||||
|
||||
<div class="dropdown-menu" aria-labelledby="dropdownMenuLink">
|
||||
<a class="dropdown-item" asp-area="" asp-controller="Person" asp-action="Index">Medlemmar</a>
|
||||
<a class="dropdown-item" asp-area="" asp-controller="Sport" asp-action="Index">Sporter</a>
|
||||
<a class="dropdown-item" asp-area="" asp-controller="PersonSport" asp-action="Enroll">Registrera träning</a>
|
||||
<a class="dropdown-item" asp-area="" asp-controller="PersonSport" asp-action="Deroll">Sluta träning</a>
|
||||
<a class="dropdown-item" asp-area="" asp-controller="PersonSport" asp-action="Index">Vem utövar vad</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" asp-area="" asp-controller="Login" asp-action="ShowAdmins">Administratörer</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" asp-area="" asp-controller="Login" asp-action="Logout">Logga ut</a>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else {
|
||||
<ul class="navbar-nav mr-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-dark btn btn-light" asp-area="" asp-controller="Login" asp-action="Index">Login</a>
|
||||
</li>
|
||||
</ul>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
2
Views/Shared/_ValidationScriptsPartial.cshtml
Normal file
@@ -0,0 +1,2 @@
|
||||
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
|
||||
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
|
||||
44
Views/Sport/Create.cshtml
Normal file
@@ -0,0 +1,44 @@
|
||||
@model Sport
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Lägg till sport";
|
||||
}
|
||||
|
||||
<div class="container mb-5">
|
||||
<h2 class="text-center mt-3 mb-4">@ViewData["Title"]</h2>
|
||||
|
||||
<form action="Create" method="post" enctype="multipart/form-data">
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.SportNamn" class="control-label"></label>
|
||||
<input type="text" class="form-control" asp-for="SportNamn" tabindex="1" placeholder="Sportens namn">
|
||||
<span asp-validation-for="SportNamn" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.Ingress" class="control-label"></label>
|
||||
<input type="text" class="form-control" asp-for="Ingress" tabindex="2" placeholder="Ingresstext">
|
||||
<span asp-validation-for="Ingress" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.DetaljText" class="control-label"></label>
|
||||
<textarea class="form-control" asp-for="DetaljText" tabindex="3" placeholder="Detaljerad text"></textarea>
|
||||
<span asp-validation-for="DetaljText" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.Traningstider" class="control-label"></label>
|
||||
<input type="text" class="form-control" asp-for="Traningstider" tabindex="4" placeholder="Träningstider">
|
||||
<span asp-validation-for="Traningstider" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.Bakgrundsbild" class="control-label"></label>
|
||||
<input type="file" class="form-control" asp-for="Bakgrundsbild" tabindex="5">
|
||||
<span asp-validation-for="Bakgrundsbild" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">Lägg till</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
||||
|
||||
27
Views/Sport/Details.cshtml
Normal file
@@ -0,0 +1,27 @@
|
||||
@model Sport
|
||||
@{
|
||||
ViewData["Title"] = "Mina Sporter";
|
||||
}
|
||||
|
||||
<div class="container mt-2 mb-5">
|
||||
<img src="~/images/sport/@Model.Bakgrundsbild" alt="@Model.SportNamn" class="img-fluid maxad mb-5" />
|
||||
<h2>@Model.SportNamn</h2>
|
||||
<p class="lead font-weight-bold">@Model.Ingress</p>
|
||||
<p>@Model.DetaljText</p>
|
||||
|
||||
<h2>Träningstider</h2>
|
||||
<p>@Model.Traningstider</p>
|
||||
|
||||
|
||||
@if (Context.User.Identity.IsAuthenticated) {
|
||||
<a href="/Sport" class="btn btn-success mt-3">Tillbaka till sporterna</a>
|
||||
}
|
||||
else {
|
||||
<a href="/Sport/Utbud" class="btn btn-success mt-3">Tillbaka till utbudet</a>
|
||||
}
|
||||
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
||||
40
Views/Sport/Edit.cshtml
Normal file
@@ -0,0 +1,40 @@
|
||||
@model Sport
|
||||
@{
|
||||
ViewData["Title"] = "Editera en Sport";
|
||||
}
|
||||
<h2 class="text-center mt-3 mb-4">@ViewData["Title"]</h2>
|
||||
|
||||
<form action="Edit" method="post" enctype="multipart/form-data">
|
||||
<input type="hidden" asp-for="SportId" value="@Model.SportId" />
|
||||
<div class="form-group">
|
||||
<label>SportNamn</label>
|
||||
<input type="text" class="form-control" asp-for="SportNamn" tabindex="1">
|
||||
<span asp-validation-for="SportNamn" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Ingress" class="control-label"></label>
|
||||
<input type="text" class="form-control" asp-for="Ingress" value="@Model.Ingress">
|
||||
<span asp-validation-for="Ingress" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="DetaljText" class="control-label"></label>
|
||||
<textarea class="form-control" asp-for="DetaljText" tabindex="2">@Model.DetaljText</textarea>
|
||||
<span asp-validation-for="DetaljText" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Traningstider" class="control-label"></label>
|
||||
<input type="text" class="form-control" asp-for="Traningstider" tabindex="3">
|
||||
<span asp-validation-for="Traningstider" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.Bakgrundsbild" class="control-label"></label>
|
||||
<input type="file" class="form-control" asp-for="Bakgrundsbild" tabindex="4">
|
||||
<span asp-validation-for="Bakgrundsbild" class="text-danger"></span>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Spara ändringar</button>
|
||||
</form>
|
||||
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
||||
58
Views/Sport/Index.cshtml
Normal file
@@ -0,0 +1,58 @@
|
||||
@model List<Sport>
|
||||
@{
|
||||
ViewData["Title"] = "Detta finns på SportPalatset";
|
||||
}
|
||||
<h2 class="text-center mt-3 mb-4">@ViewData["Title"]</h2>
|
||||
|
||||
<a href="/Sport/Create" class="btn btn-success mb-5">Skapa ny Sport</a>
|
||||
|
||||
@if (TempData.ContainsKey("MeddelandeSuccess")) {
|
||||
<div class="alert alert-success alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<strong>Allt klart!</strong> @TempData["MeddelandeSuccess"]
|
||||
</div>
|
||||
}
|
||||
else if (TempData.ContainsKey("MeddelandeFail")) {
|
||||
<div class="alert alert-danger alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<strong>Något gick fel.</strong> @TempData["MeddelandeFail"]
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="container">
|
||||
@if (Model.Count() >= 1) {
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>SportNamn</th>
|
||||
<th>Traningstider</th>
|
||||
<th>Bild</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var sport in Model) {
|
||||
<tr>
|
||||
<td>@sport.SportId</td>
|
||||
<td>@sport.SportNamn</td>
|
||||
<td>@sport.Traningstider</td>
|
||||
<td><img src="~/images/sport/@sport.Bakgrundsbild" alt="@sport.SportNamn" class="visningsbild" /></td>
|
||||
<td>
|
||||
<a asp-action="Delete" asp-controller="Sport" asp-route-Id="@sport.SportId">Ta bort</a> |
|
||||
<a asp-action="Edit" asp-controller="Sport" asp-route-Id="@sport.SportId">Editera</a> |
|
||||
<a asp-action="Details" asp-controller="Sport" asp-route-Id="@sport.SportId">Detaljer</a>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
}
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
||||
28
Views/Sport/Utbud.cshtml
Normal file
@@ -0,0 +1,28 @@
|
||||
@model List<Sport>
|
||||
@{
|
||||
ViewData["Title"] = "Detta finns på SportPalatset";
|
||||
}
|
||||
|
||||
<h2 class="text-center mt-3 mb-4">@ViewData["Title"]</h2>
|
||||
<p class="lead text-center font-weight-bold mt-1 mb-4">Hos oss hittar du allt för din träning. Det spelar ingen roll om du är elitsatsande eller motionär.</p>
|
||||
<div class="container">
|
||||
@foreach (var sport in Model) {
|
||||
<a href="/Sport/Details/@sport.SportId">
|
||||
<div class="col-sm mt-3">
|
||||
<div class="card bg-dark text-white">
|
||||
<img class="card-img" src="~/images/sport/@sport.Bakgrundsbild" alt="@sport.SportNamn">
|
||||
<div class="card-img-overlay myCard">
|
||||
<h3 class="card-title">@sport.SportNamn</h3>
|
||||
<p class="card-text mt-5">@sport.Ingress</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
|
||||
<p class="lead mt-5 mb-5 text-center font-weight-bold">Kom du ända hit utan att hitta något? Scrolla tillbaka så hittar du något kul för dig!</p>
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
||||
53
Views/Start/Index.cshtml
Normal file
@@ -0,0 +1,53 @@
|
||||
@{
|
||||
ViewData["Title"] = "Välkommen till SportPalatset";
|
||||
}
|
||||
|
||||
@if (TempData.ContainsKey("MeddelandeSuccess")) {
|
||||
<div class="alert alert-success alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<strong>Allt klart!</strong> @TempData["MeddelandeSuccess"]
|
||||
</div>
|
||||
}
|
||||
else if (TempData.ContainsKey("MeddelandeFail")) {
|
||||
<div class="alert alert-danger alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<strong>Något gick fel.</strong> @TempData["MeddelandeFail"]
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="container mb-5">
|
||||
<h2 class="text-center mt-3 mb-4">@ViewData["Title"]</h2>
|
||||
<p class="lead text-center">
|
||||
Vi har många olika sporthallar som ger dig precis den träning som du letar efter.
|
||||
Kom in till oss och låt ditt nya liv börja!
|
||||
</p>
|
||||
|
||||
<img src="~/images/arenan.jpg" alt="Arenan" class="maxad" />
|
||||
<a href="/Person/Create" class="registrera mb-5">Registrera gratis medlemskap</a>
|
||||
|
||||
<h4 class="mt-4">Vad är SportPalatset?</h4>
|
||||
<p class="lead font-weight-bold">
|
||||
Kul att du frågar! Jag ska berätta!
|
||||
</p>
|
||||
<p>
|
||||
SportPalatset är en kommunal träningsanläggning här i Staden. Vi erbjuder träning
|
||||
och friskvård till kommunens alla invånare; unga i kropp eller sinne!
|
||||
Vår kunniga personal hjälper dig gärna på vägen för att du skall nå precis
|
||||
så långt som du vill. Hos oss finns inga måsten, bara kul träning!
|
||||
</p>
|
||||
|
||||
<h4 class="mt-5">Vad kan jag träna hos er?</h4>
|
||||
<p>
|
||||
Vi har flera olika sporter och kurser som du kan vara med på. Registrera dig för ett
|
||||
gratis medlemsskap här ovanför så får du tillgång till vårt månadsbrev som kommer ut varje månad.
|
||||
Där får du tips om allt som händer hos oss och ibland med lite djupdykning på olika
|
||||
träningsformer. Vi kallar det för "Månadens fokusträning".
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
||||
|
||||
|
||||
80
Views/Start/Kurser.cshtml
Normal file
@@ -0,0 +1,80 @@
|
||||
@{
|
||||
ViewData["Title"] = "Häng med på våra kurser";
|
||||
}
|
||||
|
||||
<div class="container mb-5">
|
||||
<h2 class="text-center mt-3 mb-4">@ViewData["Title"]</h2>
|
||||
<p class="lead text-center font-weight-bold">Inte sugen på att börja träna något nytt, men vill gärna testa på? Vi har kursen för dig!</p>
|
||||
|
||||
<img src="~/images/kurser.jpg" alt="Arenan" class="maxad" />
|
||||
|
||||
<p class="lead text-center mt-5 mb-3">
|
||||
Våra kurser är fasta paket där du under några enstaka gånger i mindre grupper tränar för att lära dig mer.
|
||||
Efter en avslutad kurs kommer du att kunna stå på dina egna ben!
|
||||
</p>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm mt-3">
|
||||
<div class="card bg-dark text-white">
|
||||
<img class="card-img" src="/images/kampsport.jpg">
|
||||
<div class="card-img-overlay myKursCard">
|
||||
<h3 class="card-title text-uppercase">Kampsport</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm mt-3">
|
||||
<div class="card bg-dark text-white">
|
||||
<img class="card-img" src="/images/crossfit.jpg">
|
||||
<div class="card-img-overlay myKursCard">
|
||||
<h3 class="card-title text-uppercase">Crossfit</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm mt-3">
|
||||
<div class="card bg-dark text-white">
|
||||
<img class="card-img" src="/images/kids.jpg">
|
||||
<div class="card-img-overlay myKursCard">
|
||||
<h3 class="card-title text-uppercase">Funky Kidz</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm mt-3">
|
||||
<div class="card bg-dark text-white">
|
||||
<img class="card-img" src="/images/vardagsstark.jpg">
|
||||
<div class="card-img-overlay myKursCard">
|
||||
<h3 class="card-title text-uppercase">Vardagsstark</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm mt-3">
|
||||
<div class="card bg-dark text-white">
|
||||
<img class="card-img" src="/images/yoga.jpg">
|
||||
<div class="card-img-overlay myKursCard">
|
||||
<h3 class="card-title text-uppercase">Yoga</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm mt-3">
|
||||
<div class="card bg-dark text-white">
|
||||
<img class="card-img" src="/images/vikt.jpg">
|
||||
<div class="card-img-overlay myKursCard">
|
||||
<h3 class="card-title text-uppercase">Viktminskning</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<p class="lead text-center mt-5 mb-3 font-weight-bold">
|
||||
Blev du sugen på att testa på något? Hör av dig till receptionen för starttiden för kursen du gillade.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
||||
|
||||
141
Views/Start/Oppettider.cshtml
Normal file
@@ -0,0 +1,141 @@
|
||||
@{
|
||||
ViewData["Title"] = "Öppettider";
|
||||
}
|
||||
|
||||
<div class="container">
|
||||
<h2 class="text-center mt-3 mb-4">@ViewData["Title"]</h2>
|
||||
|
||||
<p class="lead text-center font-weight-bold">Om du har ett gymkort är det alltid öppet för dig. Andra öppettider kan du se nedan.</p>
|
||||
|
||||
<img src="~/images/oppettider.jpg" alt="Öppettider" class="maxad" />
|
||||
|
||||
|
||||
<h2 class="mt-5">Information om Coronaviruset</h2>
|
||||
<p class="lead">
|
||||
Vi följer Folkhälsomyndighetens rekommendationer och arbetar för att du ska kunna fortsätta att träna och
|
||||
bada i en frisk miljö. Det gör vi bland annat genom att öka städfrekvensen, anpassa våra aktiviteter samt informera
|
||||
dig som besöker oss om hur du kan hjälpa till att minska risken för smittspridning.
|
||||
</p>
|
||||
<p class="m-0"><i class="fas fa-check-square"></i>Följ skyltad hänvisning.</p>
|
||||
<p class="m-0"><i class="fas fa-check-square"></i>Håll avstånd till andra personer</p>
|
||||
<p class="m-0"><i class="fas fa-check-square"></i>Var extra noga med handhygien.</p>
|
||||
<p class="m-0"><i class="fas fa-check-square"></i>Torka av gymutrustning efter användning.</p>
|
||||
|
||||
<h3 class="mt-5">Öppettider för SportPalatset</h3>
|
||||
<p class="lead">
|
||||
Läs nedan för de olika sektionernas öppettider.
|
||||
Observera att på <span class="text-danger">röda dagar</span> gäller speciella öppettider.
|
||||
För dig med gymkort är det dock alltid öppet som vanligt.
|
||||
</p>
|
||||
|
||||
<h3>Kampsporthallen</h3>
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Veckodag</th>
|
||||
<th>Öppettider</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Måndag</td>
|
||||
<td>07.00 - 22.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Tisdag</td>
|
||||
<td>09.00 - 21.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Onsdag</td>
|
||||
<td>07.00 - 22.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Torsdag</td>
|
||||
<td>09.00 - 21.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Fredag</td>
|
||||
<td>07.00 - 22.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Lördag</td>
|
||||
<td>10.00 - 20.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Söndag</td>
|
||||
<td>10.00 - 20.00</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3>Yogasalen</h3>
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Veckodag</th>
|
||||
<th>Öppettider</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Måndag till Fredag</td>
|
||||
<td>16.00 - 22.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Lördag till Söndag</td>
|
||||
<td>06.00 - 19.00</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3>Stora hallen</h3>
|
||||
<p>Stora hallen har endast öppet för bokade tider. Hör av dig till receptionen om du vill boka Stora hallen.</p>
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Veckodag</th>
|
||||
<th>Öppettider</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Måndag</td>
|
||||
<td>09.00 - 20.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Tisdag</td>
|
||||
<td>09.00 - 20.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Onsdag</td>
|
||||
<td>09.00 - 20.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Torsdag</td>
|
||||
<td>09.00 - 20.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Fredag</td>
|
||||
<td>09.00 - 23.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Lördag</td>
|
||||
<td>07.00 - 23.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Söndag</td>
|
||||
<td>07.00 - 20.00</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p class="lead text-center mt-5 mb-5 font-weight-bold">
|
||||
För andra sporthallars öppettider: Kontakta receptionen.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
||||
|
||||
|
||||
159
Views/Start/Priser.cshtml
Normal file
@@ -0,0 +1,159 @@
|
||||
@{
|
||||
ViewData["Title"] = "Priser för kort och träningar";
|
||||
}
|
||||
<div class="container">
|
||||
<h2 class="text-center mt-3 mb-4">@ViewData["Title"]</h2>
|
||||
<p class="lead text-center font-weight-bold">Vi vet att det bara är på SportPalatset som du hittar en träning för just dig och din plånbok.</p>
|
||||
|
||||
<img src="~/images/priser.jpg" alt="Arenan" class="maxad" />
|
||||
|
||||
<p class="lead text-center mt-3">Vi har mycket bra priser som kommer att få dig att vilja komma lite oftare.</p>
|
||||
<p class="lead text-center">
|
||||
Vi ger dig de senaste och bästa träningsmöjligheterna, utbudet är näst intill obegränsat.
|
||||
Om du har funderingar eller vill boka tid för rådgivning kan du kontakta oss alla dagar i veckan 0123-10 20 30.
|
||||
</p>
|
||||
|
||||
<h3 class="mt-5">Träningskort för gym</h3>
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Korttyp</th>
|
||||
<th>Månadskostnad</th>
|
||||
<th>Årskort</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Maxade kortet</b><br />
|
||||
Gruppträning, styrketräning, konditionsträning. Wellness Online. Träna på alla klubbar. Kundkonto med 1000 kr i kredit (Gäller endast autogiro).
|
||||
</td>
|
||||
<td>449kr/mån</td>
|
||||
<td>5199kr</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Guldkortet</b><br />
|
||||
Styrketräning, konditionsträning. Träna på alla klubbar inom en region. Kundkonto med 1000 kr i kredit. (Gäller endast autogiro).
|
||||
</td>
|
||||
<td>399kr/mån</td>
|
||||
<td>4699kr</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Silverkortet</b><br />
|
||||
Styrketräning, konditionsträning. Träna på vald Family Fitness-klubb. Gästträna för 20 kr på annan valfri SportPalatset-klubb. Kundkonto med 1000 kr i kredit. (Gäller endast autogiro).
|
||||
</td>
|
||||
<td>349kr/mån</td>
|
||||
<td>4199kr</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Dagskortet</b><br />
|
||||
Tillgång till all träning vi erbjuder under en dag på valfri SportPalatset-klubb.
|
||||
</td>
|
||||
<td></td>
|
||||
<td>119kr</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<h3 class="mt-5">Kampsportskort</h3>
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Medlemskap</th>
|
||||
<th>Årskostnad</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Fighting Guld</b><br />
|
||||
Kortet ger dig tillträde på alla träningar i alla kampsporter på SportPalatset. Medlemsskapet är personligt.
|
||||
</td>
|
||||
<td>800kr/år</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Fighting Student</b><br />
|
||||
Kortet ger dig tillträde på alla träningar i alla kampsporter på SportPalatset. Medlemsskapet är personligt. Priset gäller vid uppvisande av giltigt Mecenat-kort.
|
||||
</td>
|
||||
<td>550kr/år</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Fighting Pensionär</b><br />
|
||||
Kortet ger dig tillträde på alla träningar i alla kampsporter på SportPalatset. Medlemsskapet är personligt och kräver att du visar legitimation och har fyllt 65år.
|
||||
</td>
|
||||
<td>550kr/år</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
<h3 class="mt-5">Seniorkort Zumba</h3>
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Medlemsskap</th>
|
||||
<th>Pris</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Zumba för old-timers</b><br />
|
||||
Träna exotisk dans med Zumba-inslag för dig över 65. Alla pass anpassas vi att alla kan vara med oavsett vilken nivå du startar från.
|
||||
</td>
|
||||
<td>1499kr/år</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
<h3 class="mt-5">Innebandykortet</h3>
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Medlemsskap</th>
|
||||
<th>Pris</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Kullerbyttan</b><br />
|
||||
Kortet som ger dig mellan 2år och 7år tillgång till alla träningar i vår innebandyhall. Naturligtvis finns tränare på plats.
|
||||
</td>
|
||||
<td>699kr/år</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Ungdomsmedlemskap</b><br />
|
||||
Kortet som ger dig mellan 8år och 14år tillgång till alla träningar i vår innebandyhall. Mobilladdare och WiFi finns, så detta blir som hemma för dig.
|
||||
</td>
|
||||
<td>1099kr/år</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Going for Pro</b><br />
|
||||
Detta är innebandy-kortet för dig som vill satsa lite extra på din innebandy. I detta kort har vi inga mobilladdare och håller WiFi avstängt för att ge dig en så koncentrerad form av innebandyträning som möjligt.
|
||||
</td>
|
||||
<td>1499kr/år</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<p class=" text-center lead mt-5 mb-5 font-weight-bold">För andra priser kontakta din tränare eller receptionen</p>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
||||
|
||||
|
||||
53
Views/Start/Receptionen.cshtml
Normal file
@@ -0,0 +1,53 @@
|
||||
@model MailViewModel
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Receptionen";
|
||||
}
|
||||
|
||||
<div class="container mb-5">
|
||||
<h2 class="text-center mt-3 mb-4">@ViewData["Title"]</h2>
|
||||
|
||||
<p class="lead text-center font-weight-bold">Vad kan vi hjälpa till med? Receptionen på SportPalatset är bemannad alla dagar 6.30-23.00</p>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<img src="~/images/map.jpg" alt="Hitta hit" />
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4 class="text-dark">Du hittar oss här</h4>
|
||||
<p class="m-1">Storgatan 1</p>
|
||||
<p class="m-1">432 10 Staden</p>
|
||||
<p class="m-1">Tel. 0123-10 20 30</p>
|
||||
<p class="m-1">Fax. 0123-30 40 50</p>
|
||||
<p class="m-1">info@sportpalatset.se</p>
|
||||
|
||||
<form action="SendMail" method="post">
|
||||
<fieldset class="form-group mt-4">
|
||||
<legend class="mt-3 font-weight-bold">Maila till oss</legend>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.Epost" class="control-label"></label>
|
||||
<input type="text" class="form-control" asp-for="Epost" tabindex="1" placeholder="Din e-postadress">
|
||||
<span asp-validation-for="Epost" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.Subject" class="control-label"></label>
|
||||
<input type="text" class="form-control" asp-for="Subject" tabindex="2" placeholder="Ärende">
|
||||
<span asp-validation-for="Subject" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="@Model.Message" class="control-label"></label>
|
||||
<textarea name="Message" class="form-control" asp-for="Message" tabindex="3" placeholder="Meddelande"></textarea>
|
||||
<span asp-validation-for="Message" class="text-danger"></span>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Skicka mail</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
}
|
||||
3
Views/_ViewImports.cshtml
Normal file
@@ -0,0 +1,3 @@
|
||||
@using PersonSport
|
||||
@using PersonSport.Models
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
3
Views/_ViewStart.cshtml
Normal file
@@ -0,0 +1,3 @@
|
||||
@{
|
||||
Layout = "_Layout";
|
||||
}
|
||||
10
appsettings.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
BIN
wwwroot/LogoOrginal.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
124
wwwroot/css/crille.css
Normal file
@@ -0,0 +1,124 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@300&family=Oswald&display=swap');
|
||||
|
||||
:root {
|
||||
--LogoMainColor: #f6be00;
|
||||
--LogoSecondColor: #4f3e07;
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
font-family: "Open Sans", sans-serif;
|
||||
margin-bottom: 0;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: Oswald, sans-serif;
|
||||
color: var(--LogoMainColor) !important;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.1rem
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 2.7rem
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 2.3rem
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 2rem
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 120%;
|
||||
}
|
||||
|
||||
.visningsbild {
|
||||
width: 70px !important;
|
||||
height: 70px !important;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.maxad {
|
||||
width: 100%;
|
||||
}
|
||||
.minLogotyp {
|
||||
transition: transform .2s
|
||||
}
|
||||
|
||||
.minLogotyp:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.myLoginForm {
|
||||
width: 20rem;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.registrera {
|
||||
background-color: var(--LogoMainColor);
|
||||
color: var(--LogoSecondColor);
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
padding: 2rem 0;
|
||||
font-size: 2rem;
|
||||
font-weight: bold;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.registrera:hover {
|
||||
background-color: var(--LogoSecondColor);
|
||||
color: var(--LogoMainColor);
|
||||
}
|
||||
|
||||
.myCard .card-title {
|
||||
font-size: 9rem;
|
||||
text-shadow: 4px 4px 2px #111, -4px -4px 2px #111, -4px 4px 2px #111, 4px -4px 2px #111;
|
||||
}
|
||||
|
||||
.myCard .card-text {
|
||||
font-size: 2.2rem;
|
||||
text-shadow: 3px 3px 3px #111, -3px -3px 3px #111, -3px 3px 3px #111, 3px -3px 3px #111;
|
||||
}
|
||||
|
||||
.myFooter {
|
||||
color: var(--LogoMainColor);
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
.myFooter a,
|
||||
.myFooter a:visited {
|
||||
color: var(--LogoMainColor);
|
||||
text-decoration: underline;
|
||||
font-size: 120%;
|
||||
}
|
||||
|
||||
.myFooter a:hover {
|
||||
background-color: var(--LogoSecondColor);
|
||||
}
|
||||
|
||||
.social i {
|
||||
font-size: 3rem;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.myKursCard {
|
||||
text-align: center;
|
||||
margin-top: 40%;
|
||||
text-shadow: 2px 2px 2px #111, -2px -2px 2px #111, -2px 2px 2px #111, 2px -2px 2px #111;
|
||||
}
|
||||
|
||||
.fa-check-square {
|
||||
color: var(--LogoSecondColor);
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.alert {
|
||||
left: 15%;
|
||||
width: 70%;
|
||||
}
|
||||
71
wwwroot/css/site.css
Normal file
@@ -0,0 +1,71 @@
|
||||
/* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
|
||||
for details on configuring this project to bundle and minify static web assets. */
|
||||
|
||||
a.navbar-brand {
|
||||
white-space: normal;
|
||||
text-align: center;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
/* Provide sufficient contrast against white background */
|
||||
a {
|
||||
color: #0366d6;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
color: #fff;
|
||||
background-color: #1b6ec2;
|
||||
border-color: #1861ac;
|
||||
}
|
||||
|
||||
.nav-pills .nav-link.active, .nav-pills .show > .nav-link {
|
||||
color: #fff;
|
||||
background-color: #1b6ec2;
|
||||
border-color: #1861ac;
|
||||
}
|
||||
|
||||
/* Sticky footer styles
|
||||
-------------------------------------------------- */
|
||||
html {
|
||||
font-size: 14px;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
html {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.border-top {
|
||||
border-top: 1px solid #e5e5e5;
|
||||
}
|
||||
.border-bottom {
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.box-shadow {
|
||||
box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
|
||||
}
|
||||
|
||||
button.accept-policy {
|
||||
font-size: 1rem;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
/* Sticky footer styles
|
||||
-------------------------------------------------- */
|
||||
html {
|
||||
position: relative;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
/* Margin bottom by footer height */
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
.footer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
line-height: 60px; /* Vertically center the text there */
|
||||
}
|
||||
BIN
wwwroot/favicon.ico
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
wwwroot/images/Logo.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
wwwroot/images/arenan.jpg
Normal file
|
After Width: | Height: | Size: 87 KiB |
BIN
wwwroot/images/crossfit.jpg
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
wwwroot/images/kampsport.jpg
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
wwwroot/images/kids.jpg
Normal file
|
After Width: | Height: | Size: 57 KiB |
BIN
wwwroot/images/kurser.jpg
Normal file
|
After Width: | Height: | Size: 102 KiB |
BIN
wwwroot/images/map.jpg
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
wwwroot/images/oppettider.jpg
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
wwwroot/images/priser.jpg
Normal file
|
After Width: | Height: | Size: 238 KiB |
BIN
wwwroot/images/sport/0672416102.jpg
Normal file
|
After Width: | Height: | Size: 98 KiB |
BIN
wwwroot/images/sport/1244035394.jpg
Normal file
|
After Width: | Height: | Size: 117 KiB |
BIN
wwwroot/images/sport/1408016154.jpg
Normal file
|
After Width: | Height: | Size: 325 KiB |
BIN
wwwroot/images/sport/3000166147.jpg
Normal file
|
After Width: | Height: | Size: 176 KiB |
BIN
wwwroot/images/sport/7609145953.jpg
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
wwwroot/images/sport/9128728540.jpg
Normal file
|
After Width: | Height: | Size: 149 KiB |
BIN
wwwroot/images/sport/9657996380.jpg
Normal file
|
After Width: | Height: | Size: 185 KiB |
BIN
wwwroot/images/sport/nosport.jpg
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
wwwroot/images/userphoto/2557162065.jpg
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
wwwroot/images/userphoto/3084318669.jpg
Normal file
|
After Width: | Height: | Size: 93 KiB |
BIN
wwwroot/images/userphoto/3462294956.jpg
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
BIN
wwwroot/images/userphoto/3699262999.jpg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
wwwroot/images/userphoto/4073068709.jpg
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
BIN
wwwroot/images/userphoto/4396324834.jpg
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
wwwroot/images/userphoto/4692567562.jpg
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
BIN
wwwroot/images/userphoto/4966463767.jpg
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
BIN
wwwroot/images/userphoto/5299504725.jpg
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
wwwroot/images/userphoto/5596019725.jpg
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
wwwroot/images/userphoto/5926666956.jpg
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
BIN
wwwroot/images/userphoto/noimage.jpg
Normal file
|
After Width: | Height: | Size: 7.9 KiB |
BIN
wwwroot/images/vardagsstark.jpg
Normal file
|
After Width: | Height: | Size: 68 KiB |
BIN
wwwroot/images/vikt.jpg
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
wwwroot/images/yoga.jpg
Normal file
|
After Width: | Height: | Size: 62 KiB |
4
wwwroot/js/site.js
Normal file
@@ -0,0 +1,4 @@
|
||||
// Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
|
||||
// for details on configuring this project to bundle and minify static web assets.
|
||||
|
||||
// Write your JavaScript code.
|
||||