Showing preview only (895K chars total). Download the full file or copy to clipboard to get everything.
Repository: teddysmithdev/RunGroop
Branch: master
Commit: 3695f75527d0
Files: 119
Total size: 850.3 KB
Directory structure:
gitextract_r3gp682_/
├── .gitignore
├── README.md
├── RunGroopWebApp/
│ ├── ClaimsPrincipalExtensions.cs
│ ├── Controllers/
│ │ ├── AccountController.cs
│ │ ├── ClubController.cs
│ │ ├── DashboardController.cs
│ │ ├── HomeController.cs
│ │ ├── RaceController.cs
│ │ └── UserController.cs
│ ├── Data/
│ │ ├── ApplicationDbContext.cs
│ │ ├── Enum/
│ │ │ ├── ClubCategory.cs
│ │ │ └── RaceCategory.cs
│ │ ├── Seed.cs
│ │ └── UserRoles.cs
│ ├── Extensions/
│ │ ├── NumberExtensions.cs
│ │ └── StringExtensions.cs
│ ├── Helpers/
│ │ ├── CloudinarySettings.cs
│ │ ├── IPInfo.cs
│ │ ├── Location.cs
│ │ └── StateConverter.cs
│ ├── Interfaces/
│ │ ├── IClubRepository.cs
│ │ ├── IDashboardRepository.cs
│ │ ├── ILocationService.cs
│ │ ├── IPhotoService.cs
│ │ ├── IRaceRepository.cs
│ │ └── IUserRepository.cs
│ ├── Migrations/
│ │ ├── 20220215112438_InitialCreate.Designer.cs
│ │ ├── 20220215112438_InitialCreate.cs
│ │ └── ApplicationDbContextModelSnapshot.cs
│ ├── Models/
│ │ ├── Address.cs
│ │ ├── AppUser.cs
│ │ ├── City.cs
│ │ ├── Club.cs
│ │ ├── ErrorViewModel.cs
│ │ ├── Race.cs
│ │ └── State.cs
│ ├── Program.cs
│ ├── Properties/
│ │ └── launchSettings.json
│ ├── Repository/
│ │ ├── ClubRepository.cs
│ │ ├── DashboardRepository.cs
│ │ ├── RaceRepository.cs
│ │ └── UserRepository.cs
│ ├── RunGroopWebApp.csproj
│ ├── Services/
│ │ ├── LocationService.cs
│ │ └── PhotoService.cs
│ ├── ViewModels/
│ │ ├── CreateClubViewModel.cs
│ │ ├── CreateRaceViewModel.cs
│ │ ├── DashboardViewModel.cs
│ │ ├── EditClubViewModel.cs
│ │ ├── EditProfileViewModel.cs
│ │ ├── EditRaceViewModel.cs
│ │ ├── HomeUserCreateViewModel.cs
│ │ ├── HomeViewModel.cs
│ │ ├── IndexClubViewModel.cs
│ │ ├── IndexRaceViewModel.cs
│ │ ├── ListClubByCityViewModel.cs
│ │ ├── ListClubByStateViewModel.cs
│ │ ├── LoginViewModel.cs
│ │ ├── RegisterViewModel.cs
│ │ ├── RunningClubByCity.cs
│ │ ├── RunningClubByState.cs
│ │ ├── UserDetailViewModel.cs
│ │ ├── UserViewModel.cs
│ │ └── WelcomeViewModel.cs
│ ├── Views/
│ │ ├── Account/
│ │ │ ├── Login.cshtml
│ │ │ ├── Register.cshtml
│ │ │ └── Welcome.cshtml
│ │ ├── Club/
│ │ │ ├── Create.cshtml
│ │ │ ├── Delete.cshtml
│ │ │ ├── DetailClub.cshtml
│ │ │ ├── Edit.cshtml
│ │ │ ├── Index.cshtml
│ │ │ ├── ListClubsByCity.cshtml
│ │ │ ├── ListClubsByState.cshtml
│ │ │ ├── RunningClubsByCityDirectory.cshtml
│ │ │ ├── RunningClubsByStateDirectory.cshtml
│ │ │ └── RunningClubsByStateForCityDirectory.cshtml
│ │ ├── Dashboard/
│ │ │ └── Index.cshtml
│ │ ├── Home/
│ │ │ ├── Index.cshtml
│ │ │ ├── Privacy.cshtml
│ │ │ └── Register.cshtml
│ │ ├── Race/
│ │ │ ├── Create.cshtml
│ │ │ ├── Delete.cshtml
│ │ │ ├── DetailRace.cshtml
│ │ │ ├── Edit.cshtml
│ │ │ └── Index.cshtml
│ │ ├── Shared/
│ │ │ ├── Error.cshtml
│ │ │ ├── _Layout.cshtml
│ │ │ ├── _Layout.cshtml.css
│ │ │ └── _ValidationScriptsPartial.cshtml
│ │ ├── User/
│ │ │ ├── Detail.cshtml
│ │ │ ├── EditProfile.cshtml
│ │ │ └── Index.cshtml
│ │ ├── _ViewImports.cshtml
│ │ └── _ViewStart.cshtml
│ ├── appsettings.Development.json
│ ├── appsettings.json
│ └── wwwroot/
│ ├── css/
│ │ ├── custom.css
│ │ ├── entypo.css
│ │ ├── socicon.css
│ │ └── theme.css
│ └── js/
│ ├── aos.js
│ ├── bootstrap.js
│ ├── custom.js
│ ├── flickity.pkgd.js
│ ├── prism.js
│ ├── scrollMonitor.js
│ └── theme.js
├── RunGroopWebApp.Scraper/
│ ├── Data/
│ │ └── ScraperDBContext.cs
│ ├── Extensions/
│ │ └── DateTimeExtension.cs
│ ├── Interfaces/
│ │ └── IAtraScraper.cs
│ ├── Program.cs
│ ├── RunGroopWebApp.Scraper.csproj
│ └── Services/
│ ├── AtraScraper.cs
│ └── MeetupScraper.cs
├── RunGroopWebApp.Tests/
│ ├── Controller/
│ │ └── ClubControllerTests.cs
│ ├── Repository/
│ │ └── ClubRepositoryTests.cs
│ └── RunGroopWebApp.Tests.csproj
└── RunGroopWebApp.sln
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.tlog
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
*.vbp
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
*.dsw
*.dsp
# Visual Studio 6 technical files
*.ncb
*.aps
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# Visual Studio History (VSHistory) files
.vshistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
# VS Code files for those working on multiple tools
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
# Windows Installer files from build outputs
*.cab
*.msi
*.msix
*.msm
*.msp
# JetBrains Rider
*.sln.iml
================================================
FILE: README.md
================================================
# RunGroops
Rungroops is an online platform for runners. This platform will help you to find clubs, schedule events, and meet other runners in your area.
<kbd></kbd>
## 🏃 Getting Started
[Youtube video on how to get database setup](https://www.youtube.com/watch?v=af_tK9LUiX0)
1. Go into directory where you plan on keeping project and run.
```bash
git fork https://github.com/teddysmithdev/RunGroop.git
```
2. Create a local database. (If you are unsure how to do this, watch my Youtube video )
3. Add connection string to app settings.json. It will look something like this:
```bash
Data Source=DESKTOP-EI2TOGP\\SQLEXPRESS;Initial Catalog=RunGroops;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False
```
4. Register for a [Cloudinary Account](https://cloudinary.com/users/register/free) (%100 free) and add Cloudname, ApiKey, and Api secret to appsettings.json.
================================================
FILE: RunGroopWebApp/ClaimsPrincipalExtensions.cs
================================================
using System.Security.Claims;
namespace RunGroopWebApp
{
public static class ClaimsPrincipalExtensions
{
public static string GetUserId(this ClaimsPrincipal user)
{
return user.FindFirst(ClaimTypes.NameIdentifier).Value;
}
}
}
================================================
FILE: RunGroopWebApp/Controllers/AccountController.cs
================================================
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using RunGroopWebApp.Data;
using RunGroopWebApp.Interfaces;
using RunGroopWebApp.Models;
using RunGroopWebApp.ViewModels;
namespace RunGroopWebApp.Controllers
{
public class AccountController : Controller
{
private readonly UserManager<AppUser> _userManager;
private readonly SignInManager<AppUser> _signInManager;
private readonly ApplicationDbContext _context;
private readonly ILocationService _locationService;
public AccountController(UserManager<AppUser> userManager,
SignInManager<AppUser> signInManager,
ApplicationDbContext context,
ILocationService locationService)
{
_context = context;
_locationService = locationService;
_signInManager = signInManager;
_userManager = userManager;
}
[HttpGet]
public IActionResult Login()
{
var response = new LoginViewModel();
return View(response);
}
[HttpPost]
public async Task<IActionResult> Login(LoginViewModel loginViewModel)
{
if (!ModelState.IsValid) return View(loginViewModel);
var user = await _userManager.FindByEmailAsync(loginViewModel.EmailAddress);
if (user != null)
{
//User is found, check password
var passwordCheck = await _userManager.CheckPasswordAsync(user, loginViewModel.Password);
if (passwordCheck)
{
//Password correct, sign in
var result = await _signInManager.PasswordSignInAsync(user, loginViewModel.Password, false, false);
if (result.Succeeded)
{
return RedirectToAction("Index", "Race");
}
}
//Password is incorrect
TempData["Error"] = "Wrong credentials. Please try again";
return View(loginViewModel);
}
//User not found
TempData["Error"] = "Wrong credentials. Please try again";
return View(loginViewModel);
}
[HttpGet]
public IActionResult Register()
{
var response = new RegisterViewModel();
return View(response);
}
[HttpPost]
public async Task<IActionResult> Register(RegisterViewModel registerViewModel)
{
if (!ModelState.IsValid) return View(registerViewModel);
var user = await _userManager.FindByEmailAsync(registerViewModel.EmailAddress);
if (user != null)
{
TempData["Error"] = "This email address is already in use";
return View(registerViewModel);
}
var newUser = new AppUser()
{
Email = registerViewModel.EmailAddress,
UserName = registerViewModel.EmailAddress
};
var newUserResponse = await _userManager.CreateAsync(newUser, registerViewModel.Password);
if (newUserResponse.Succeeded)
await _userManager.AddToRoleAsync(newUser, UserRoles.User);
return RedirectToAction("Index", "Race");
}
[HttpGet]
public async Task<IActionResult> Logout()
{
await _signInManager.SignOutAsync();
return RedirectToAction("Index", "Race");
}
[HttpGet]
[Route("Account/Welcome")]
public async Task<IActionResult> Welcome(int page = 0)
{
if(page == 0)
{
return View();
}
return View();
}
[HttpGet]
public async Task<IActionResult> GetLocation(string location)
{
if(location == null)
{
return Json("Not found");
}
var locationResult = await _locationService.GetLocationSearch(location);
return Json(locationResult);
}
}
}
================================================
FILE: RunGroopWebApp/Controllers/ClubController.cs
================================================
using Microsoft.AspNetCore.Mvc;
using RunGroopWebApp.Data.Enum;
using RunGroopWebApp.Helpers;
using RunGroopWebApp.Interfaces;
using RunGroopWebApp.Models;
using RunGroopWebApp.ViewModels;
namespace RunGroopWebApp.Controllers
{
public class ClubController : Controller
{
private readonly IClubRepository _clubRepository;
private readonly IPhotoService _photoService;
public ClubController(IClubRepository clubRepository, IPhotoService photoService)
{
_clubRepository = clubRepository;
_photoService = photoService;
}
[HttpGet]
[Route("RunningClubs")]
public async Task<IActionResult> Index(int category = -1, int page = 1, int pageSize = 6)
{
if (page < 1 || pageSize < 1)
{
return NotFound();
}
// if category is -1 (All) dont filter else filter by selected category
var clubs = category switch
{
-1 => await _clubRepository.GetSliceAsync((page - 1) * pageSize, pageSize),
_ => await _clubRepository.GetClubsByCategoryAndSliceAsync((ClubCategory)category, (page - 1) * pageSize, pageSize),
};
var count = category switch
{
-1 => await _clubRepository.GetCountAsync(),
_ => await _clubRepository.GetCountByCategoryAsync((ClubCategory)category),
};
var clubViewModel = new IndexClubViewModel
{
Clubs = clubs,
Page = page,
PageSize = pageSize,
TotalClubs = count,
TotalPages = (int)Math.Ceiling(count / (double)pageSize),
Category = category,
};
return View(clubViewModel);
}
[HttpGet]
[Route("RunningClubs/{state}")]
public async Task<IActionResult> ListClubsByState(string state)
{
var clubs = await _clubRepository.GetClubsByState(StateConverter.GetStateByName(state).ToString());
var clubVM = new ListClubByStateViewModel()
{
Clubs = clubs
};
if (clubs.Count() == 0)
{
clubVM.NoClubWarning = true;
}
else
{
clubVM.State = state;
}
return View(clubVM);
}
[HttpGet]
[Route("RunningClubs/{city}/{state}")]
public async Task<IActionResult> ListClubsByCity(string city, string state)
{
var clubs = await _clubRepository.GetClubByCity(city);
var clubVM = new ListClubByCityViewModel()
{
Clubs = clubs
};
if (clubs.Count() == 0)
{
clubVM.NoClubWarning = true;
}
else
{
clubVM.State = state;
clubVM.City = city;
}
return View(clubVM);
}
[HttpGet]
[Route("club/{runningClub}/{id}")]
public async Task<IActionResult> DetailClub(int id, string runningClub)
{
var club = await _clubRepository.GetByIdAsync(id);
return club == null ? NotFound() : View(club);
}
[HttpGet]
[Route("RunningClubs/State")]
public async Task<IActionResult> RunningClubsByStateDirectory()
{
var states = await _clubRepository.GetAllStates();
var clubVM = new RunningClubByState()
{
States = states
};
return states == null ? NotFound() : View(clubVM);
}
[HttpGet]
[Route("RunningClubs/State/City")]
public async Task<IActionResult> RunningClubsByStateForCityDirectory()
{
var states = await _clubRepository.GetAllStates();
var clubVM = new RunningClubByState()
{
States = states
};
return states == null ? NotFound() : View(clubVM);
}
[HttpGet]
[Route("RunningClubs/{state}/City")]
public async Task<IActionResult> RunningClubsByCityDirectory(string state)
{
var cities = await _clubRepository.GetAllCitiesByState(StateConverter.GetStateByName(state).ToString());
var clubVM = new RunningClubByCity()
{
Cities = cities
};
return cities == null ? NotFound() : View(clubVM);
}
[HttpGet]
public IActionResult Create()
{
var curUserId = HttpContext.User.GetUserId();
var createClubViewModel = new CreateClubViewModel { AppUserId = curUserId };
return View(createClubViewModel);
}
[HttpPost]
public async Task<IActionResult> Create(CreateClubViewModel clubVM)
{
if (ModelState.IsValid)
{
var result = await _photoService.AddPhotoAsync(clubVM.Image);
var club = new Club
{
Title = clubVM.Title,
Description = clubVM.Description,
Image = result.Url.ToString(),
ClubCategory = clubVM.ClubCategory,
AppUserId = clubVM.AppUserId,
Address = new Address
{
Street = clubVM.Address.Street,
City = clubVM.Address.City,
State = clubVM.Address.State,
}
};
_clubRepository.Add(club);
return RedirectToAction("Index");
}
else
{
ModelState.AddModelError("", "Photo upload failed");
}
return View(clubVM);
}
[HttpGet]
public async Task<IActionResult> Edit(int id)
{
var club = await _clubRepository.GetByIdAsync(id);
if (club == null) return View("Error");
var clubVM = new EditClubViewModel
{
Title = club.Title,
Description = club.Description,
AddressId = club.AddressId,
Address = club.Address,
URL = club.Image,
ClubCategory = club.ClubCategory
};
return View(clubVM);
}
[HttpPost]
public async Task<IActionResult> Edit(int id, EditClubViewModel clubVM)
{
if (!ModelState.IsValid)
{
ModelState.AddModelError("", "Failed to edit club");
return View("Edit", clubVM);
}
var userClub = await _clubRepository.GetByIdAsyncNoTracking(id);
if (userClub == null)
{
return View("Error");
}
var photoResult = await _photoService.AddPhotoAsync(clubVM.Image);
if (photoResult.Error != null)
{
ModelState.AddModelError("Image", "Photo upload failed");
return View(clubVM);
}
if (!string.IsNullOrEmpty(userClub.Image))
{
_ = _photoService.DeletePhotoAsync(userClub.Image);
}
var club = new Club
{
Id = id,
Title = clubVM.Title,
Description = clubVM.Description,
Image = photoResult.Url.ToString(),
AddressId = clubVM.AddressId,
Address = clubVM.Address,
};
_clubRepository.Update(club);
return RedirectToAction("Index");
}
[HttpGet]
public async Task<IActionResult> Delete(int id)
{
var clubDetails = await _clubRepository.GetByIdAsync(id);
if (clubDetails == null) return View("Error");
return View(clubDetails);
}
[HttpPost, ActionName("Delete")]
public async Task<IActionResult> DeleteClub(int id)
{
var clubDetails = await _clubRepository.GetByIdAsync(id);
if (clubDetails == null)
{
return View("Error");
}
if (!string.IsNullOrEmpty(clubDetails.Image))
{
_ = _photoService.DeletePhotoAsync(clubDetails.Image);
}
_clubRepository.Delete(clubDetails);
return RedirectToAction("Index");
}
}
}
================================================
FILE: RunGroopWebApp/Controllers/DashboardController.cs
================================================
using CloudinaryDotNet.Actions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using RunGroopWebApp.Interfaces;
using RunGroopWebApp.Models;
using RunGroopWebApp.ViewModels;
namespace RunGroopWebApp.Controllers
{
[Authorize]
public class DashboardController : Controller
{
private readonly IDashboardRepository _dashboardRespository;
private readonly IPhotoService _photoService;
public DashboardController(IDashboardRepository dashboardRespository, IPhotoService photoService)
{
_dashboardRespository = dashboardRespository;
_photoService = photoService;
}
public async Task<IActionResult> Index()
{
var userRaces = await _dashboardRespository.GetAllUserRaces();
var userClubs = await _dashboardRespository.GetAllUserClubs();
var dashboardViewModel = new DashboardViewModel()
{
Races = userRaces,
Clubs = userClubs
};
return View(dashboardViewModel);
}
}
}
================================================
FILE: RunGroopWebApp/Controllers/HomeController.cs
================================================
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using RunGroopWebApp.Data;
using RunGroopWebApp.Helpers;
using RunGroopWebApp.Interfaces;
using RunGroopWebApp.Models;
using RunGroopWebApp.ViewModels;
using System.Diagnostics;
using System.Globalization;
using System.Net;
namespace RunGroopWebApp.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IClubRepository _clubRepository;
private readonly UserManager<AppUser> _userManager;
private readonly SignInManager<AppUser> _signInManager;
private readonly ILocationService _locationService;
private readonly IConfiguration _config;
public HomeController(ILogger<HomeController> logger, IClubRepository clubRepository,
UserManager<AppUser> userManager, SignInManager<AppUser> signInManager, ILocationService locationService, IConfiguration config)
{
_logger = logger;
_clubRepository = clubRepository;
_userManager = userManager;
_signInManager = signInManager;
_locationService = locationService;
_config = config;
}
public async Task<IActionResult> Index()
{
var ipInfo = new IPInfo();
var homeViewModel = new HomeViewModel();
try
{
string url = "https://ipinfo.io?token=" + _config.GetValue<string>("IPInfoToken");
var info = new WebClient().DownloadString(url);
ipInfo = JsonConvert.DeserializeObject<IPInfo>(info);
RegionInfo myRI1 = new RegionInfo(ipInfo.Country);
ipInfo.Country = myRI1.EnglishName;
homeViewModel.City = ipInfo.City;
homeViewModel.State = ipInfo.Region;
if (homeViewModel.City != null)
{
homeViewModel.Clubs = await _clubRepository.GetClubByCity(homeViewModel.City);
}
return View(homeViewModel);
}
catch (Exception)
{
homeViewModel.Clubs = null;
}
return View(homeViewModel);
}
public IActionResult Register()
{
var response = new HomeUserCreateViewModel();
return View(response);
}
[HttpPost]
public async Task<IActionResult> Index(HomeViewModel homeVM)
{
var createVM = homeVM.Register;
if (!ModelState.IsValid) return View(homeVM);
var user = await _userManager.FindByEmailAsync(createVM.Email);
if (user != null)
{
ModelState.AddModelError("Register.Email", "This email address is already in use");
return View(homeVM);
}
var userLocation = await _locationService.GetCityByZipCode(createVM.ZipCode ?? 0);
if (userLocation == null)
{
ModelState.AddModelError("Register.ZipCode", "Could not find zip code!");
return View(homeVM);
}
var newUser = new AppUser
{
UserName = createVM.UserName,
Email = createVM.Email,
Address = new Address()
{
State = userLocation.StateCode,
City = userLocation.CityName,
ZipCode = createVM.ZipCode ?? 0,
}
};
var newUserResponse = await _userManager.CreateAsync(newUser, createVM.Password);
if (newUserResponse.Succeeded)
{
await _signInManager.SignInAsync(newUser, isPersistent: false);
await _userManager.AddToRoleAsync(newUser, UserRoles.User);
}
return RedirectToAction("Index", "Club");
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
================================================
FILE: RunGroopWebApp/Controllers/RaceController.cs
================================================
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using RunGroopWebApp.Data;
using RunGroopWebApp.Data.Enum;
using RunGroopWebApp.Interfaces;
using RunGroopWebApp.Models;
using RunGroopWebApp.ViewModels;
namespace RunGroopWebApp.Controllers
{
public class RaceController : Controller
{
private readonly IRaceRepository _raceRepository;
private readonly IPhotoService _photoService;
private readonly IHttpContextAccessor _httpContextAccessor;
public RaceController(IRaceRepository raceRepository, IPhotoService photoService, IHttpContextAccessor httpContextAccessor)
{
_raceRepository = raceRepository;
_photoService = photoService;
_httpContextAccessor = httpContextAccessor;
}
[HttpGet]
public async Task<IActionResult> Index(int category = -1, int page = 1, int pageSize = 6)
{
if (page < 1 || pageSize < 1)
{
return NotFound();
}
// if category is -1 (All) dont filter else filter by selected category
var races = category switch
{
-1 => await _raceRepository.GetSliceAsync((page - 1) * pageSize, pageSize),
_ => await _raceRepository.GetRacesByCategoryAndSliceAsync((RaceCategory)category, (page - 1) * pageSize, pageSize),
};
var count = category switch
{
-1 => await _raceRepository.GetCountAsync(),
_ => await _raceRepository.GetCountByCategoryAsync((RaceCategory)category),
};
var viewModel = new IndexRaceViewModel
{
Races = races,
Page = page,
PageSize = pageSize,
TotalRaces = count,
TotalPages = (int)Math.Ceiling(count / (double)pageSize),
Category = category,
};
return View(viewModel);
}
[HttpGet]
[Route("event/{runningRace}/{id}")]
public async Task<IActionResult> DetailRace(int id, string runningRace)
{
var race = await _raceRepository.GetByIdAsync(id);
return race == null ? NotFound() : View(race);
}
[HttpGet]
public IActionResult Create()
{
var curUserID = _httpContextAccessor.HttpContext?.User.GetUserId();
var createRaceViewModel = new CreateRaceViewModel { AppUserId = curUserID };
return View(createRaceViewModel);
}
[HttpPost]
public async Task<IActionResult> Create(CreateRaceViewModel raceVM)
{
if (ModelState.IsValid)
{
var result = await _photoService.AddPhotoAsync(raceVM.Image);
var race = new Race
{
Title = raceVM.Title,
Description = raceVM.Description,
Image = result.Url.ToString(),
AppUserId = raceVM.AppUserId,
RaceCategory = raceVM.RaceCategory,
Address = new Address
{
Street = raceVM.Address.Street,
City = raceVM.Address.City,
State = raceVM.Address.State,
}
};
_raceRepository.Add(race);
return RedirectToAction("Index");
}
else
{
ModelState.AddModelError("", "Photo upload failed");
}
return View(raceVM);
}
[HttpGet]
public async Task<IActionResult> Edit(int id)
{
var race = await _raceRepository.GetByIdAsync(id);
if (race == null) return View("Error");
var raceVM = new EditRaceViewModel
{
Title = race.Title,
Description = race.Description,
AddressId = race.AddressId,
Address = race.Address,
URL = race.Image,
RaceCategory = race.RaceCategory
};
return View(raceVM);
}
[HttpPost]
public async Task<IActionResult> Edit(int id, EditRaceViewModel raceVM)
{
if (!ModelState.IsValid)
{
ModelState.AddModelError("", "Failed to edit club");
return View(raceVM);
}
var userRace = await _raceRepository.GetByIdAsyncNoTracking(id);
if (userRace == null)
{
return View("Error");
}
var photoResult = await _photoService.AddPhotoAsync(raceVM.Image);
if (photoResult.Error != null)
{
ModelState.AddModelError("Image", "Photo upload failed");
return View(raceVM);
}
if (!string.IsNullOrEmpty(userRace.Image))
{
_ = _photoService.DeletePhotoAsync(userRace.Image);
}
var race = new Race
{
Id = id,
Title = raceVM.Title,
Description = raceVM.Description,
Image = photoResult.Url.ToString(),
AddressId = raceVM.AddressId,
Address = raceVM.Address,
};
_raceRepository.Update(race);
return RedirectToAction("Index");
}
[HttpGet]
public async Task<IActionResult> Delete(int id)
{
var clubDetails = await _raceRepository.GetByIdAsync(id);
if (clubDetails == null) return View("Error");
return View(clubDetails);
}
[HttpPost, ActionName("Delete")]
public async Task<IActionResult> DeleteClub(int id)
{
var raceDetails = await _raceRepository.GetByIdAsync(id);
if (raceDetails == null)
{
return View("Error");
}
if (!string.IsNullOrEmpty(raceDetails.Image))
{
_ = _photoService.DeletePhotoAsync(raceDetails.Image);
}
_raceRepository.Delete(raceDetails);
return RedirectToAction("Index");
}
}
}
================================================
FILE: RunGroopWebApp/Controllers/UserController.cs
================================================
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using RunGroopWebApp.ViewModels;
using RunGroopWebApp.Interfaces;
using RunGroopWebApp.Models;
namespace RunGroopWebApp.Controllers
{
public class UserController : Controller
{
private readonly IUserRepository _userRepository;
private readonly UserManager<AppUser> _userManager;
private readonly IPhotoService _photoService;
public UserController(IUserRepository userRepository, UserManager<AppUser> userManager, IPhotoService photoService)
{
_userRepository = userRepository;
_userManager = userManager;
_photoService = photoService;
}
[HttpGet("users")]
public async Task<IActionResult> Index()
{
var users = await _userRepository.GetAllUsers();
List<UserViewModel> result = new List<UserViewModel>();
foreach (var user in users)
{
var userViewModel = new UserViewModel()
{
Id = user.Id,
Pace = user.Pace,
City = user.City,
State = user.State,
Mileage = user.Mileage,
UserName = user.UserName,
ProfileImageUrl = user.ProfileImageUrl ?? "/img/avatar-male-4.jpg",
};
result.Add(userViewModel);
}
return View(result);
}
[HttpGet]
public async Task<IActionResult> Detail(string id)
{
var user = await _userRepository.GetUserById(id);
if (user == null)
{
return RedirectToAction("Index", "Users");
}
var userDetailViewModel = new UserDetailViewModel()
{
Id = user.Id,
Pace = user.Pace,
City = user.City,
State = user.State,
Mileage = user.Mileage,
UserName = user.UserName,
ProfileImageUrl = user.ProfileImageUrl ?? "/img/avatar-male-4.jpg",
};
return View(userDetailViewModel);
}
[HttpGet]
[Authorize]
public async Task<IActionResult> EditProfile()
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
return View("Error");
}
var editMV = new EditProfileViewModel()
{
City = user.City,
State = user.State,
Pace = user.Pace,
Mileage = user.Mileage,
ProfileImageUrl = user.ProfileImageUrl,
};
return View(editMV);
}
[HttpPost]
[Authorize]
public async Task<IActionResult> EditProfile(EditProfileViewModel editVM)
{
if (!ModelState.IsValid)
{
ModelState.AddModelError("", "Failed to edit profile");
return View("EditProfile", editVM);
}
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
return View("Error");
}
if (editVM.Image != null) // only update profile image
{
var photoResult = await _photoService.AddPhotoAsync(editVM.Image);
if (photoResult.Error != null)
{
ModelState.AddModelError("Image", "Failed to upload image");
return View("EditProfile", editVM);
}
if (!string.IsNullOrEmpty(user.ProfileImageUrl))
{
_ = _photoService.DeletePhotoAsync(user.ProfileImageUrl);
}
user.ProfileImageUrl = photoResult.Url.ToString();
editVM.ProfileImageUrl = user.ProfileImageUrl;
await _userManager.UpdateAsync(user);
return View(editVM);
}
user.City = editVM.City;
user.State = editVM.State;
user.Pace = editVM.Pace;
user.Mileage = editVM.Mileage;
await _userManager.UpdateAsync(user);
return RedirectToAction("Detail", "User", new { user.Id });
}
}
}
================================================
FILE: RunGroopWebApp/Data/ApplicationDbContext.cs
================================================
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using RunGroopWebApp.Models;
namespace RunGroopWebApp.Data
{
public class ApplicationDbContext : IdentityDbContext<AppUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
public DbSet<Race> Races { get; set; }
public DbSet<Club> Clubs { get; set; }
public DbSet<Address> Addresses { get; set; }
public DbSet<State> States { get; set; }
public DbSet<City> Cities { get; set; }
}
}
================================================
FILE: RunGroopWebApp/Data/Enum/ClubCategory.cs
================================================
namespace RunGroopWebApp.Data.Enum
{
public enum ClubCategory
{
RoadRunner,
Womens,
City,
Trail,
Endurance
}
}
================================================
FILE: RunGroopWebApp/Data/Enum/RaceCategory.cs
================================================
namespace RunGroopWebApp.Data.Enum
{
public enum RaceCategory
{
Marathon,
Ultra,
FiveK,
TenK,
HalfMarathon
}
}
================================================
FILE: RunGroopWebApp/Data/Seed.cs
================================================
using Microsoft.AspNetCore.Identity;
using RunGroopWebApp.Data.Enum;
using RunGroopWebApp.Models;
namespace RunGroopWebApp.Data
{
public class Seed
{
public static void SeedData(IApplicationBuilder applicationBuilder)
{
using (var serviceScope = applicationBuilder.ApplicationServices.CreateScope())
{
var context = serviceScope.ServiceProvider.GetService<ApplicationDbContext>();
context.Database.EnsureCreated();
if (!context.Clubs.Any())
{
context.Clubs.AddRange(new List<Club>()
{
new Club()
{
Title = "Running Club 1",
Image = "https://www.eatthis.com/wp-content/uploads/sites/4/2020/05/running.jpg?quality=82&strip=1&resize=640%2C360",
Description = "This is the description of the first cinema",
ClubCategory = ClubCategory.City,
Address = new Address()
{
Street = "123 Main St",
City = "Charlotte",
State = "NC"
}
},
new Club()
{
Title = "Running Club 2",
Image = "https://www.eatthis.com/wp-content/uploads/sites/4/2020/05/running.jpg?quality=82&strip=1&resize=640%2C360",
Description = "This is the description of the first cinema",
ClubCategory = ClubCategory.Endurance,
Address = new Address()
{
Street = "123 Main St",
City = "Charlotte",
State = "NC"
}
},
new Club()
{
Title = "Running Club 3",
Image = "https://www.eatthis.com/wp-content/uploads/sites/4/2020/05/running.jpg?quality=82&strip=1&resize=640%2C360",
Description = "This is the description of the first club",
ClubCategory = ClubCategory.Trail,
Address = new Address()
{
Street = "123 Main St",
City = "Charlotte",
State = "NC"
}
},
new Club()
{
Title = "Running Club 3",
Image = "https://www.eatthis.com/wp-content/uploads/sites/4/2020/05/running.jpg?quality=82&strip=1&resize=640%2C360",
Description = "This is the description of the first club",
ClubCategory = ClubCategory.City,
Address = new Address()
{
Street = "123 Main St",
City = "Michigan",
State = "NC"
}
}
});
context.SaveChanges();
}
//Races
if (!context.Races.Any())
{
context.Races.AddRange(new List<Race>()
{
new Race()
{
Title = "Running Race 1",
Image = "https://www.eatthis.com/wp-content/uploads/sites/4/2020/05/running.jpg?quality=82&strip=1&resize=640%2C360",
Description = "This is the description of the first race",
RaceCategory = RaceCategory.Marathon,
Address = new Address()
{
Street = "123 Main St",
City = "Charlotte",
State = "NC"
}
},
new Race()
{
Title = "Running Race 2",
Image = "https://www.eatthis.com/wp-content/uploads/sites/4/2020/05/running.jpg?quality=82&strip=1&resize=640%2C360",
Description = "This is the description of the first race",
RaceCategory = RaceCategory.Ultra,
AddressId = 5,
Address = new Address()
{
Street = "123 Main St",
City = "Charlotte",
State = "NC"
}
}
});
context.SaveChanges();
}
}
}
public static async Task SeedUsersAndRolesAsync(IApplicationBuilder applicationBuilder)
{
using (var serviceScope = applicationBuilder.ApplicationServices.CreateScope())
{
//Roles
var roleManager = serviceScope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();
if (!await roleManager.RoleExistsAsync(UserRoles.Admin))
await roleManager.CreateAsync(new IdentityRole(UserRoles.Admin));
if (!await roleManager.RoleExistsAsync(UserRoles.User))
await roleManager.CreateAsync(new IdentityRole(UserRoles.User));
//Users
var userManager = serviceScope.ServiceProvider.GetRequiredService<UserManager<AppUser>>();
string adminUserEmail = "teddysmithdeveloper@gmail.com";
var adminUser = await userManager.FindByEmailAsync(adminUserEmail);
if (adminUser == null)
{
var newAdminUser = new AppUser()
{
UserName = "teddysmithdev",
Email = adminUserEmail,
EmailConfirmed = true,
Address = new Address()
{
Street = "123 Main St",
City = "Charlotte",
State = "NC"
}
};
await userManager.CreateAsync(newAdminUser, "Coding@1234?");
await userManager.AddToRoleAsync(newAdminUser, UserRoles.Admin);
}
string appUserEmail = "user@etickets.com";
var appUser = await userManager.FindByEmailAsync(appUserEmail);
if (appUser == null)
{
var newAppUser = new AppUser()
{
UserName = "app-user",
Email = appUserEmail,
EmailConfirmed = true,
Address = new Address()
{
Street = "123 Main St",
City = "Charlotte",
State = "NC"
}
};
await userManager.CreateAsync(newAppUser, "Coding@1234?");
await userManager.AddToRoleAsync(newAppUser, UserRoles.User);
}
}
}
}
}
================================================
FILE: RunGroopWebApp/Data/UserRoles.cs
================================================
namespace RunGroopWebApp.Data
{
public static class UserRoles
{
public const string Admin = "admin";
public const string User = "user";
}
}
================================================
FILE: RunGroopWebApp/Extensions/NumberExtensions.cs
================================================
namespace RunGroopWebApp.Extensions
{
public static class NumberExtensions
{
public static bool IsNumericType(this object o)
{
switch (Type.GetTypeCode(o.GetType()))
{
case TypeCode.Byte:
case TypeCode.SByte:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.UInt64:
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
case TypeCode.Decimal:
case TypeCode.Double:
case TypeCode.Single:
return true;
default:
return false;
}
}
}
}
================================================
FILE: RunGroopWebApp/Extensions/StringExtensions.cs
================================================
using System.Text.RegularExpressions;
namespace RunGroopWebApp.Extensions
{
public static class StringExtensions
{
public static string FirstCharToUpper(this string input) =>
input switch
{
null => throw new ArgumentNullException(nameof(input)),
"" => throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input)),
_ => string.Concat(input[0].ToString().ToUpper(), input.AsSpan(1))
};
public static string GenerateSlug(this string phrase)
{
string str = phrase.RemoveAccent().ToLower();
// invalid chars
str = Regex.Replace(str, @"[^a-z0-9\s-]", "");
// convert multiple spaces into one space
str = Regex.Replace(str, @"\s+", " ").Trim();
// cut and trim
str = str.Substring(0, str.Length <= 45 ? str.Length : 45).Trim();
str = Regex.Replace(str, @"\s", "-"); // hyphens
return str;
}
public static string RemoveAccent(this string txt)
{
byte[] bytes = System.Text.Encoding.GetEncoding("Cyrillic").GetBytes(txt);
return System.Text.Encoding.ASCII.GetString(bytes);
}
}
}
================================================
FILE: RunGroopWebApp/Helpers/CloudinarySettings.cs
================================================
namespace RunGroopWebApp.Helpers
{
public class CloudinarySettings
{
public string CloudName { get; set; }
public string ApiKey { get; set; }
public string ApiSecret { get; set; }
}
}
================================================
FILE: RunGroopWebApp/Helpers/IPInfo.cs
================================================
using Newtonsoft.Json;
namespace RunGroopWebApp.Helpers
{
public class IPInfo
{
[JsonProperty("ip")]
public string Ip { get; set; }
[JsonProperty("hostname")]
public string Hostname { get; set; }
[JsonProperty("city")]
public string City { get; set; }
[JsonProperty("region")]
public string Region { get; set; }
[JsonProperty("country")]
public string Country { get; set; }
[JsonProperty("loc")]
public string Location { get; set; }
[JsonProperty("org")]
public string Org { get; set; }
[JsonProperty("postal")]
public string Postal { get; set; }
[JsonProperty("timezone")]
public string Timezone { get; set; }
}
}
================================================
FILE: RunGroopWebApp/Helpers/Location.cs
================================================
namespace RunGroopWebApp.Helpers
{
public class Location
{
public string City { get; set; }
public string State { get; set; }
}
}
================================================
FILE: RunGroopWebApp/Helpers/StateConverter.cs
================================================
namespace RunGroopWebApp.Helpers
{
public static class StateConverter
{
public static string GetState(State state)
{
switch (state)
{
case State.AL:
return "ALABAMA";
case State.AK:
return "ALASKA";
case State.AS:
return "AMERICAN SAMOA";
case State.AZ:
return "ARIZONA";
case State.AR:
return "ARKANSAS";
case State.CA:
return "CALIFORNIA";
case State.CO:
return "COLORADO";
case State.CT:
return "CONNECTICUT";
case State.DE:
return "DELAWARE";
case State.DC:
return "DISTRICT OF COLUMBIA";
case State.FM:
return "FEDERATED STATES OF MICRONESIA";
case State.FL:
return "FLORIDA";
case State.GA:
return "GEORGIA";
case State.GU:
return "GUAM";
case State.HI:
return "HAWAII";
case State.ID:
return "IDAHO";
case State.IL:
return "ILLINOIS";
case State.IN:
return "INDIANA";
case State.IA:
return "IOWA";
case State.KS:
return "KANSAS";
case State.KY:
return "KENTUCKY";
case State.LA:
return "LOUISIANA";
case State.ME:
return "MAINE";
case State.MH:
return "MARSHALL ISLANDS";
case State.MD:
return "MARYLAND";
case State.MA:
return "MASSACHUSETTS";
case State.MI:
return "MICHIGAN";
case State.MN:
return "MINNESOTA";
case State.MS:
return "MISSISSIPPI";
case State.MO:
return "MISSOURI";
case State.MT:
return "MONTANA";
case State.NE:
return "NEBRASKA";
case State.NV:
return "NEVADA";
case State.NH:
return "NEW HAMPSHIRE";
case State.NJ:
return "NEW JERSEY";
case State.NM:
return "NEW MEXICO";
case State.NY:
return "NEW YORK";
case State.NC:
return "NORTH CAROLINA";
case State.ND:
return "NORTH DAKOTA";
case State.MP:
return "NORTHERN MARIANA ISLANDS";
case State.OH:
return "OHIO";
case State.OK:
return "OKLAHOMA";
case State.OR:
return "OREGON";
case State.PW:
return "PALAU";
case State.PA:
return "PENNSYLVANIA";
case State.PR:
return "PUERTO RICO";
case State.RI:
return "RHODE ISLAND";
case State.SC:
return "SOUTH CAROLINA";
case State.SD:
return "SOUTH DAKOTA";
case State.TN:
return "TENNESSEE";
case State.TX:
return "TEXAS";
case State.UT:
return "UTAH";
case State.VT:
return "VERMONT";
case State.VI:
return "VIRGIN ISLANDS";
case State.VA:
return "VIRGINIA";
case State.WA:
return "WASHINGTON";
case State.WV:
return "WEST VIRGINIA";
case State.WI:
return "WISCONSIN";
case State.WY:
return "WYOMING";
}
throw new Exception("Not Available");
}
public static State GetStateByName(string name)
{
switch (name.ToUpper())
{
case "ALABAMA":
return State.AL;
case "ALASKA":
return State.AK;
case "AMERICAN SAMOA":
return State.AS;
case "ARIZONA":
return State.AZ;
case "ARKANSAS":
return State.AR;
case "CALIFORNIA":
return State.CA;
case "COLORADO":
return State.CO;
case "CONNECTICUT":
return State.CT;
case "DELAWARE":
return State.DE;
case "DISTRICT OF COLUMBIA":
return State.DC;
case "FEDERATED STATES OF MICRONESIA":
return State.FM;
case "FLORIDA":
return State.FL;
case "GEORGIA":
return State.GA;
case "GUAM":
return State.GU;
case "HAWAII":
return State.HI;
case "IDAHO":
return State.ID;
case "ILLINOIS":
return State.IL;
case "INDIANA":
return State.IN;
case "IOWA":
return State.IA;
case "KANSAS":
return State.KS;
case "KENTUCKY":
return State.KY;
case "LOUISIANA":
return State.LA;
case "MAINE":
return State.ME;
case "MARSHALL ISLANDS":
return State.MH;
case "MARYLAND":
return State.MD;
case "MASSACHUSETTS":
return State.MA;
case "MICHIGAN":
return State.MI;
case "MINNESOTA":
return State.MN;
case "MISSISSIPPI":
return State.MS;
case "MISSOURI":
return State.MO;
case "MONTANA":
return State.MT;
case "NEBRASKA":
return State.NE;
case "NEVADA":
return State.NV;
case "NEW HAMPSHIRE":
return State.NH;
case "NEW JERSEY":
return State.NJ;
case "NEW MEXICO":
return State.NM;
case "NEW YORK":
return State.NY;
case "NORTH CAROLINA":
return State.NC;
case "NORTH DAKOTA":
return State.ND;
case "NORTHERN MARIANA ISLANDS":
return State.MP;
case "OHIO":
return State.OH;
case "OKLAHOMA":
return State.OK;
case "OREGON":
return State.OR;
case "PALAU":
return State.PW;
case "PENNSYLVANIA":
return State.PA;
case "PUERTO RICO":
return State.PR;
case "RHODE ISLAND":
return State.RI;
case "SOUTH CAROLINA":
return State.SC;
case "SOUTH DAKOTA":
return State.SD;
case "TENNESSEE":
return State.TN;
case "TEXAS":
return State.TX;
case "UTAH":
return State.UT;
case "VERMONT":
return State.VT;
case "VIRGIN ISLANDS":
return State.VI;
case "VIRGINIA":
return State.VA;
case "WASHINGTON":
return State.WA;
case "WEST VIRGINIA":
return State.WV;
case "WISCONSIN":
return State.WI;
case "WYOMING":
return State.WY;
}
throw new Exception("Not Available");
}
public enum State
{
AL,
AK,
AS,
AZ,
AR,
CA,
CO,
CT,
DE,
DC,
FM,
FL,
GA,
GU,
HI,
ID,
IL,
IN,
IA,
KS,
KY,
LA,
ME,
MH,
MD,
MA,
MI,
MN,
MS,
MO,
MT,
NE,
NV,
NH,
NJ,
NM,
NY,
NC,
ND,
MP,
OH,
OK,
OR,
PW,
PA,
PR,
RI,
SC,
SD,
TN,
TX,
UT,
VT,
VI,
VA,
WA,
WV,
WI,
WY
}
}
}
================================================
FILE: RunGroopWebApp/Interfaces/IClubRepository.cs
================================================
using RunGroopWebApp.Data.Enum;
using RunGroopWebApp.Models;
namespace RunGroopWebApp.Interfaces
{
public interface IClubRepository
{
Task<IEnumerable<Club>> GetAll();
Task<IEnumerable<Club>> GetSliceAsync(int offset, int size);
Task<IEnumerable<Club>> GetClubsByState(string state);
Task<IEnumerable<Club>> GetClubsByCategoryAndSliceAsync(ClubCategory category, int offset, int size);
Task<List<State>> GetAllStates();
Task<List<City>> GetAllCitiesByState(string state);
Task<Club?> GetByIdAsync(int id);
Task<Club?> GetByIdAsyncNoTracking(int id);
Task<IEnumerable<Club>> GetClubByCity(string city);
Task<int> GetCountAsync();
Task<int> GetCountByCategoryAsync(ClubCategory category);
bool Add(Club club);
bool Update(Club club);
bool Delete(Club club);
bool Save();
}
}
================================================
FILE: RunGroopWebApp/Interfaces/IDashboardRepository.cs
================================================
using RunGroopWebApp.Models;
namespace RunGroopWebApp.Interfaces
{
public interface IDashboardRepository
{
Task<List<Race>> GetAllUserRaces();
Task<List<Club>> GetAllUserClubs();
Task<AppUser> GetUserById(string id);
Task<AppUser> GetByIdNoTracking(string id);
bool Update(AppUser user);
bool Save();
}
}
================================================
FILE: RunGroopWebApp/Interfaces/ILocationService.cs
================================================
using RunGroopWebApp.Models;
namespace RunGroopWebApp.Interfaces
{
public interface ILocationService
{
Task<List<City>> GetLocationSearch(string location);
Task<City> GetCityByZipCode(int zipCode);
}
}
================================================
FILE: RunGroopWebApp/Interfaces/IPhotoService.cs
================================================
using CloudinaryDotNet.Actions;
namespace RunGroopWebApp.Interfaces
{
public interface IPhotoService
{
Task<ImageUploadResult> AddPhotoAsync(IFormFile file);
Task<DeletionResult> DeletePhotoAsync(string publicUrl);
}
}
================================================
FILE: RunGroopWebApp/Interfaces/IRaceRepository.cs
================================================
using RunGroopWebApp.Data.Enum;
using RunGroopWebApp.Models;
namespace RunGroopWebApp.Interfaces
{
public interface IRaceRepository
{
Task<int> GetCountAsync();
Task<int> GetCountByCategoryAsync(RaceCategory category);
Task<Race?> GetByIdAsync(int id);
Task<Race?> GetByIdAsyncNoTracking(int id);
Task<IEnumerable<Race>> GetAll();
Task<IEnumerable<Race>> GetAllRacesByCity(string city);
Task<IEnumerable<Race>> GetSliceAsync(int offset, int size);
Task<IEnumerable<Race>> GetRacesByCategoryAndSliceAsync(RaceCategory category, int offset, int size);
bool Add(Race race);
bool Update(Race race);
bool Delete(Race race);
bool Save();
}
}
================================================
FILE: RunGroopWebApp/Interfaces/IUserRepository.cs
================================================
using RunGroopWebApp.Models;
namespace RunGroopWebApp.Interfaces
{
public interface IUserRepository
{
Task<IEnumerable<AppUser>> GetAllUsers();
Task<AppUser> GetUserById(string id);
bool Add(AppUser user);
bool Update(AppUser user);
bool Delete(AppUser user);
bool Save();
}
}
================================================
FILE: RunGroopWebApp/Migrations/20220215112438_InitialCreate.Designer.cs
================================================
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using RunGroopWebApp.Data;
#nullable disable
namespace RunGroopWebApp.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20220215112438_InitialCreate")]
partial class InitialCreate
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
modelBuilder.Entity("RunGroopWebApp.Models.Address", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
b.Property<string>("City")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("State")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Street")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Addresses");
});
modelBuilder.Entity("RunGroopWebApp.Models.AppUser", b =>
{
b.Property<string>("Id")
.HasColumnType("nvarchar(450)");
b.Property<int?>("AddressId")
.HasColumnType("int");
b.Property<int?>("Mileage")
.HasColumnType("int");
b.Property<int?>("Pace")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("AddressId");
b.ToTable("AppUser");
});
modelBuilder.Entity("RunGroopWebApp.Models.Club", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
b.Property<int>("AddressId")
.HasColumnType("int");
b.Property<string>("AppUserId")
.HasColumnType("nvarchar(450)");
b.Property<int>("ClubCategory")
.HasColumnType("int");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Image")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.HasIndex("AddressId");
b.HasIndex("AppUserId");
b.ToTable("Clubs");
});
modelBuilder.Entity("RunGroopWebApp.Models.Race", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
b.Property<int>("AddressId")
.HasColumnType("int");
b.Property<string>("AppUserId")
.HasColumnType("nvarchar(450)");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Image")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("RaceCategory")
.HasColumnType("int");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.HasIndex("AddressId");
b.HasIndex("AppUserId");
b.ToTable("Races");
});
modelBuilder.Entity("RunGroopWebApp.Models.AppUser", b =>
{
b.HasOne("RunGroopWebApp.Models.Address", "Address")
.WithMany()
.HasForeignKey("AddressId");
b.Navigation("Address");
});
modelBuilder.Entity("RunGroopWebApp.Models.Club", b =>
{
b.HasOne("RunGroopWebApp.Models.Address", "Address")
.WithMany()
.HasForeignKey("AddressId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("RunGroopWebApp.Models.AppUser", "AppUser")
.WithMany("Clubs")
.HasForeignKey("AppUserId");
b.Navigation("Address");
b.Navigation("AppUser");
});
modelBuilder.Entity("RunGroopWebApp.Models.Race", b =>
{
b.HasOne("RunGroopWebApp.Models.Address", "Address")
.WithMany()
.HasForeignKey("AddressId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("RunGroopWebApp.Models.AppUser", "AppUser")
.WithMany("Races")
.HasForeignKey("AppUserId");
b.Navigation("Address");
b.Navigation("AppUser");
});
modelBuilder.Entity("RunGroopWebApp.Models.AppUser", b =>
{
b.Navigation("Clubs");
b.Navigation("Races");
});
#pragma warning restore 612, 618
}
}
}
================================================
FILE: RunGroopWebApp/Migrations/20220215112438_InitialCreate.cs
================================================
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace RunGroopWebApp.Migrations
{
public partial class InitialCreate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Addresses",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Street = table.Column<string>(type: "nvarchar(max)", nullable: false),
City = table.Column<string>(type: "nvarchar(max)", nullable: false),
State = table.Column<string>(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Addresses", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AppUser",
columns: table => new
{
Id = table.Column<string>(type: "nvarchar(450)", nullable: false),
Pace = table.Column<int>(type: "int", nullable: true),
Mileage = table.Column<int>(type: "int", nullable: true),
AddressId = table.Column<int>(type: "int", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AppUser", x => x.Id);
table.ForeignKey(
name: "FK_AppUser_Addresses_AddressId",
column: x => x.AddressId,
principalTable: "Addresses",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "Clubs",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Title = table.Column<string>(type: "nvarchar(max)", nullable: false),
Description = table.Column<string>(type: "nvarchar(max)", nullable: false),
Image = table.Column<string>(type: "nvarchar(max)", nullable: false),
AddressId = table.Column<int>(type: "int", nullable: false),
ClubCategory = table.Column<int>(type: "int", nullable: false),
AppUserId = table.Column<string>(type: "nvarchar(450)", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Clubs", x => x.Id);
table.ForeignKey(
name: "FK_Clubs_Addresses_AddressId",
column: x => x.AddressId,
principalTable: "Addresses",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Clubs_AppUser_AppUserId",
column: x => x.AppUserId,
principalTable: "AppUser",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "Races",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Title = table.Column<string>(type: "nvarchar(max)", nullable: false),
Description = table.Column<string>(type: "nvarchar(max)", nullable: false),
Image = table.Column<string>(type: "nvarchar(max)", nullable: false),
AddressId = table.Column<int>(type: "int", nullable: false),
RaceCategory = table.Column<int>(type: "int", nullable: false),
AppUserId = table.Column<string>(type: "nvarchar(450)", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Races", x => x.Id);
table.ForeignKey(
name: "FK_Races_Addresses_AddressId",
column: x => x.AddressId,
principalTable: "Addresses",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Races_AppUser_AppUserId",
column: x => x.AppUserId,
principalTable: "AppUser",
principalColumn: "Id");
});
migrationBuilder.CreateIndex(
name: "IX_AppUser_AddressId",
table: "AppUser",
column: "AddressId");
migrationBuilder.CreateIndex(
name: "IX_Clubs_AddressId",
table: "Clubs",
column: "AddressId");
migrationBuilder.CreateIndex(
name: "IX_Clubs_AppUserId",
table: "Clubs",
column: "AppUserId");
migrationBuilder.CreateIndex(
name: "IX_Races_AddressId",
table: "Races",
column: "AddressId");
migrationBuilder.CreateIndex(
name: "IX_Races_AppUserId",
table: "Races",
column: "AppUserId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Clubs");
migrationBuilder.DropTable(
name: "Races");
migrationBuilder.DropTable(
name: "AppUser");
migrationBuilder.DropTable(
name: "Addresses");
}
}
}
================================================
FILE: RunGroopWebApp/Migrations/ApplicationDbContextModelSnapshot.cs
================================================
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using RunGroopWebApp.Data;
#nullable disable
namespace RunGroopWebApp.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
partial class ApplicationDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("nvarchar(450)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex")
.HasFilter("[NormalizedName] IS NOT NULL");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
b.Property<string>("ClaimType")
.HasColumnType("nvarchar(max)");
b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(max)");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
b.Property<string>("ClaimType")
.HasColumnType("nvarchar(max)");
b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(max)");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("nvarchar(450)");
b.Property<string>("ProviderKey")
.HasColumnType("nvarchar(450)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("nvarchar(max)");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("nvarchar(450)");
b.Property<string>("RoleId")
.HasColumnType("nvarchar(450)");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("nvarchar(450)");
b.Property<string>("LoginProvider")
.HasColumnType("nvarchar(450)");
b.Property<string>("Name")
.HasColumnType("nvarchar(450)");
b.Property<string>("Value")
.HasColumnType("nvarchar(max)");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("RunGroopWebApp.Models.Address", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
b.Property<string>("City")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("State")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Street")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Addresses");
});
modelBuilder.Entity("RunGroopWebApp.Models.AppUser", b =>
{
b.Property<string>("Id")
.HasColumnType("nvarchar(450)");
b.Property<int>("AccessFailedCount")
.HasColumnType("int");
b.Property<int?>("AddressId")
.HasColumnType("int");
b.Property<string>("City")
.HasColumnType("nvarchar(max)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<bool>("EmailConfirmed")
.HasColumnType("bit");
b.Property<bool>("LockoutEnabled")
.HasColumnType("bit");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetimeoffset");
b.Property<int?>("Mileage")
.HasColumnType("int");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<int?>("Pace")
.HasColumnType("int");
b.Property<string>("PasswordHash")
.HasColumnType("nvarchar(max)");
b.Property<string>("PhoneNumber")
.HasColumnType("nvarchar(max)");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("bit");
b.Property<string>("ProfileImageUrl")
.HasColumnType("nvarchar(max)");
b.Property<string>("SecurityStamp")
.HasColumnType("nvarchar(max)");
b.Property<string>("State")
.HasColumnType("nvarchar(max)");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("bit");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.HasKey("Id");
b.HasIndex("AddressId");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex")
.HasFilter("[NormalizedUserName] IS NOT NULL");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("RunGroopWebApp.Models.City", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
b.Property<string>("CityName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("County")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<float>("Latitude")
.HasColumnType("real");
b.Property<float>("Longitude")
.HasColumnType("real");
b.Property<string>("StateCode")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("Zip")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("Cities");
});
modelBuilder.Entity("RunGroopWebApp.Models.Club", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
b.Property<int>("AddressId")
.HasColumnType("int");
b.Property<string>("AppUserId")
.HasColumnType("nvarchar(450)");
b.Property<int>("ClubCategory")
.HasColumnType("int");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Image")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.HasIndex("AddressId");
b.HasIndex("AppUserId");
b.ToTable("Clubs");
});
modelBuilder.Entity("RunGroopWebApp.Models.Race", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
b.Property<int>("AddressId")
.HasColumnType("int");
b.Property<string>("AppUserId")
.HasColumnType("nvarchar(450)");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Image")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("RaceCategory")
.HasColumnType("int");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.HasIndex("AddressId");
b.HasIndex("AppUserId");
b.ToTable("Races");
});
modelBuilder.Entity("RunGroopWebApp.Models.State", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
b.Property<string>("StateCode")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("StateName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("States");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("RunGroopWebApp.Models.AppUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("RunGroopWebApp.Models.AppUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("RunGroopWebApp.Models.AppUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("RunGroopWebApp.Models.AppUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("RunGroopWebApp.Models.AppUser", b =>
{
b.HasOne("RunGroopWebApp.Models.Address", "Address")
.WithMany()
.HasForeignKey("AddressId");
b.Navigation("Address");
});
modelBuilder.Entity("RunGroopWebApp.Models.Club", b =>
{
b.HasOne("RunGroopWebApp.Models.Address", "Address")
.WithMany()
.HasForeignKey("AddressId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("RunGroopWebApp.Models.AppUser", "AppUser")
.WithMany("Clubs")
.HasForeignKey("AppUserId");
b.Navigation("Address");
b.Navigation("AppUser");
});
modelBuilder.Entity("RunGroopWebApp.Models.Race", b =>
{
b.HasOne("RunGroopWebApp.Models.Address", "Address")
.WithMany()
.HasForeignKey("AddressId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("RunGroopWebApp.Models.AppUser", "AppUser")
.WithMany("Races")
.HasForeignKey("AppUserId");
b.Navigation("Address");
b.Navigation("AppUser");
});
modelBuilder.Entity("RunGroopWebApp.Models.AppUser", b =>
{
b.Navigation("Clubs");
b.Navigation("Races");
});
#pragma warning restore 612, 618
}
}
}
================================================
FILE: RunGroopWebApp/Models/Address.cs
================================================
using System.ComponentModel.DataAnnotations;
namespace RunGroopWebApp.Models
{
public class Address
{
[Key]
public int Id { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
public int ZipCode { get; set; }
}
}
================================================
FILE: RunGroopWebApp/Models/AppUser.cs
================================================
using Microsoft.AspNetCore.Identity;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace RunGroopWebApp.Models
{
public class AppUser : IdentityUser
{
public int? Pace { get; set; }
public int? Mileage { get; set; }
public string? ProfileImageUrl { get; set; }
public string? City { get; set; }
public string? State { get; set; }
[ForeignKey("Address")]
public int? AddressId { get; set; }
public Address? Address { get; set; }
public ICollection<Club> Clubs { get; set; }
public ICollection<Race> Races { get; set; }
}
}
================================================
FILE: RunGroopWebApp/Models/City.cs
================================================
namespace RunGroopWebApp.Models
{
public class City
{
public int Id { get; set; }
public string CityName { get; set; }
public string StateCode { get; set; }
public int Zip { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public string County { get; set; }
}
}
================================================
FILE: RunGroopWebApp/Models/Club.cs
================================================
using RunGroopWebApp.Data.Enum;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace RunGroopWebApp.Models
{
public class Club
{
[Key]
public int Id { get; set; }
public string? Title { get; set; }
public string? Description { get; set; }
public string? Image { get; set; }
[ForeignKey("Address")]
public int? AddressId { get; set; }
public Address? Address { get; set; }
public ClubCategory ClubCategory { get; set; }
[ForeignKey("AppUser")]
public string? AppUserId { get; set; }
public AppUser? AppUser { get; set; }
}
}
================================================
FILE: RunGroopWebApp/Models/ErrorViewModel.cs
================================================
namespace RunGroopWebApp.Models
{
public class ErrorViewModel
{
public string? RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}
}
================================================
FILE: RunGroopWebApp/Models/Race.cs
================================================
using RunGroopWebApp.Data.Enum;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace RunGroopWebApp.Models
{
public class Race
{
[Key]
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string? Image { get; set; }
public DateTime? StartTime { get; set; }
public int? EntryFee { get; set; }
public string? Website { get; set; }
public string? Twitter { get; set; }
public string? Facebook { get; set; }
public string? Contact { get; set; }
[ForeignKey("Address")]
public int AddressId { get; set; }
public Address Address { get; set; }
public RaceCategory RaceCategory { get; set; }
[ForeignKey("AppUser")]
public string? AppUserId { get; set; }
public AppUser? AppUser { get; set; }
}
}
================================================
FILE: RunGroopWebApp/Models/State.cs
================================================
namespace RunGroopWebApp.Models
{
public class State
{
public int Id { get; set; }
public string StateName { get; set; }
public string StateCode { get; set; }
}
}
================================================
FILE: RunGroopWebApp/Program.cs
================================================
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using RunGroopWebApp.Data;
using RunGroopWebApp.Helpers;
using RunGroopWebApp.Interfaces;
using RunGroopWebApp.Models;
using RunGroopWebApp.Repository;
using RunGroopWebApp.Services;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddScoped<IClubRepository, ClubRepository>();
builder.Services.AddScoped<IRaceRepository, RaceRepository>();
builder.Services.AddScoped<IDashboardRepository, DashboardRepository>();
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddScoped<ILocationService, LocationService>();
builder.Services.AddScoped<IPhotoService, PhotoService>();
builder.Services.Configure<CloudinarySettings>(builder.Configuration.GetSection("CloudinarySettings"));
builder.Services.AddDbContext<ApplicationDbContext>(options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));
});
builder.Services.AddIdentity<AppUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddMemoryCache();
builder.Services.AddSession();
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie();
var app = builder.Build();
if (args.Length == 1 && args[0].ToLower() == "seeddata")
{
await Seed.SeedUsersAndRolesAsync(app);
//Seed.SeedData(app);
}
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/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();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
================================================
FILE: RunGroopWebApp/Properties/launchSettings.json
================================================
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:42985",
"sslPort": 44364
}
},
"profiles": {
"RunGroopWebApp": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7195;http://localhost:5195",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
================================================
FILE: RunGroopWebApp/Repository/ClubRepository.cs
================================================
using Microsoft.EntityFrameworkCore;
using RunGroopWebApp.Data;
using RunGroopWebApp.Data.Enum;
using RunGroopWebApp.Interfaces;
using RunGroopWebApp.Models;
namespace RunGroopWebApp.Repository
{
public class ClubRepository : IClubRepository
{
private readonly ApplicationDbContext _context;
public ClubRepository(ApplicationDbContext context)
{
_context = context;
}
public bool Add(Club club)
{
_context.Add(club);
return Save();
}
public bool Delete(Club club)
{
_context.Remove(club);
return Save();
}
public async Task<IEnumerable<Club>> GetAll()
{
return await _context.Clubs.ToListAsync();
}
public async Task<List<State>> GetAllStates()
{
return await _context.States.ToListAsync();
}
public async Task<IEnumerable<Club>> GetSliceAsync(int offset, int size)
{
return await _context.Clubs.Include(i => i.Address).Skip(offset).Take(size).ToListAsync();
}
public async Task<IEnumerable<Club>> GetClubsByCategoryAndSliceAsync(ClubCategory category, int offset, int size)
{
return await _context.Clubs
.Include(i => i.Address)
.Where(c => c.ClubCategory == category)
.Skip(offset)
.Take(size)
.ToListAsync();
}
public async Task<int> GetCountByCategoryAsync(ClubCategory category)
{
return await _context.Clubs.CountAsync(c => c.ClubCategory == category);
}
public async Task<Club?> GetByIdAsync(int id)
{
return await _context.Clubs.Include(i => i.Address).FirstOrDefaultAsync(i => i.Id == id);
}
public async Task<Club?> GetByIdAsyncNoTracking(int id)
{
return await _context.Clubs.Include(i => i.Address).AsNoTracking().FirstOrDefaultAsync(i => i.Id == id);
}
public async Task<IEnumerable<Club>> GetClubByCity(string city)
{
return await _context.Clubs.Where(c => c.Address.City.Contains(city)).Distinct().ToListAsync();
}
public bool Save()
{
var saved = _context.SaveChanges();
return saved > 0;
}
public bool Update(Club club)
{
_context.Update(club);
return Save();
}
public async Task<int> GetCountAsync()
{
return await _context.Clubs.CountAsync();
}
public async Task<IEnumerable<Club>> GetClubsByState(string state)
{
return await _context.Clubs.Where(c => c.Address.State.Contains(state)).ToListAsync();
}
public async Task<List<City>> GetAllCitiesByState(string state)
{
return await _context.Cities.Where(c => c.StateCode.Contains(state)).ToListAsync();
}
}
}
================================================
FILE: RunGroopWebApp/Repository/DashboardRepository.cs
================================================
using Microsoft.EntityFrameworkCore;
using RunGroopWebApp.Data;
using RunGroopWebApp.Interfaces;
using RunGroopWebApp.Models;
namespace RunGroopWebApp.Repository
{
public class DashboardRepository : IDashboardRepository
{
private readonly ApplicationDbContext _context;
private readonly IHttpContextAccessor _httpContextAccessor;
public DashboardRepository(ApplicationDbContext context, IHttpContextAccessor httpContextAccessor)
{
_context = context;
_httpContextAccessor = httpContextAccessor;
}
public async Task<List<Club>> GetAllUserClubs()
{
var curUser = _httpContextAccessor.HttpContext?.User.GetUserId();
var userClubs = _context.Clubs.Where(r => r.AppUser.Id == curUser);
return userClubs.ToList();
}
public async Task<List<Race>> GetAllUserRaces()
{
var curUser = _httpContextAccessor.HttpContext?.User.GetUserId();
var userRaces = _context.Races.Where(r => r.AppUser.Id == curUser);
return userRaces.ToList();
}
public async Task<AppUser> GetUserById(string id)
{
return await _context.Users.FindAsync(id);
}
public async Task<AppUser> GetByIdNoTracking(string id)
{
return await _context.Users.Where(u => u.Id == id).AsNoTracking().FirstOrDefaultAsync();
}
public bool Update(AppUser user)
{
_context.Users.Update(user);
return Save();
}
public bool Save()
{
var saved = _context.SaveChanges();
return saved > 0 ? true : false;
}
}
}
================================================
FILE: RunGroopWebApp/Repository/RaceRepository.cs
================================================
using Microsoft.EntityFrameworkCore;
using RunGroopWebApp.Data;
using RunGroopWebApp.Data.Enum;
using RunGroopWebApp.Interfaces;
using RunGroopWebApp.Models;
namespace RunGroopWebApp.Repository
{
public class RaceRepository : IRaceRepository
{
private readonly ApplicationDbContext _context;
public RaceRepository(ApplicationDbContext context)
{
_context = context;
}
public bool Add(Race race)
{
_context.Add(race);
return Save();
}
public bool Delete(Race race)
{
_context.Remove(race);
return Save();
}
public async Task<IEnumerable<Race>> GetAll()
{
return await _context.Races.ToListAsync();
}
public async Task<IEnumerable<Race>> GetAllRacesByCity(string city)
{
return await _context.Races.Where(c => c.Address.City.Contains(city)).ToListAsync();
}
public async Task<Race?> GetByIdAsync(int id)
{
return await _context.Races.Include(i => i.Address).FirstOrDefaultAsync(x => x.Id == id);
}
public async Task<Race?> GetByIdAsyncNoTracking(int id)
{
return await _context.Races.Include(i => i.Address).AsNoTracking().FirstOrDefaultAsync();
}
public async Task<int> GetCountAsync()
{
return await _context.Races.CountAsync();
}
public async Task<int> GetCountByCategoryAsync(RaceCategory category)
{
return await _context.Races.CountAsync(r => r.RaceCategory == category);
}
public async Task<IEnumerable<Race>> GetSliceAsync(int offset, int size)
{
return await _context.Races.Include(a => a.Address).Skip(offset).Take(size).ToListAsync();
}
public async Task<IEnumerable<Race>> GetRacesByCategoryAndSliceAsync(RaceCategory category, int offset, int size)
{
return await _context.Races
.Where(r => r.RaceCategory == category)
.Include(a => a.Address)
.Skip(offset)
.Take(size)
.ToListAsync();
}
public bool Save()
{
var saved = _context.SaveChanges();
return saved > 0;
}
public bool Update(Race race)
{
_context.Update(race);
return Save();
}
}
}
================================================
FILE: RunGroopWebApp/Repository/UserRepository.cs
================================================
using Microsoft.EntityFrameworkCore;
using RunGroopWebApp.Data;
using RunGroopWebApp.Interfaces;
using RunGroopWebApp.Models;
namespace RunGroopWebApp.Repository
{
public class UserRepository : IUserRepository
{
private readonly ApplicationDbContext _context;
public UserRepository(ApplicationDbContext context)
{
_context = context;
}
public bool Add(AppUser user)
{
throw new NotImplementedException();
}
public bool Delete(AppUser user)
{
throw new NotImplementedException();
}
public async Task<IEnumerable<AppUser>> GetAllUsers()
{
return await _context.Users.ToListAsync();
}
public async Task<AppUser> GetUserById(string id)
{
return await _context.Users.FindAsync(id);
}
public bool Save()
{
var saved = _context.SaveChanges();
return saved > 0 ? true : false;
}
public bool Update(AppUser user)
{
_context.Update(user);
return Save();
}
}
}
================================================
FILE: RunGroopWebApp/RunGroopWebApp.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CloudinaryDotNet" Version="1.17.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
================================================
FILE: RunGroopWebApp/Services/LocationService.cs
================================================
using Microsoft.EntityFrameworkCore;
using RunGroopWebApp.Data;
using RunGroopWebApp.Extensions;
using RunGroopWebApp.Helpers;
using RunGroopWebApp.Interfaces;
using RunGroopWebApp.Models;
namespace RunGroopWebApp.Services
{
public class LocationService : ILocationService
{
private readonly ApplicationDbContext _context;
public LocationService(ApplicationDbContext context)
{
_context = context;
}
public async Task<City> GetCityByZipCode(int zipCode)
{
return await _context.Cities.FirstOrDefaultAsync(x => x.Zip == zipCode);
}
public async Task<List<City>> GetLocationSearch(string location)
{
List<City> result;
if(location.Length > 0 && char.IsDigit(location[0]))
{
return await _context.Cities.Where(x => x.Zip.ToString().StartsWith(location)).Take(4).Distinct().ToListAsync();
}
else if (location.Length > 0)
{
result = await _context.Cities.Where(x => x.CityName == location).Take(10).ToListAsync();
}
result = await _context.Cities.Where(x => x.StateCode == location).Take(10).ToListAsync();
return result;
}
}
}
================================================
FILE: RunGroopWebApp/Services/PhotoService.cs
================================================
using CloudinaryDotNet;
using CloudinaryDotNet.Actions;
using Microsoft.Extensions.Options;
using RunGroopWebApp.Helpers;
using RunGroopWebApp.Interfaces;
namespace RunGroopWebApp.Services
{
public class PhotoService : IPhotoService
{
private readonly Cloudinary _cloundinary;
public PhotoService(IOptions<CloudinarySettings> config)
{
var acc = new Account(
config.Value.CloudName,
config.Value.ApiKey,
config.Value.ApiSecret
);
_cloundinary = new Cloudinary(acc);
}
public async Task<ImageUploadResult> AddPhotoAsync(IFormFile file)
{
var uploadResult = new ImageUploadResult();
if (file.Length > 0)
{
using var stream = file.OpenReadStream();
var uploadParams = new ImageUploadParams
{
File = new FileDescription(file.FileName, stream),
Transformation = new Transformation().Height(500).Width(500).Crop("fill").Gravity("face")
};
uploadResult = await _cloundinary.UploadAsync(uploadParams);
}
return uploadResult;
}
public async Task<DeletionResult> DeletePhotoAsync(string publicUrl)
{
var publicId = publicUrl.Split('/').Last().Split('.')[0];
var deleteParams = new DeletionParams(publicId);
return await _cloundinary.DestroyAsync(deleteParams);
}
}
}
================================================
FILE: RunGroopWebApp/ViewModels/CreateClubViewModel.cs
================================================
using RunGroopWebApp.Data.Enum;
using RunGroopWebApp.Models;
namespace RunGroopWebApp.ViewModels
{
public class CreateClubViewModel
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public Address Address { get; set; }
public IFormFile Image { get; set; }
public ClubCategory ClubCategory { get; set; }
public string AppUserId { get; set; }
}
}
================================================
FILE: RunGroopWebApp/ViewModels/CreateRaceViewModel.cs
================================================
using RunGroopWebApp.Data.Enum;
using RunGroopWebApp.Models;
namespace RunGroopWebApp.ViewModels
{
public class CreateRaceViewModel
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public Address Address { get; set; }
public IFormFile Image { get; set; }
public RaceCategory RaceCategory { get; set; }
public string AppUserId { get; set; }
}
}
================================================
FILE: RunGroopWebApp/ViewModels/DashboardViewModel.cs
================================================
using RunGroopWebApp.Models;
namespace RunGroopWebApp.ViewModels
{
public class DashboardViewModel
{
public List<Race> Races { get; set; }
public List<Club> Clubs { get; set; }
}
}
================================================
FILE: RunGroopWebApp/ViewModels/EditClubViewModel.cs
================================================
using RunGroopWebApp.Data.Enum;
using RunGroopWebApp.Models;
namespace RunGroopWebApp.ViewModels
{
public class EditClubViewModel
{
public int Id{ get; set; }
public string Title { get; set; }
public string Description { get; set; }
public IFormFile Image { get; set; }
public string? URL { get; set; }
public int? AddressId { get; set; }
public Address? Address { get; set; }
public ClubCategory ClubCategory { get; set; }
}
}
================================================
FILE: RunGroopWebApp/ViewModels/EditProfileViewModel.cs
================================================
namespace RunGroopWebApp.ViewModels
{
public class EditProfileViewModel
{
public int? Pace { get; set; }
public int? Mileage { get; set; }
public string? ProfileImageUrl { get; set; }
public string? City { get; set; }
public string? State { get; set; }
public IFormFile? Image { get; set; }
}
}
================================================
FILE: RunGroopWebApp/ViewModels/EditRaceViewModel.cs
================================================
using RunGroopWebApp.Data.Enum;
using RunGroopWebApp.Models;
namespace RunGroopWebApp.ViewModels
{
public class EditRaceViewModel
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public IFormFile Image { get; set; }
public string? URL { get; set; }
public int AddressId { get; set; }
public Address Address { get; set; }
public RaceCategory RaceCategory { get; set; }
}
}
================================================
FILE: RunGroopWebApp/ViewModels/HomeUserCreateViewModel.cs
================================================
using System.ComponentModel.DataAnnotations;
namespace RunGroopWebApp.ViewModels
{
public class HomeUserCreateViewModel
{
public string UserName { get; set; }
public string Email { get; set; }
[DataType(DataType.Password)]
public string Password { get; set; }
[Required]
public int? ZipCode { get; set; }
}
}
================================================
FILE: RunGroopWebApp/ViewModels/HomeViewModel.cs
================================================
using RunGroopWebApp.Models;
namespace RunGroopWebApp.ViewModels
{
public class HomeViewModel
{
public IEnumerable<Club>? Clubs { get; set; }
public string? City { get; set; }
public string? State { get; set; }
public HomeUserCreateViewModel Register { get; set; } = new HomeUserCreateViewModel();
}
}
================================================
FILE: RunGroopWebApp/ViewModels/IndexClubViewModel.cs
================================================
using RunGroopWebApp.Models;
namespace RunGroopWebApp.ViewModels;
public class IndexClubViewModel
{
public IEnumerable<Club> Clubs { get; set; }
public int PageSize { get; set; }
public int Page { get; set; }
public int TotalPages { get; set; }
public int TotalClubs { get; set; }
public int Category { get; set; }
public bool HasPreviousPage => Page > 1;
public bool HasNextPage => Page < TotalPages;
}
================================================
FILE: RunGroopWebApp/ViewModels/IndexRaceViewModel.cs
================================================
using RunGroopWebApp.Models;
namespace RunGroopWebApp.ViewModels;
public class IndexRaceViewModel
{
public IEnumerable<Race> Races { get; set; }
public int PageSize { get; set; }
public int Page { get; set; }
public int TotalPages { get; set; }
public int TotalRaces { get; set; }
public int Category { get; set; }
public bool HasPreviousPage => Page > 1;
public bool HasNextPage => Page < TotalPages;
}
================================================
FILE: RunGroopWebApp/ViewModels/ListClubByCityViewModel.cs
================================================
using RunGroopWebApp.Models;
namespace RunGroopWebApp.ViewModels
{
public class ListClubByCityViewModel
{
public IEnumerable<Club> Clubs { get; set; }
public bool NoClubWarning { get; set; } = false;
public string City { get; set; }
public string State { get; set; }
}
}
================================================
FILE: RunGroopWebApp/ViewModels/ListClubByStateViewModel.cs
================================================
using RunGroopWebApp.Models;
namespace RunGroopWebApp.ViewModels
{
public class ListClubByStateViewModel
{
public IEnumerable<Club> Clubs { get; set; }
public bool NoClubWarning { get; set; } = false;
public string State { get; set; }
}
}
================================================
FILE: RunGroopWebApp/ViewModels/LoginViewModel.cs
================================================
using System.ComponentModel.DataAnnotations;
namespace RunGroopWebApp.ViewModels
{
public class LoginViewModel
{
[Display(Name = "Email Address")]
[Required(ErrorMessage = "Email address is required")]
public string EmailAddress { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
}
}
================================================
FILE: RunGroopWebApp/ViewModels/RegisterViewModel.cs
================================================
using System.ComponentModel.DataAnnotations;
namespace RunGroopWebApp.ViewModels
{
public class RegisterViewModel
{
[Display(Name = "Email address")]
[Required(ErrorMessage = "Email address is required")]
public string EmailAddress { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[Display(Name = "Confirm password")]
[Required(ErrorMessage = "Confirm password is required")]
[DataType(DataType.Password)]
[Compare("Password", ErrorMessage = "Password do not match")]
public string ConfirmPassword { get; set; }
}
}
================================================
FILE: RunGroopWebApp/ViewModels/RunningClubByCity.cs
================================================
using RunGroopWebApp.Models;
namespace RunGroopWebApp.ViewModels
{
public class RunningClubByCity
{
public List<City> Cities { get; set; } = null;
}
}
================================================
FILE: RunGroopWebApp/ViewModels/RunningClubByState.cs
================================================
using RunGroopWebApp.Models;
namespace RunGroopWebApp.ViewModels
{
public class RunningClubByState
{
public List<State> States { get; set; } = null;
}
}
================================================
FILE: RunGroopWebApp/ViewModels/UserDetailViewModel.cs
================================================
using RunGroopWebApp.Models;
namespace RunGroopWebApp.ViewModels;
public class UserDetailViewModel
{
public string Id { get; set; }
public string UserName { get; set; }
public int? Pace { get; set; }
public int? Mileage { get; set; }
public string? City { get; set; }
public string? State { get; set; }
public string ProfileImageUrl { get; set; }
public string Location => (City, State) switch
{
(string city, string state) => $"{city}, {state}",
(string city, null) => city,
(null, string state) => state,
(null, null) => "",
};
}
================================================
FILE: RunGroopWebApp/ViewModels/UserViewModel.cs
================================================
namespace RunGroopWebApp.ViewModels;
public class UserViewModel
{
public string Id { get; set; }
public string UserName { get; set; }
public int? Pace { get; set; }
public int? Mileage { get; set; }
public string? City { get; set; }
public string? State { get; set; }
public string ProfileImageUrl { get; set; }
public string Location => (City, State) switch
{
(string city, string state) => $"{city}, {state}",
(string city, null) => city,
(null, string state) => state,
(null, null) => "",
};
}
================================================
FILE: RunGroopWebApp/ViewModels/WelcomeViewModel.cs
================================================
namespace RunGroopWebApp.ViewModels
{
public class WelcomeViewModel
{
public int? Pace { get; set; }
public int? Mileage { get; set; }
public string? ProfileImageUrl { get; set; }
public string? City { get; set; }
public string? State { get; set; }
public IFormFile? Image { get; set; }
}
}
================================================
FILE: RunGroopWebApp/Views/Account/Login.cshtml
================================================
@using RunGroopWebApp.ViewModels
@model LoginViewModel
@{
ViewData["Title"] = "Login";
}
<div class="row">
<div class="col-md-6 offset-3">
<p>
<h4>Log in to your account</h4>
</p>
@if(TempData["Error"] != null)
{
<div class="col-md-12 alert alert-danger">
<span><b>Sorry!</b> - @TempData["Error"]</span>
</div>
}
<div class="row">
<div class="col-md-8 offset-2">
<form asp-action="Login">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="EmailAddress" class="control-label"></label>
<input asp-for="EmailAddress" class="form-control">
<span asp-validation-for="EmailAddress" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Password" class="control-label"></label>
<input asp-for="Password" class="form-control" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<div class="form-group">
<input class="btn btn-outline-success float right" type="submit" value="Log in" />
<a class="btn btn-outline-secondary" asp-controller="Club" asp-action="Index">Cancel</a>
</div>
</form>
</div>
</div>
</div>
</div>
================================================
FILE: RunGroopWebApp/Views/Account/Register.cshtml
================================================
@using RunGroopWebApp.ViewModels
@model RegisterViewModel
@{
ViewData["Title"] = "Sign up";
}
<div class="row">
<div class="col-md-6 offset-3">
<p>
<h4>Sign up for a new account</h4>
</p>
@if (TempData["Error"] != null)
{
<div class="col-md-12 alert alert-danger">
<span><b>Sorry!</b> - @TempData["Error"] </span>
</div>
}
<div class="row">
<div class="col-md-8 offset-2">
<form asp-action="Register">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="EmailAddress" class="control-label"></label>
<input asp-for="EmailAddress" class="form-control" />
<span asp-validation-for="EmailAddress" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Password" class="control-label"></label>
<input asp-for="Password" class="form-control" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ConfirmPassword" class="control-label"></label>
<input asp-for="ConfirmPassword" class="form-control" />
<span asp-validation-for="ConfirmPassword" class="text-danger"></span>
</div>
<div class="form-group">
<input class="btn btn-outline-success float-right" type="submit" value="Sign up" />
<a class="btn btn-outline-secondary" asp-controller="Race" asp-action="Index">Cancel</a>
</div>
</form>
</div>
</div>
</div>
</div>
================================================
FILE: RunGroopWebApp/Views/Account/Welcome.cshtml
================================================
@using RunGroopWebApp.ViewModels
@model WelcomeViewModel
@*
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
}
<section>
<div class="container">
<form class="row justify-content-around">
<!--end of col-->
<div class="col col-lg-9 tab-content">
<div id="first">
<div class="row align-items-center mb-5">
<div class="col-12 col-md-7">
<h6 class="title-decorative">Step One</h6>
<h3 class="h1">Upload A Picture</h3>
<span class="lead">Let's begin by uploading a picture. Users that upload pictures run more!</span>
</div>
<!--end of col-->
<div class="media flex-wrap mb-0 align-items-center">
@*<img alt="Image" src="@imageU" class="avatar avatar-lg mb-3 mb-md-0" />*@
<div class="media-body">
<form asp-action="EditProfile" enctype="multipart/form-data">
<label asp-for="Image" class="custom-file mb-2" for="file2">
<input asp-for="Image" type="file" id="file2" class="custom-file-input height-0" oninput="submitProfileImage();" />
<span class="btn btn-primary"><i class="icon-upload-to-cloud"> </i>Upload</span>
<span asp-validation-for="Image" class="text-danger"></span>
<button id="submit-image-button" type="submit" hidden></button>
</label>
<div>
<small>For best results, use an image at least 256px by 256px in either .jpg or .png format</small>
</div>
</form>
</div>
</div>
<!--end of col-->
</div>
</div>
</div>
</form>
</div>
</section>
================================================
FILE: RunGroopWebApp/Views/Club/Create.cshtml
================================================
@using RunGroopWebApp.Data.Enum
@using RunGroopWebApp.ViewModels
@model CreateClubViewModel
@*
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
}
<div class="navbar-container">
</div>
<div class="main-container">
<section class="space-sm">
<div class="container">
<div class="row mb-5">
<!--end of col-->
</div>
<!--end of row-->
<div class="row flex-md-row card card-md">
<div class="card-body bg-secondary">
<div class="text-center mb-5">
<h1 class="h2 mb-2">Create your own running club</h1>
<span>Bring together runners in your community</span>
</div>
<div class="row justify-content-center">
<div class="col-6 col-lg-5">
<form method="post" asp-action="Create" enctype="multipart/form-data">
<input type="hidden" id="AppUserId" name="AppUserId" asp-for="AppUserId" />
<div class="form-row form-group">
<div class="col">
<input asp-for="Title" class="form-control form-control-lg" placeholder="Title" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="col">
<select asp-for="ClubCategory" asp-items="@Html.GetEnumSelectList<ClubCategory>()" class="form-control form-control-lg">
<option>--Select--</option>
</select>
<span asp-validation-for="ClubCategory" class="text-danger"></span>
</div>
</div>
<div class="form-row form-group">
<div class="col">
<input asp-for="Description" class="form-control form-control-lg" placeholder="Description" />
<span asp-validation-for="Description" class="text-danger"></span>
</div>
</div>
<div class="form-row form-group">
<div class="col">
<input asp-for="Address.Street" class="form-control form-control-lg" placeholder="Street" />
<span asp-validation-for="Address.Street" class="text-danger"></span>
</div>
</div>
<div class="form-row form-group">
<div class="col">
<input asp-for="Address.City" class="form-control form-control-lg" placeholder="City" />
<span asp-validation-for="Address.City" class="text-danger"></span>
</div>
<div class="col">
<input asp-for="Address.State" class="form-control form-control-lg" placeholder="State" />
<span asp-validation-for="Address.State" class="text-danger"></span>
</div>
</div>
<div class="form-row form-group">
<div class="col">
<input asp-for="Image" type="file" class="form-control form-control-lg" placeholder="Image" />
<span asp-validation-for="Image" class="text-danger"></span>
</div>
</div>
<div class="form-row form-group">
<div class="col">
<button class="btn btn-block btn-success btn-lg" type="submit">Create Account</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<!--end of container-->
</section>
<!--end of section-->
</div>
================================================
FILE: RunGroopWebApp/Views/Club/Delete.cshtml
================================================
@using RunGroopWebApp.Data.Enum
@model Club
<h1>Are you sure you want to delete this club?</h1>
<form method="post" asp-action="Delete" enctype="multipart/form-data">
<input type="hidden" value="AddressId" id="AddressId" />
<div class="form-group">
<label asp-for="Title">Title</label>
<input asp-for="Title" class="form-control" placeholder="Title">
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Description">Description</label>
<input asp-for="Description" class="form-control" placeholder="Description">
<span asp-validation-for="Description" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ClubCategory">Club Category</label>
<select asp-for="ClubCategory" asp-items="@Html.GetEnumSelectList<ClubCategory>()" class="form-control">
<option selected="selected" value="">--Select--</option>
</select>
<span asp-validation-for="ClubCategory" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Address.Street">Street</label>
<input asp-for="Address.Street" class="form-control" placeholder="Street">
<span asp-validation-for="Address.Street" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Address.City">City</label>
<input asp-for="Address.City" class="form-control" placeholder="City">
<span asp-validation-for="Address.Street" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Address.State">State</label>
<input asp-for="Address.State" class="form-control" placeholder="Street">
<span asp-validation-for="Address.State" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Image">Image</label>
<input asp-for="Image" type="file" class="form-control" placeholder="Image">
<span asp-validation-for="Image" class="text-danger"></span>
</div>
</form>
<div class="form-group">
<form action="Delete" method="post">
<input type="hidden" asp-for="Id" />
<input type="submit" value="Confirm" class="btn btn-danger float-right mt-3" />
</form>
</div>
================================================
FILE: RunGroopWebApp/Views/Club/DetailClub.cshtml
================================================
@model Club
@*
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
}
<div class="main-container">
<nav aria-label="breadcrumb" role="navigation" class="bg-primary text-white">
<div class="container">
<div class="row justify-content-center">
<div class="col">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="index.html">Home</a>
</li>
<li class="breadcrumb-item"><a href="pages-app.html">Find</a>
</li>
<li class="breadcrumb-item active" aria-current="page">Runnings Clubs in @Model.Address.City, @Model.Address.State</li>
</ol>
</div>
<!--end of col-->
</div>
<!--end of row-->
</div>
<!--end of container-->
</nav>
<section class="bg-white space-sm">
<div class="container">
<div class="row">
<div class="col-lg-7 mb-4 mb-sm-0">
<img alt="Image" src="@Model.Image" class="rounded img-fluid" />
</div>
<!--end of col-->
<div class="col-lg-4 d-flex flex-column justify-content-between mr-auto ml-auto">
<div>
<h1 class="mb-2">@Model.Title</h1>
<h2 class="lead mb-3">@Model.Address.City, @Model.Address.State</h2>
<div>
<span class="badge badge-secondary mr-3">@Model.ClubCategory</span>
</div>
<div>
<ul class="list-inline text-small d-inline-block mb-3">
<li class="list-inline-item"><i class="icon-thumbs-up"></i> 214</li>
<li class="list-inline-item"><i class="icon-message"></i> 6</li>
</ul>
</div>
</div>
<div>
<div class="btn-group mb-2">
<button type="button" class="btn btn-success btn-lg">Join Club</button>
<button type="button" class="btn btn-success dropdown-toggle dropdown-toggle-split dropdown-toggle-no-arrow" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="icon-dots-three-horizontal"></i>
<span class="sr-only">Toggle Dropdown</span>
</button>
<div class="dropdown-menu dropdown-menu-right dropdown-menu-sm">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Separated link</a>
</div>
</div>
</div>
</div>
<!--end of col-->
</div>
<!--end of row-->
</div>
<!--end of container-->
</section>
<!--end of section-->
<section class="space-sm">
<div class="container">
<div class="row justify-content-between">
<div class="col-12 col-md-8 col-lg-7">
<h5 class="mb-4">Overview</h5>
<article>
@Model.Description
</article>
<hr>
<h5 class="mb-4">Discussion</h5>
<div class="card">
<div class="card-header bg-secondary d-flex justify-content-between">
<button class="btn btn-secondary" type="button" data-target="#comment-reply" data-toggle="collapse" aria-expanded="false" aria-controls="comment-reply">Post a reply</button>
<form class="d-flex align-items-center">
<span class="mr-2 text-muted text-small text-nowrap">Sort by:</span>
<select class="custom-select">
<option value="alpha">Alphabetical</option>
<option value="old-new" selected>Newest</option>
<option value="new-old">Popular</option>
<option value="recent">Recently Updated</option>
</select>
</form>
</div>
<div class="collapse" id="comment-reply">
<form class="card-body">
<div class="form-group">
<textarea class="form-control from-control-lg" id="comment-reply-text" name="comment-reply" rows="4" placeholder="Type your reply here"></textarea>
</div>
<div class="mb-2">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" name="notify-reply" id="check-notify">
<label class="custom-control-label text-small" for="check-notify">Notify me when someone replies</label>
</div>
</div>
<div class="d-flex align-items-center">
<button type="submit" class="btn btn-success mr-3">Submit reply</button>
<a href="#comment-reply" class="text-small text-muted" data-toggle="collapse" aria-expanded="true" aria-controls="comment-reply">Cancel</a>
</div>
</form>
</div>
<ul class="list-group list-group-flush list-group-comments">
@* <li class="list-group-item py-4">
<div class="media">
<img alt="Image" src="assets/img/avatar-female-2.jpg" class="avatar avatar-sm" />
<div class="media-body">
<div class="mb-2">
<span class="h6 mb-0">Kelly Fraiser</span>
<span class="text-muted">Making awesome products</span>
</div>
<p>
Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.
</p>
<div class="d-flex align-items-center">
<div class="mr-2">
<button class="btn btn-sm btn-outline-primary">Reply</button>
<button class="btn btn-sm btn-outline-primary"><i class="icon-thumbs-up"></i> (2)</button>
</div>
<small class="text-muted">1st Dec 2017 • 10:15am</small>
</div>
</div>
</div>
</li>
<li class="list-group-item py-4">
<div class="media">
<img alt="Image" src="assets/img/avatar-male-6.jpg" class="avatar avatar-sm" />
<div class="media-body">
<div class="mb-2">
<span class="h6 mb-0">Tim Lester</span>
<span class="text-muted">Interface Designer </span>
</div>
<p>
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.
</p>
<div class="d-flex align-items-center">
<div class="mr-2">
<button class="btn btn-sm btn-outline-primary">Reply</button>
<button class="btn btn-sm btn-outline-primary"><i class="icon-thumbs-up"></i>
</button>
</div>
<small class="text-muted">1st Dec 2017 • 10:15am</small>
</div>
</div>
</div>
<div class="media">
<img alt="Image" src="assets/img/avatar-female-5.jpg" class="avatar avatar-sm" />
<div class="media-body">
<div class="mb-2">
<span class="h6 mb-0">Carly Pemberton</span>
<span class="text-muted">Freelance Product Engineer</span>
</div>
<p>
Omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus
</p>
<div class="d-flex align-items-center">
<div class="mr-2">
<button class="btn btn-sm btn-outline-primary">Reply</button>
<button class="btn btn-sm btn-outline-primary"><i class="icon-thumbs-up"></i>(4)</button>
</div>
<small class="text-muted">1st Dec 2017 • 10:15am</small>
</div>
</div>
</div>
<div class="media">
<img alt="Image" src="assets/img/graphic-product-paydar-thumb.jpg" class="avatar avatar-sm" />
<div class="media-body">
<div class="mb-2">
<span class="h6 mb-0">Luke Carol</span>
<span class="text-muted">Product Designer</span>
</div>
<p>
Adipisci velit, sed quia non numquam eius modi tempora
</p>
<div class="d-flex align-items-center">
<div class="mr-2">
<button class="btn btn-sm btn-outline-primary">Reply</button>
<button class="btn btn-sm btn-outline-primary"><i class="icon-thumbs-up"></i>
</button>
</div>
<small class="text-muted">1st Dec 2017 • 10:15am</small>
</div>
</div>
</div>
</li>
<li class="list-group-item py-4">
<div class="media">
<img alt="Image" src="assets/img/avatar-male-3.jpg" class="avatar avatar-sm" />
<div class="media-body">
<div class="mb-2">
<span class="h6 mb-0">Pip Thompson</span>
<span class="text-muted">Development at Kin</span>
</div>
<p>
Natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto
</p>
<div class="d-flex align-items-center">
<div class="mr-2">
<button class="btn btn-sm btn-outline-primary">Reply</button>
<button class="btn btn-sm btn-outline-primary"><i class="icon-thumbs-up"></i> (1)</button>
</div>
<small class="text-muted">1st Dec 2017 • 10:15am</small>
</div>
</div>
</div>
</li>
<li class="list-group-item py-4">
<div class="media">
<img alt="Image" src="assets/img/avatar-male-1.jpg" class="avatar avatar-sm" />
<div class="media-body">
<div class="mb-2">
<span class="h6 mb-0">Daniel Cameron</span>
<span class="text-muted">Industrial Designer at Kin</span>
</div>
<p>
Nam HTML tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est
</p>
<div class="d-flex align-items-center">
<div class="mr-2">
<button class="btn btn-sm btn-outline-primary">Reply</button>
<button class="btn btn-sm btn-outline-primary"><i class="icon-thumbs-up"></i> (1)</button>
</div>
<small class="text-muted">1st Dec 2017 • 10:15am</small>
</div>
</div>
</div>
</li>*@
</ul>
</div>
</div>
<!--end of col-->
<div class="col-12 col-md-4">
@* <div class="card card-borderless bg-secondary">
<a class="card-body" href="#">
<div class="d-flex justify-content-between mb-3">
<img alt="Image" src="assets/img/logo-w-gradient.svg" />
<span class="title-decorative">Sponsor</span>
</div>
<span class="h6">A robust suite of styled elements and pages for Bootstrap 4</span>
</a>
</div>*@
<!-- end card -->
<div class="card">
<ul class="list-group list-group-flush">
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div><i class="icon-text-document mr-1"></i> Created</div>
<span>17/11/2017</span>
</div>
</li>
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div><i class="icon-edit mr-1"></i> Last updated</div>
<span>23/12/2017</span>
</div>
</li>
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div><i class="icon-thumbs-up mr-1"></i> Owner</div>
<span>214</span>
</div>
</li>
<li class="list-group-item">
<div class="d-flex justify-content-between">
<div><i class="icon-share mr-1"></i> Shares</div>
<span>52</span>
</div>
</li>
</ul>
</div>
@* <div class="card">
<div class="card-header d-flex justify-content-between">
<div>
<span class="h6">Contributors</span>
</div>
<a href="#">View all ›</a>
</div>
<div class="card-body">
<ul class="list-unstyled list-spacing-sm">
<li>
<a class="media" href="#">
<img alt="Image" src="assets/img/avatar-male-1.jpg" class="avatar avatar-sm mr-3" />
<div class="media-body">
<span class="h6 mb-0">Daniel Cameron</span>
<span class="text-muted">Product Designer</span>
</div>
</a>
</li>
<li>
<a class="media" href="#">
<img alt="Image" src="assets/img/avatar-female-1.jpg" class="avatar avatar-sm mr-3" />
<div class="media-body">
<span class="h6 mb-0">Caitlyn Halsy</span>
<span class="text-muted">Marketing Professional</span>
</div>
</a>
</li>
<li>
<a class="media" href="#">
<img alt="Image" src="assets/img/avatar-male-2.jpg" class="avatar avatar-sm mr-3" />
<div class="media-body">
<span class="h6 mb-0">Toby Marsh</span>
<span class="text-muted">Developer</span>
</div>
</a>
</li>
<li>
<a class="media" href="#">
<img alt="Image" src="assets/img/avatar-female-2.jpg" class="avatar avatar-sm mr-3" />
<div class="media-body">
<span class="h6 mb-0">Lucille Freebody</span>
<span class="text-muted">Graphic Designer</span>
</div>
</a>
</li>
</ul>
</div>
</div>*@
<!-- end card -->
@*<div class="card">
<div class="card-header d-flex justify-content-between">
<div>
<span class="h6">Related Products</span>
</div>
<a href="#">View all ›</a>
</div>
<div class="card-body">
<ul class="list-unstyled list-spacing-sm">
<li>
<div class="media">
<a href="#">
<img alt="Image" src="assets/img/graphic-product-bench-thumb.jpg" class="avatar avatar-square rounded mr-3" />
</a>
<div class="media-body">
<a href="#">
<span class="h6">Bench</span>
</a>
<span class="badge badge-secondary">Productivity</span>
<div class="text-muted">
<ul class="list-inline">
<li class="list-inline-item">
<small><i class="icon-heart"></i> 373</small>
</li>
<li class="list-inline-item">
<small><i class="icon-message"></i> 62</small>
</li>
</ul>
</div>
</div>
</div>
</li>
<li>
<div class="media">
<a href="#">
<img alt="Image" src="assets/img/graphic-product-kin-thumb.jpg" class="avatar avatar-square rounded mr-3" />
</a>
<div class="media-body">
<a href="#">
<span class="h6">Kin</span>
</a>
<span class="badge badge-secondary">Lifestyle</span>
<div class="text-muted">
<ul class="list-inline">
<li class="list-inline-item">
<small><i class="icon-heart"></i> 84</small>
</li>
<li class="list-inline-item">
<small><i class="icon-message"></i> 21</small>
</li>
</ul>
</div>
</div>
</div>
</li>
<li>
<div class="media">
<a href="#">
<img alt="Image" src="assets/img/graphic-product-paydar-thumb.jpg" class="avatar avatar-square rounded mr-3" />
</a>
<div class="media-body">
<a href="#">
<span class="h6">Paydar</span>
</a>
<span class="badge badge-secondary">Productivity</span>
<div class="text-muted">
<ul class="list-inline">
<li class="list-inline-item">
<small><i class="icon-heart"></i> 253</small>
</li>
<li class="list-inline-item">
<small><i class="icon-message"></i> 19</small>
</li>
</ul>
</div>
</div>
</div>
</li>
<li>
<div class="media">
<a href="#">
<img alt="Image" src="assets/img/graphic-product-pipeline-thumb.jpg" class="avatar avatar-square rounded mr-3" />
</a>
<div class="media-body">
<a href="#">
<span class="h6">pipeline.js</span>
</a>
<span class="badge badge-secondary">Development</span>
<div class="text-muted">
<ul class="list-inline">
<li class="list-inline-item">
<small><i class="icon-heart"></i> 84</small>
</li>
<li class="list-inline-item">
<small><i class="icon-message"></i> 25</small>
</li>
</ul>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>*@
<!-- end card -->
</div>
<!--end of col-->
</div>
<!--end of row-->
</div>
<!--end of container-->
</section>
================================================
FILE: RunGroopWebApp/Views/Club/Edit.cshtml
================================================
@using RunGroopWebApp.Data.Enum
@using RunGroopWebApp.ViewModels
@model EditClubViewModel
<form method="post" asp-action="Edit" enctype="multipart/form-data">
<input type="hidden" value="AddressId" id="AddressId" />
<div class="form-group">
<label asp-for="Title">Title</label>
<input asp-for="Title" class="form-control" placeholder="Title">
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Description">Description</label>
<input asp-for="Description" class="form-control" placeholder="Description">
<span asp-validation-for="Description" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ClubCategory">Club Category</label>
<select asp-for="ClubCategory" asp-items="@Html.GetEnumSelectList<ClubCategory>()" class="form-control">
<option selected="selected" value="">--Select--</option>
</select>
<span asp-validation-for="ClubCategory" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Address.Street">Street</label>
<input asp-for="Address.Street" class="form-control" placeholder="Street">
<span asp-validation-for="Address.Street" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Address.City">City</label>
<input asp-for="Address.City" class="form-control" placeholder="City">
<span asp-validation-for="Address.Street" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Address.State">State</label>
<input asp-for="Address.State" class="form-control" placeholder="Street">
<span asp-validation-for="Address.State" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Image">Image</label>
<input asp-for="Image" type="file" class="form-control" placeholder="Image">
<span asp-validation-for="Image" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
================================================
FILE: RunGroopWebApp/Views/Club/Index.cshtml
================================================
@using RunGroopWebApp.Data.Enum
@using RunGroopWebApp.Extensions
@using RunGroopWebApp.ViewModels
@model IndexClubViewModel
@{
bool isAuthenticated = User.Identity?.IsAuthenticated == true;
int resultStart = ((Model.Page - 1) * Model.PageSize) + 1;
int resultEnd = Math.Min(resultStart + Model.PageSize - 1, Model.TotalClubs);
bool isValidPage = resultStart <= Model.TotalClubs;
var prevDisabled = !Model.HasPreviousPage ? "disabled" : "";
var nextDisabled = !Model.HasNextPage ? "disabled" : "";
}
<section class="space-sm flush-with-above">
<div class="container">
<div class="row">
<div class="col text-center">
<p>Club Categories</p>
<div class="mb-3">
<a type="button" class="btn btn-secondary mb-1" asp-action="Index" asp-route-page="1" asp-route-category="-1">All</a>
@foreach (var category in Html.GetEnumSelectList<ClubCategory>())
{
<a type="button" class="btn btn-secondary mb-1" asp-action="Index" asp-route-page="1" asp-route-category="@category.Value">@category.Text</a>
}
</div>
</div>
</div>
</div>
<div class="container">
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
@if (isValidPage)
{
<a type="button" class="btn btn-sm btn-outline-primary @prevDisabled"
asp-action="Index" asp-route-page="@(Model.Page - 1)" asp-route-category="@Model.Category">
Prev
</a>
<a type="button" class="btn btn-sm btn-outline-primary @nextDisabled"
asp-action="Index" asp-route-page="@(Model.Page + 1)" asp-route-category="@Model.Category">
Next
</a>
<span class="text-muted text-small">Results @resultStart - @resultEnd of @Model.TotalClubs</span>
}
</div>
</div>
<ul class="row feature-list feature-list-sm">
@foreach (var club in Model.Clubs)
{
<li class="col-12 col-md-6 col-lg-4">
<div class="card">
<a type="button" asp-controller="Club" asp-action="DetailClub" asp-route-runningClub="@club.Title.GenerateSlug()" asp-route-id="@club.Id">
@if(@club.Image != null)
{
<img class="card-img-top" src="@club.Image" alt="Card image cap">
}
else
{
<img class="card-img-top" src="/img/rungroopclub.png" alt="Card image cap">
}
</a>
<div class="card-body">
<h4 class="card-title">@club.Title</h4>
<p class="card-text">@club.Description</p>
<p class="card-text">@club.Address.City, @club.Address.State</p>
</div>
<div class="card-footer card-footer-borderless d-flex justify-content-between">
<div>
<small>@club.ClubCategory</small>
</div>
@if (isAuthenticated && User.IsInRole("admin"))
{
<div>
<a type="button" class="btn btn-sm btn-outline-info" asp-controller="Club" asp-action="Edit" asp-route-id="@club.Id">
Edit
</a>
<a type="button" class="btn btn-sm btn-outline-danger" asp-controller="Club" asp-action="Delete" asp-route-id="@club.Id">
Delete
</a>
</div>
}
</div>
</div>
</li>
}
</ul>
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
@if (isValidPage)
{
<a type="button" class="btn btn-sm btn-outline-primary @prevDisabled"
asp-action="Index" asp-route-page="@(Model.Page - 1)" asp-route-category="@Model.Category">
Prev
</a>
<a type="button" class="btn btn-sm btn-outline-primary @nextDisabled"
asp-action="Index" asp-route-page="@(Model.Page + 1)" asp-route-category="@Model.Category">
Next
</a>
<span class="text-muted text-small">Results @resultStart - @resultEnd of @Model.TotalClubs</span>
}
</div>
</div>
</div>
</section>
================================================
FILE: RunGroopWebApp/Views/Club/ListClubsByCity.cshtml
================================================
@using Microsoft.AspNetCore.Identity
@inject SignInManager<AppUser> SignInManager
@using RunGroopWebApp.ViewModels
@model ListClubByCityViewModel
<section class="space-sm flush-with-above">
<div class="container">
@if (Model.NoClubWarning == true)
{
<h1 class="fw-light">
There are no running clubs in your area! <a asp-area="" asp-controller="Account"
asp-action="Login">Login</a> and create one!
</h1>
}
else
{
<h1>Running Clubs in @Model.City, @Model.State</h1>
}
<ul class="row feature-list feature-list-sm">
@foreach (var club in Model.Clubs)
{
<li class="col-12 col-md-6 col-lg-4">
<div class="card">
<a type="button" asp-controller="Club" asp-action="Detail" asp-route-id="@club.Id">
<img class="card-img-top" src="@club.Image" alt="Card image cap">
</a>
<div class="card-body">
<h4 class="card-title">@club.Title</h4>
<p class="card-text">@club.Description</p>
</div>
<div class="card-footer card-footer-borderless d-flex justify-content-between">
<div>
<small>@club.ClubCategory</small>
</div>
@if (SignInManager.IsSignedIn(User) && User.IsInRole("admin"))
{
<div>
<a type="button" class="btn btn-sm btn-outline-info" asp-controller="Club" asp-action="Edit" asp-route-id="@club.Id">
Edit
</a>
<a type="button" class="btn btn-sm btn-outline-danger" asp-controller="Club" asp-action="Delete" asp-route-id="@club.Id">
Delete
</a>
</div>
}
</div>
</div>
</li>
}
</ul>
</div>
</section>
================================================
FILE: RunGroopWebApp/Views/Club/ListClubsByState.cshtml
================================================
@using Microsoft.AspNetCore.Identity
@inject SignInManager<AppUser> SignInManager
@using RunGroopWebApp.ViewModels
@model ListClubByStateViewModel
<section class="space-sm flush-with-above">
<div class="container">
@if (Model.NoClubWarning == true)
{
<h1 class="fw-light">
There are no running clubs in your area! <a asp-area="" asp-controller="Account"
asp-action="Login">Login</a> and create one!
</h1>
}
else
{
<h1>Running Clubs in @Model.State</h1>
}
<ul class="row feature-list feature-list-sm">
@foreach (var club in Model.Clubs)
{
<li class="col-12 col-md-6 col-lg-4">
<div class="card">
<a type="button" asp-controller="Club" asp-action="Detail" asp-route-id="@club.Id">
<img class="card-img-top" src="@club.Image" alt="Card image cap">
</a>
<div class="card-body">
<h4 class="card-title">@club.Title</h4>
<p class="card-text">@club.Description</p>
</div>
<div class="card-footer card-footer-borderless d-flex justify-content-between">
<div>
<small>@club.ClubCategory</small>
</div>
@if (SignInManager.IsSignedIn(User) && User.IsInRole("admin"))
{
<div>
<a type="button" class="btn btn-sm btn-outline-info" asp-controller="Club" asp-action="Edit" asp-route-id="@club.Id">
Edit
</a>
<a type="button" class="btn btn-sm btn-outline-danger" asp-controller="Club" asp-action="Delete" asp-route-id="@club.Id">
Delete
</a>
</div>
}
</div>
</div>
</li>
}
</ul>
</div>
</section>
================================================
FILE: RunGroopWebApp/Views/Club/RunningClubsByCityDirectory.cshtml
================================================
@using RunGroopWebApp.ViewModels
@model RunningClubByCity
@{
var cities = Model.Cities.DistinctBy(city => city.CityName);
}
<section class="container">
<h1>Find running clubs in your city</h1>
<div class="row">
<form class="card card-sm">
<div class="card-body row no-gutters align-items-center">
<div class="col-auto">
<i class="icon-magnifying-glass h4 text-body"></i>
</div>
<!--end of col-->
<div class="col">
<input class="form-control form-control-sm form-control-borderless" type="search" placeholder="Search your city" oninput="filterList(this.value);">
</div>
</div>
</form>
<!--end of col-->
</div>
<ul class="list-unstyled">
@foreach (var val in cities)
{
<li class="li-item">
<a asp-controller="Club" asp-action="ListClubsByCity" asp-route-state="@val.StateCode" asp-route-city="@val.CityName">@val.CityName</a>
</li>
}
</ul>
</section>
<script type="text/javascript">
const elements = [...document.getElementsByClassName("li-item")]
.map(elem => ({elem, text: elem.querySelector("a").innerText.toUpperCase()}));
function filterList(search) {
const term = search.toUpperCase();
for (const {elem, text} of elements) {
elem.style.display = text.includes(term) ? "" : "none";
}
}
</script>
================================================
FILE: RunGroopWebApp/Views/Club/RunningClubsByStateDirectory.cshtml
================================================
@using RunGroopWebApp.ViewModels
@model RunningClubByState
<section class="container">
<h1>Find running clubs in your state</h1>
<div class="row">
<form class="card card-sm">
<div class="card-body row no-gutters align-items-center">
<div class="col-auto">
<i class="icon-magnifying-glass h4 text-body"></i>
</div>
<!--end of col-->
<div class="col">
<input class="form-control form-control-sm form-control-borderless" type="search" placeholder="Search your state" oninput="filterList(this.value);">
</div>
</div>
</form>
<!--end of col-->
</div>
<ul class="list-unstyled">
@foreach (var val in Model.States)
{
<li class="li-item">
<a asp-controller="Club" asp-action="ListClubsByState" asp-route-state="@val.StateName">@val.StateName</a>
</li>
}
</ul>
</section>
<script type="text/javascript">
const elements = [...document.getElementsByClassName("li-item")]
.map(elem => ({elem, text: elem.querySelector("a").innerText.toUpperCase()}));
function filterList(search) {
const term = search.toUpperCase();
for (const {elem, text} of elements) {
elem.style.display = text.includes(term) ? "" : "none";
}
}
</script>
================================================
FILE: RunGroopWebApp/Views/Club/RunningClubsByStateForCityDirectory.cshtml
================================================
@using RunGroopWebApp.ViewModels
@model RunningClubByState
<section class="container">
<h1>Select your state</h1>
<div class="row">
<form class="card card-sm">
<div class="card-body row no-gutters align-items-center">
<div class="col-auto">
<i class="icon-magnifying-glass h4 text-body"></i>
</div>
<!--end of col-->
<div class="col">
<input class="form-control form-control-sm form-control-borderless" type="search" placeholder="Search your state" oninput="filterState(this.value);">
</div>
</div>
</form>
<!--end of col-->
</div>
<div class="row">
<ul class="list-unstyled">
@foreach (var val in Model.States)
{
<li class="li-item">
<a class="state-link" asp-controller="Club" asp-action="RunningClubsByCityDirectory" asp-route-state="@val.StateName">@val.StateName</a>
</li>
}
</ul>
</div>
</section>
<script type="text/javascript">
const elements = [...document.getElementsByClassName("li-item")]
.map(elem => ({elem, text: elem.querySelector("a").innerText.toUpperCase()}));
function filterState(search) {
const term = search.toUpperCase();
for (const {elem, text} of elements) {
elem.style.display = text.includes(term) ? "" : "none";
}
}
</script>
================================================
FILE: RunGroopWebApp/Views/Dashboard/Index.cshtml
================================================
@using Microsoft.AspNetCore.Identity
@inject SignInManager<AppUser> SignInManager
@model RunGroopWebApp.ViewModels.DashboardViewModel
<h1 class="display-4 fw-normal">User Dashboard</h1>
<a type="button" class="btn btn-primary" asp-area="" asp-controller="Club" asp-action="Create">Create Club</a>
<a type="button" class="btn btn-primary" asp-area="" asp-controller="Race" asp-action="Create">Create Race</a>
<a type="button" class="btn btn-primary" asp-area="" asp-controller="Dashboard" asp-action="EditUserProfile">Edit User Profile</a>
<div class="album py-5 bg-light">
<div class="container">
<h2 class="display-4 fw-normal">Your races</h2>
<div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 g-3">
@foreach (var item in Model.Races)
{
<div class="col-md-4">
<div class="card mb-4 box-shadow">
<img class="card-img-top" src="@item.Image" width="100%" height="225" alt="Card image cap">
<div class="card-body">
<p class="card-text">@item.Title</p>
<p class="card-text">@item.Description</p>
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group">
<a type="btn btn-success" asp-controller="Club" asp-action="Detail" asp-route-id="@item.Id"
class="btn btn-sm btn-outline-secondary">View</a>
@if (SignInManager.IsSignedIn(User))
{
<a asp-controller="Race" asp-action="Edit" asp-route-id="@item.Id" class="btn btn-sm btn-outline-secondary">Edit</a>
<a asp-controller="Race" asp-action="Delete" asp-route-id="@item.Id" class="btn btn-sm btn-outline-secondary">Delete</a>
}
</div>
<small class="text-muted">@item.RaceCategory</small>
</div>
</div>
</div>
</div>
}
</div>
<h2 class="display-4 fw-normal">Your Clubs</h2>
<div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 g-3">
@foreach (var item in Model.Clubs)
{
<div class="col-md-4">
<div class="card mb-4 box-shadow">
<img class="card-img-top" src="@item.Image" width="100%" height="225" alt="Card image cap">
<div class="card-body">
<p class="card-text">@item.Title</p>
<p class="card-text">@item.Description</p>
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group">
<a type="btn btn-success" asp-controller="Club" asp-action="Detail" asp-route-id="@item.Id"
class="btn btn-sm btn-outline-secondary">View</a>
@if (SignInManager.IsSignedIn(User))
{
<a asp-controller="Club" asp-action="Edit" asp-route-id="@item.Id" class="btn btn-sm btn-outline-secondary">Edit</a>
<a asp-controller="Club" asp-action="Delete" asp-route-id="@item.Id" class="btn btn-sm btn-outline-secondary">Delete</a>
}
</div>
<small class="text-muted">@item.ClubCategory</small>
</div>
</div>
</div>
</div>
}
</div>
</div>
</div>
================================================
FILE: RunGroopWebApp/Views/Home/Index.cshtml
================================================
@using RunGroopWebApp.ViewModels
@model HomeViewModel
@{
ViewData["Title"] = "Home Page";
}
<section class="bg-dark space-lg" data-jarallax data-speed="0.2">
<img alt="Image" src="/img/photo-road.jpg" class="bg-image position-absolute opacity-20" />
<div class="container">
<div class="row align-items-center justify-content-between">
<div class="col-12 col-md-6 col-lg-5 section-intro">
<h1 class="display-3">Find a running group</h1>
<span class="lead">
A community of devoted runners, passionate about running and life. Ready to find your accountability partner?
</span>
</div>
<!--end of col-->
<div class="col-12 col-md-6 col-lg-5">
<div class="card">
<div class="card-body">
<form asp-action="Index">
<div class="form-group">
<label asp-for="Register.UserName">Username</label>
<input asp-for="Register.UserName" type="text" class="form-control form-control-lg" placeholder="Pick a username">
<span asp-validation-for="Register.UserName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Register.Email">Email address</label>
<input asp-for="Register.Email" type="email" class="form-control form-control-lg" placeholder="Enter email">
<span asp-validation-for="Register.Email" class="text-danger"></span>
<small id="emailHelp" class="form-text">We'll never share your email with anyone else.</small>
</div>
<div class="form-group">
<label asp-for="Register.Password">Password</label>
<input asp-for="Register.Password" type="password" class="form-control form-control-lg" placeholder="Password">
<span asp-validation-for="Register.Password" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Register.ZipCode">Zip Code</label>
<input asp-for="Register.ZipCode" type="text" list="datlistOptions" id="registerLocation" class="form-control form-control-lg" placeholder="">
<div id="datalistOptions">
</div>
<span asp-validation-for="Register.ZipCode" class="text-danger"></span>
</div>
@* <div class="mb-3">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" value="agree" name="agree-terms" id="check-agree">
<label class="custom-control-label text-small" for="check-agree">
I agree to the <a href="#">Terms & Conditions</a>
</label>
</div>
</div>*@
<button type="submit" class="btn btn-lg btn-success btn-block">Sign up for RunGroop</button>
</form>
</div>
</div>
</div>
</div>
<!--end of row-->
</div>
<!--end of container-->
</section>
<!--end of section-->
<section>
<div class="container">
@if (Model.Clubs == null)
{
<h1 class="fw-light">
There are no running clubs in your area! <a asp-area="" asp-controller="Account"
asp-action="Login">Login</a> and create one!
</h1>
}
else
{
<div class="row justify-content-between mb-5">
<div class="col-auto">
<h3>Running clubs near @Model.City, @Model.State</h3>
</div>
<!--end of col-->
<div class="col-auto">
<a href="#" class="btn btn-outline-primary">View all</a>
</div>
<!--end of col-->
</div>
<ul class="row feature-list feature-list-sm">
@foreach (var item in Model.Clubs)
{
<li class="col-12 col-md-6 col-lg-4">
<div class="card">
<a href="#">
<img class="card-img-top" src="@item.Image" alt="Card image cap">
</a>
<div class="card-body">
<a href="#">
<h4 class="card-title">@item.Title</h4>
<p class="card-text text-body">@item.Description</p>
</a>
</div>
<div class="card-footer card-footer-borderless d-flex justify-content-between">
<div class="text-small">
<ul class="list-inline">
<li class="list-inline-item"><i class="icon-heart"></i> 221</li>
<li class="list-inline-item"><i class="icon-message"></i> 14</li>
</ul>
</div>
<div class="dropup">
<a type="btn btn-success" asp-controller="Race" asp-action="Detail" asp-route-id="@item.Id"
class="btn btn-sm btn-outline-secondary">View</a>
<div class="dropdown-menu dropdown-menu-sm" aria-labelledby="SidekickButton">
<a class="dropdown-item" href="#">Save</a>
<a class="dropdown-item" href="#">Share</a>
<a class="dropdown-item" href="#">Comment</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Report</a>
</div>
</div>
</div>
</div>
</li>
}
</ul>
}
<!--end of row-->
</div>
<!--end of container-->
</section>
================================================
FILE: RunGroopWebApp/Views/Home/Privacy.cshtml
================================================
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>
<p>Use this page to detail your site's privacy policy.</p>
================================================
FILE: RunGroopWebApp/Views/Home/Register.cshtml
================================================
@using RunGroopWebApp.ViewModels
@model HomeUserCreateViewModel
@{
ViewData["Title"] = "Register Page";
}
<section class="bg-dark space-lg" data-jarallax data-speed="0.2">
<img alt="Image" src="/img/photo-road.jpg" class="bg-image position-absolute opacity-20" />
<div class="container">
<div class="row align-items-center justify-content-between">
<div class="col-12 col-md-6 col-lg-5 section-intro">
<h1 class="display-3">Find a running group</h1>
<span class="lead">
A community of devoted runners, passionate about running and life. Ready to find your accountability partner?
</span>
</div>
<!--end of col-->
<div class="col-12 col-md-6 col-lg-5">
<div class="card">
<div class="card-body">
@if (TempData["Error"] != null)
{
<div class="col-md-12 alert alert-danger">
<span><b>Sorry!</b> - @TempData["Error"] </span>
</div>
}
<form asp-action="Register">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="UserName">Username</label>
<input asp-for="UserName" class="form-control form-control-lg" placeholder="Pick a username">
<span asp-validation-for="UserName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Email">Email address</label>
<input asp-for="Email" class="form-control form-control-lg" placeholder="Enter email">
<span asp-validation-for="Email" class="text-danger"></span>
<small id="emailHelp" class="form-text">We'll never share your email with anyone else.</small>
</div>
<div class="form-group">
<label asp-for="Password">Password</label>
<input asp-for="Password" class="form-control form-control-lg" placeholder="Password">
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<div class="mb-3">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" value="agree" name="agree-terms" id="check-agree">
<label class="custom-control-label text-small" for="check-agree">I agree to the <a href="#">Terms & Conditions</a>
</label>
</div>
</div>
<button type="submit" class="btn btn-lg btn-success btn-block">Sign up for RunGroops</button>
</form>
</div>
</div>
</div>
</div>
<!--end of row-->
</div>
<!--end of container-->
</section>
<!--end of section-->
================================================
FILE: RunGroopWebApp/Views/Race/Create.cshtml
================================================
@using RunGroopWebApp.Data.Enum
@using RunGroopWebApp.ViewModels
@model CreateRaceViewModel
<div class="navbar-container">
</div>
<div class="main-container">
<section class="space-sm">
<div class="container">
<div class="row mb-5">
<!--end of col-->
</div>
<!--end of row-->
<div class="row flex-md-row card card-md">
<div class="card-body bg-secondary">
<div class="text-center mb-5">
<h1 class="h2 mb-2">Create your own race</h1>
<span>Challenge the runners in your community</span>
</div>
<div class="row justify-content-center">
<div class="col-6 col-lg-5">
<form method="post" asp-action="Create" enctype="multipart/form-data">
<input type="hidden" id="AppUserId" name="AppUserId" asp-for="AppUserId" />
<div class="form-row form-group">
<div class="col">
<input asp-for="Title" class="form-control form-control-lg" placeholder="Title" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
</div>
<div class="form-row form-group">
<div class="col">
<input asp-for="Description" class="form-control form-control-lg" placeholder="Description" />
<span asp-validation-for="Description" class="text-danger"></span>
</div>
</div>
<div class="form-row form-group">
<div class="col">
<select asp-for="RaceCategory" asp-items="@Html.GetEnumSelectList<RaceCategory>()" class="form-control">
<option>--Select--</option>
</select>
<span asp-validation-for="RaceCategory" class="text-danger"></span>
</div>
</div>
<div class="form-row form-group">
<div class="col">
<input asp-for="Address.Street" class="form-control form-control-lg" placeholder="Street" />
<span asp-validation-for="Address.Street" class="text-danger"></span>
</div>
</div>
<div class="form-row form-group">
<div class="col">
<input asp-for="Address.City" class="form-control form-control-lg" placeholder="City" />
<span asp-validation-for="Address.City" class="text-danger"></span>
</div>
<div class="col">
<input asp-for="Address.State" class="form-control form-control-lg" placeholder="State" />
<span asp-validation-for="Address.State" class="text-danger"></span>
</div>
</div>
<div class="form-row form-group">
<div class="col">
<input asp-for="Image" type="file" class="form-control form-control-lg" placeholder="Image" />
<span asp-validation-for="Image" class="text-danger"></span>
</div>
</div>
<div class="form-row form-group">
<div class="col">
<button class="btn btn-block btn-success btn-lg" type="submit">Create Account</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<!--end of containe
gitextract_r3gp682_/ ├── .gitignore ├── README.md ├── RunGroopWebApp/ │ ├── ClaimsPrincipalExtensions.cs │ ├── Controllers/ │ │ ├── AccountController.cs │ │ ├── ClubController.cs │ │ ├── DashboardController.cs │ │ ├── HomeController.cs │ │ ├── RaceController.cs │ │ └── UserController.cs │ ├── Data/ │ │ ├── ApplicationDbContext.cs │ │ ├── Enum/ │ │ │ ├── ClubCategory.cs │ │ │ └── RaceCategory.cs │ │ ├── Seed.cs │ │ └── UserRoles.cs │ ├── Extensions/ │ │ ├── NumberExtensions.cs │ │ └── StringExtensions.cs │ ├── Helpers/ │ │ ├── CloudinarySettings.cs │ │ ├── IPInfo.cs │ │ ├── Location.cs │ │ └── StateConverter.cs │ ├── Interfaces/ │ │ ├── IClubRepository.cs │ │ ├── IDashboardRepository.cs │ │ ├── ILocationService.cs │ │ ├── IPhotoService.cs │ │ ├── IRaceRepository.cs │ │ └── IUserRepository.cs │ ├── Migrations/ │ │ ├── 20220215112438_InitialCreate.Designer.cs │ │ ├── 20220215112438_InitialCreate.cs │ │ └── ApplicationDbContextModelSnapshot.cs │ ├── Models/ │ │ ├── Address.cs │ │ ├── AppUser.cs │ │ ├── City.cs │ │ ├── Club.cs │ │ ├── ErrorViewModel.cs │ │ ├── Race.cs │ │ └── State.cs │ ├── Program.cs │ ├── Properties/ │ │ └── launchSettings.json │ ├── Repository/ │ │ ├── ClubRepository.cs │ │ ├── DashboardRepository.cs │ │ ├── RaceRepository.cs │ │ └── UserRepository.cs │ ├── RunGroopWebApp.csproj │ ├── Services/ │ │ ├── LocationService.cs │ │ └── PhotoService.cs │ ├── ViewModels/ │ │ ├── CreateClubViewModel.cs │ │ ├── CreateRaceViewModel.cs │ │ ├── DashboardViewModel.cs │ │ ├── EditClubViewModel.cs │ │ ├── EditProfileViewModel.cs │ │ ├── EditRaceViewModel.cs │ │ ├── HomeUserCreateViewModel.cs │ │ ├── HomeViewModel.cs │ │ ├── IndexClubViewModel.cs │ │ ├── IndexRaceViewModel.cs │ │ ├── ListClubByCityViewModel.cs │ │ ├── ListClubByStateViewModel.cs │ │ ├── LoginViewModel.cs │ │ ├── RegisterViewModel.cs │ │ ├── RunningClubByCity.cs │ │ ├── RunningClubByState.cs │ │ ├── UserDetailViewModel.cs │ │ ├── UserViewModel.cs │ │ └── WelcomeViewModel.cs │ ├── Views/ │ │ ├── Account/ │ │ │ ├── Login.cshtml │ │ │ ├── Register.cshtml │ │ │ └── Welcome.cshtml │ │ ├── Club/ │ │ │ ├── Create.cshtml │ │ │ ├── Delete.cshtml │ │ │ ├── DetailClub.cshtml │ │ │ ├── Edit.cshtml │ │ │ ├── Index.cshtml │ │ │ ├── ListClubsByCity.cshtml │ │ │ ├── ListClubsByState.cshtml │ │ │ ├── RunningClubsByCityDirectory.cshtml │ │ │ ├── RunningClubsByStateDirectory.cshtml │ │ │ └── RunningClubsByStateForCityDirectory.cshtml │ │ ├── Dashboard/ │ │ │ └── Index.cshtml │ │ ├── Home/ │ │ │ ├── Index.cshtml │ │ │ ├── Privacy.cshtml │ │ │ └── Register.cshtml │ │ ├── Race/ │ │ │ ├── Create.cshtml │ │ │ ├── Delete.cshtml │ │ │ ├── DetailRace.cshtml │ │ │ ├── Edit.cshtml │ │ │ └── Index.cshtml │ │ ├── Shared/ │ │ │ ├── Error.cshtml │ │ │ ├── _Layout.cshtml │ │ │ ├── _Layout.cshtml.css │ │ │ └── _ValidationScriptsPartial.cshtml │ │ ├── User/ │ │ │ ├── Detail.cshtml │ │ │ ├── EditProfile.cshtml │ │ │ └── Index.cshtml │ │ ├── _ViewImports.cshtml │ │ └── _ViewStart.cshtml │ ├── appsettings.Development.json │ ├── appsettings.json │ └── wwwroot/ │ ├── css/ │ │ ├── custom.css │ │ ├── entypo.css │ │ ├── socicon.css │ │ └── theme.css │ └── js/ │ ├── aos.js │ ├── bootstrap.js │ ├── custom.js │ ├── flickity.pkgd.js │ ├── prism.js │ ├── scrollMonitor.js │ └── theme.js ├── RunGroopWebApp.Scraper/ │ ├── Data/ │ │ └── ScraperDBContext.cs │ ├── Extensions/ │ │ └── DateTimeExtension.cs │ ├── Interfaces/ │ │ └── IAtraScraper.cs │ ├── Program.cs │ ├── RunGroopWebApp.Scraper.csproj │ └── Services/ │ ├── AtraScraper.cs │ └── MeetupScraper.cs ├── RunGroopWebApp.Tests/ │ ├── Controller/ │ │ └── ClubControllerTests.cs │ ├── Repository/ │ │ └── ClubRepositoryTests.cs │ └── RunGroopWebApp.Tests.csproj └── RunGroopWebApp.sln
SYMBOL INDEX (325 symbols across 72 files)
FILE: RunGroopWebApp.Scraper/Data/ScraperDBContext.cs
class ScraperDBContext (line 11) | public class ScraperDBContext : DbContext
method OnConfiguring (line 19) | protected override void OnConfiguring(DbContextOptionsBuilder optionsB...
FILE: RunGroopWebApp.Scraper/Extensions/DateTimeExtension.cs
class DateTimeExtension (line 10) | public static class DateTimeExtension
method ToDate (line 12) | public static DateTime? ToDate(this string dateTimeStr, params string[...
FILE: RunGroopWebApp.Scraper/Interfaces/IAtraScraper.cs
type IAtraScraper (line 10) | internal interface IAtraScraper
method GetElements (line 12) | IReadOnlyCollection<IWebElement> GetElements();
method IterateOverRaceElements (line 13) | void IterateOverRaceElements();
method Run (line 14) | void Run();
FILE: RunGroopWebApp.Scraper/Services/AtraScraper.cs
class AtraScraper (line 19) | public class AtraScraper : IAtraScraper
method AtraScraper (line 23) | public AtraScraper()
method Run (line 28) | public void Run()
method GetElements (line 33) | public IReadOnlyCollection<IWebElement> GetElements()
method IterateOverRaceElements (line 38) | public void IterateOverRaceElements()
FILE: RunGroopWebApp.Scraper/Services/MeetupScraper.cs
class MeetupScraper (line 15) | public class MeetupScraper
method MeetupScraper (line 18) | public MeetupScraper()
method Run (line 23) | public void Run()
method GetListOfCityAndState (line 28) | public void GetListOfCityAndState()
method IterateOverRunningClubs (line 49) | public void IterateOverRunningClubs(string state, string city)
FILE: RunGroopWebApp.Tests/Controller/ClubControllerTests.cs
class ClubControllerTests (line 18) | public class ClubControllerTests
method ClubControllerTests (line 24) | public ClubControllerTests()
method ClubController_Index_ReturnsSuccess (line 35) | [Fact]
method ClubController_Detail_ReturnsSuccess (line 47) | [Fact]
FILE: RunGroopWebApp.Tests/Repository/ClubRepositoryTests.cs
class ClubRepositoryTests (line 16) | public class ClubRepositoryTests
method GetDbContext (line 18) | private async Task<ApplicationDbContext> GetDbContext()
method ClubRepository_Add_ReturnsBool (line 49) | [Fact]
method ClubRepository_GetByIdAsync_ReturnsClub (line 76) | [Fact]
method ClubRepository_GetAll_ReturnsList (line 92) | [Fact]
method ClubRepository_SuccessfulDelete_ReturnsTrue (line 107) | [Fact]
method ClubRepository_GetCountAsync_ReturnsInt (line 137) | [Fact]
method ClubRepository_GetAllStates_ReturnsList (line 165) | [Fact]
method ClubRepository_GetClubsByState_ReturnsList (line 180) | [Fact]
FILE: RunGroopWebApp/ClaimsPrincipalExtensions.cs
class ClaimsPrincipalExtensions (line 5) | public static class ClaimsPrincipalExtensions
method GetUserId (line 7) | public static string GetUserId(this ClaimsPrincipal user)
FILE: RunGroopWebApp/Controllers/AccountController.cs
class AccountController (line 10) | public class AccountController : Controller
method AccountController (line 17) | public AccountController(UserManager<AppUser> userManager,
method Login (line 28) | [HttpGet]
method Login (line 35) | [HttpPost]
method Register (line 64) | [HttpGet]
method Register (line 71) | [HttpPost]
method Logout (line 96) | [HttpGet]
method Welcome (line 103) | [HttpGet]
method GetLocation (line 115) | [HttpGet]
FILE: RunGroopWebApp/Controllers/ClubController.cs
class ClubController (line 10) | public class ClubController : Controller
method ClubController (line 15) | public ClubController(IClubRepository clubRepository, IPhotoService ph...
method Index (line 21) | [HttpGet]
method ListClubsByState (line 56) | [HttpGet]
method ListClubsByCity (line 76) | [HttpGet]
method DetailClub (line 97) | [HttpGet]
method RunningClubsByStateDirectory (line 106) | [HttpGet]
method RunningClubsByStateForCityDirectory (line 119) | [HttpGet]
method RunningClubsByCityDirectory (line 132) | [HttpGet]
method Create (line 145) | [HttpGet]
method Create (line 153) | [HttpPost]
method Edit (line 185) | [HttpGet]
method Edit (line 202) | [HttpPost]
method Delete (line 246) | [HttpGet]
method DeleteClub (line 254) | [HttpPost, ActionName("Delete")]
FILE: RunGroopWebApp/Controllers/DashboardController.cs
class DashboardController (line 10) | [Authorize]
method DashboardController (line 16) | public DashboardController(IDashboardRepository dashboardRespository, ...
method Index (line 22) | public async Task<IActionResult> Index()
FILE: RunGroopWebApp/Controllers/HomeController.cs
class HomeController (line 15) | public class HomeController : Controller
method HomeController (line 24) | public HomeController(ILogger<HomeController> logger, IClubRepository ...
method Index (line 35) | public async Task<IActionResult> Index()
method Register (line 62) | public IActionResult Register()
method Index (line 68) | [HttpPost]
method Privacy (line 112) | public IActionResult Privacy()
method Error (line 117) | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, No...
FILE: RunGroopWebApp/Controllers/RaceController.cs
class RaceController (line 11) | public class RaceController : Controller
method RaceController (line 17) | public RaceController(IRaceRepository raceRepository, IPhotoService ph...
method Index (line 25) | [HttpGet]
method DetailRace (line 59) | [HttpGet]
method Create (line 67) | [HttpGet]
method Create (line 75) | [HttpPost]
method Edit (line 107) | [HttpGet]
method Edit (line 124) | [HttpPost]
method Delete (line 168) | [HttpGet]
method DeleteClub (line 176) | [HttpPost, ActionName("Delete")]
FILE: RunGroopWebApp/Controllers/UserController.cs
class UserController (line 10) | public class UserController : Controller
method UserController (line 16) | public UserController(IUserRepository userRepository, UserManager<AppU...
method Index (line 23) | [HttpGet("users")]
method Detail (line 45) | [HttpGet]
method EditProfile (line 67) | [HttpGet]
method EditProfile (line 89) | [HttpPost]
FILE: RunGroopWebApp/Data/ApplicationDbContext.cs
class ApplicationDbContext (line 7) | public class ApplicationDbContext : IdentityDbContext<AppUser>
method ApplicationDbContext (line 9) | public ApplicationDbContext(DbContextOptions<ApplicationDbContext> opt...
FILE: RunGroopWebApp/Data/Enum/ClubCategory.cs
type ClubCategory (line 3) | public enum ClubCategory
FILE: RunGroopWebApp/Data/Enum/RaceCategory.cs
type RaceCategory (line 3) | public enum RaceCategory
FILE: RunGroopWebApp/Data/Seed.cs
class Seed (line 7) | public class Seed
method SeedData (line 9) | public static void SeedData(IApplicationBuilder applicationBuilder)
method SeedUsersAndRolesAsync (line 114) | public static async Task SeedUsersAndRolesAsync(IApplicationBuilder ap...
FILE: RunGroopWebApp/Data/UserRoles.cs
class UserRoles (line 3) | public static class UserRoles
FILE: RunGroopWebApp/Extensions/NumberExtensions.cs
class NumberExtensions (line 3) | public static class NumberExtensions
method IsNumericType (line 5) | public static bool IsNumericType(this object o)
FILE: RunGroopWebApp/Extensions/StringExtensions.cs
class StringExtensions (line 5) | public static class StringExtensions
method FirstCharToUpper (line 7) | public static string FirstCharToUpper(this string input) =>
method GenerateSlug (line 15) | public static string GenerateSlug(this string phrase)
method RemoveAccent (line 28) | public static string RemoveAccent(this string txt)
FILE: RunGroopWebApp/Helpers/CloudinarySettings.cs
class CloudinarySettings (line 3) | public class CloudinarySettings
FILE: RunGroopWebApp/Helpers/IPInfo.cs
class IPInfo (line 5) | public class IPInfo
FILE: RunGroopWebApp/Helpers/Location.cs
class Location (line 3) | public class Location
FILE: RunGroopWebApp/Helpers/StateConverter.cs
class StateConverter (line 3) | public static class StateConverter
method GetState (line 5) | public static string GetState(State state)
method GetStateByName (line 190) | public static State GetStateByName(string name)
type State (line 375) | public enum State
FILE: RunGroopWebApp/Interfaces/IClubRepository.cs
type IClubRepository (line 6) | public interface IClubRepository
method GetAll (line 8) | Task<IEnumerable<Club>> GetAll();
method GetSliceAsync (line 10) | Task<IEnumerable<Club>> GetSliceAsync(int offset, int size);
method GetClubsByState (line 12) | Task<IEnumerable<Club>> GetClubsByState(string state);
method GetClubsByCategoryAndSliceAsync (line 14) | Task<IEnumerable<Club>> GetClubsByCategoryAndSliceAsync(ClubCategory c...
method GetAllStates (line 16) | Task<List<State>> GetAllStates();
method GetAllCitiesByState (line 18) | Task<List<City>> GetAllCitiesByState(string state);
method GetByIdAsync (line 20) | Task<Club?> GetByIdAsync(int id);
method GetByIdAsyncNoTracking (line 22) | Task<Club?> GetByIdAsyncNoTracking(int id);
method GetClubByCity (line 24) | Task<IEnumerable<Club>> GetClubByCity(string city);
method GetCountAsync (line 26) | Task<int> GetCountAsync();
method GetCountByCategoryAsync (line 28) | Task<int> GetCountByCategoryAsync(ClubCategory category);
method Add (line 30) | bool Add(Club club);
method Update (line 32) | bool Update(Club club);
method Delete (line 34) | bool Delete(Club club);
method Save (line 36) | bool Save();
FILE: RunGroopWebApp/Interfaces/IDashboardRepository.cs
type IDashboardRepository (line 5) | public interface IDashboardRepository
method GetAllUserRaces (line 7) | Task<List<Race>> GetAllUserRaces();
method GetAllUserClubs (line 8) | Task<List<Club>> GetAllUserClubs();
method GetUserById (line 9) | Task<AppUser> GetUserById(string id);
method GetByIdNoTracking (line 10) | Task<AppUser> GetByIdNoTracking(string id);
method Update (line 11) | bool Update(AppUser user);
method Save (line 12) | bool Save();
FILE: RunGroopWebApp/Interfaces/ILocationService.cs
type ILocationService (line 5) | public interface ILocationService
method GetLocationSearch (line 7) | Task<List<City>> GetLocationSearch(string location);
method GetCityByZipCode (line 8) | Task<City> GetCityByZipCode(int zipCode);
FILE: RunGroopWebApp/Interfaces/IPhotoService.cs
type IPhotoService (line 5) | public interface IPhotoService
method AddPhotoAsync (line 7) | Task<ImageUploadResult> AddPhotoAsync(IFormFile file);
method DeletePhotoAsync (line 9) | Task<DeletionResult> DeletePhotoAsync(string publicUrl);
FILE: RunGroopWebApp/Interfaces/IRaceRepository.cs
type IRaceRepository (line 6) | public interface IRaceRepository
method GetCountAsync (line 8) | Task<int> GetCountAsync();
method GetCountByCategoryAsync (line 10) | Task<int> GetCountByCategoryAsync(RaceCategory category);
method GetByIdAsync (line 12) | Task<Race?> GetByIdAsync(int id);
method GetByIdAsyncNoTracking (line 14) | Task<Race?> GetByIdAsyncNoTracking(int id);
method GetAll (line 16) | Task<IEnumerable<Race>> GetAll();
method GetAllRacesByCity (line 18) | Task<IEnumerable<Race>> GetAllRacesByCity(string city);
method GetSliceAsync (line 20) | Task<IEnumerable<Race>> GetSliceAsync(int offset, int size);
method GetRacesByCategoryAndSliceAsync (line 22) | Task<IEnumerable<Race>> GetRacesByCategoryAndSliceAsync(RaceCategory c...
method Add (line 24) | bool Add(Race race);
method Update (line 26) | bool Update(Race race);
method Delete (line 28) | bool Delete(Race race);
method Save (line 30) | bool Save();
FILE: RunGroopWebApp/Interfaces/IUserRepository.cs
type IUserRepository (line 5) | public interface IUserRepository
method GetAllUsers (line 7) | Task<IEnumerable<AppUser>> GetAllUsers();
method GetUserById (line 8) | Task<AppUser> GetUserById(string id);
method Add (line 9) | bool Add(AppUser user);
method Update (line 10) | bool Update(AppUser user);
method Delete (line 11) | bool Delete(AppUser user);
method Save (line 12) | bool Save();
FILE: RunGroopWebApp/Migrations/20220215112438_InitialCreate.Designer.cs
class InitialCreate (line 14) | [DbContext(typeof(ApplicationDbContext))]
method BuildTargetModel (line 18) | protected override void BuildTargetModel(ModelBuilder modelBuilder)
FILE: RunGroopWebApp/Migrations/20220215112438_InitialCreate.cs
class InitialCreate (line 7) | public partial class InitialCreate : Migration
method Up (line 9) | protected override void Up(MigrationBuilder migrationBuilder)
method Down (line 129) | protected override void Down(MigrationBuilder migrationBuilder)
FILE: RunGroopWebApp/Migrations/ApplicationDbContextModelSnapshot.cs
class ApplicationDbContextModelSnapshot (line 13) | [DbContext(typeof(ApplicationDbContext))]
method BuildModel (line 16) | protected override void BuildModel(ModelBuilder modelBuilder)
FILE: RunGroopWebApp/Models/Address.cs
class Address (line 5) | public class Address
FILE: RunGroopWebApp/Models/AppUser.cs
class AppUser (line 7) | public class AppUser : IdentityUser
FILE: RunGroopWebApp/Models/City.cs
class City (line 3) | public class City
FILE: RunGroopWebApp/Models/Club.cs
class Club (line 7) | public class Club
FILE: RunGroopWebApp/Models/ErrorViewModel.cs
class ErrorViewModel (line 3) | public class ErrorViewModel
FILE: RunGroopWebApp/Models/Race.cs
class Race (line 7) | public class Race
FILE: RunGroopWebApp/Models/State.cs
class State (line 3) | public class State
FILE: RunGroopWebApp/Repository/ClubRepository.cs
class ClubRepository (line 9) | public class ClubRepository : IClubRepository
method ClubRepository (line 13) | public ClubRepository(ApplicationDbContext context)
method Add (line 18) | public bool Add(Club club)
method Delete (line 24) | public bool Delete(Club club)
method GetAll (line 30) | public async Task<IEnumerable<Club>> GetAll()
method GetAllStates (line 35) | public async Task<List<State>> GetAllStates()
method GetSliceAsync (line 40) | public async Task<IEnumerable<Club>> GetSliceAsync(int offset, int size)
method GetClubsByCategoryAndSliceAsync (line 45) | public async Task<IEnumerable<Club>> GetClubsByCategoryAndSliceAsync(C...
method GetCountByCategoryAsync (line 55) | public async Task<int> GetCountByCategoryAsync(ClubCategory category)
method GetByIdAsync (line 60) | public async Task<Club?> GetByIdAsync(int id)
method GetByIdAsyncNoTracking (line 65) | public async Task<Club?> GetByIdAsyncNoTracking(int id)
method GetClubByCity (line 70) | public async Task<IEnumerable<Club>> GetClubByCity(string city)
method Save (line 75) | public bool Save()
method Update (line 81) | public bool Update(Club club)
method GetCountAsync (line 87) | public async Task<int> GetCountAsync()
method GetClubsByState (line 92) | public async Task<IEnumerable<Club>> GetClubsByState(string state)
method GetAllCitiesByState (line 97) | public async Task<List<City>> GetAllCitiesByState(string state)
FILE: RunGroopWebApp/Repository/DashboardRepository.cs
class DashboardRepository (line 8) | public class DashboardRepository : IDashboardRepository
method DashboardRepository (line 13) | public DashboardRepository(ApplicationDbContext context, IHttpContextA...
method GetAllUserClubs (line 18) | public async Task<List<Club>> GetAllUserClubs()
method GetAllUserRaces (line 25) | public async Task<List<Race>> GetAllUserRaces()
method GetUserById (line 31) | public async Task<AppUser> GetUserById(string id)
method GetByIdNoTracking (line 36) | public async Task<AppUser> GetByIdNoTracking(string id)
method Update (line 41) | public bool Update(AppUser user)
method Save (line 47) | public bool Save()
FILE: RunGroopWebApp/Repository/RaceRepository.cs
class RaceRepository (line 9) | public class RaceRepository : IRaceRepository
method RaceRepository (line 13) | public RaceRepository(ApplicationDbContext context)
method Add (line 18) | public bool Add(Race race)
method Delete (line 24) | public bool Delete(Race race)
method GetAll (line 30) | public async Task<IEnumerable<Race>> GetAll()
method GetAllRacesByCity (line 35) | public async Task<IEnumerable<Race>> GetAllRacesByCity(string city)
method GetByIdAsync (line 40) | public async Task<Race?> GetByIdAsync(int id)
method GetByIdAsyncNoTracking (line 45) | public async Task<Race?> GetByIdAsyncNoTracking(int id)
method GetCountAsync (line 50) | public async Task<int> GetCountAsync()
method GetCountByCategoryAsync (line 55) | public async Task<int> GetCountByCategoryAsync(RaceCategory category)
method GetSliceAsync (line 60) | public async Task<IEnumerable<Race>> GetSliceAsync(int offset, int size)
method GetRacesByCategoryAndSliceAsync (line 65) | public async Task<IEnumerable<Race>> GetRacesByCategoryAndSliceAsync(R...
method Save (line 75) | public bool Save()
method Update (line 81) | public bool Update(Race race)
FILE: RunGroopWebApp/Repository/UserRepository.cs
class UserRepository (line 8) | public class UserRepository : IUserRepository
method UserRepository (line 12) | public UserRepository(ApplicationDbContext context)
method Add (line 17) | public bool Add(AppUser user)
method Delete (line 22) | public bool Delete(AppUser user)
method GetAllUsers (line 27) | public async Task<IEnumerable<AppUser>> GetAllUsers()
method GetUserById (line 32) | public async Task<AppUser> GetUserById(string id)
method Save (line 37) | public bool Save()
method Update (line 43) | public bool Update(AppUser user)
FILE: RunGroopWebApp/Services/LocationService.cs
class LocationService (line 10) | public class LocationService : ILocationService
method LocationService (line 14) | public LocationService(ApplicationDbContext context)
method GetCityByZipCode (line 19) | public async Task<City> GetCityByZipCode(int zipCode)
method GetLocationSearch (line 23) | public async Task<List<City>> GetLocationSearch(string location)
FILE: RunGroopWebApp/Services/PhotoService.cs
class PhotoService (line 9) | public class PhotoService : IPhotoService
method PhotoService (line 13) | public PhotoService(IOptions<CloudinarySettings> config)
method AddPhotoAsync (line 23) | public async Task<ImageUploadResult> AddPhotoAsync(IFormFile file)
method DeletePhotoAsync (line 39) | public async Task<DeletionResult> DeletePhotoAsync(string publicUrl)
FILE: RunGroopWebApp/ViewModels/CreateClubViewModel.cs
class CreateClubViewModel (line 6) | public class CreateClubViewModel
FILE: RunGroopWebApp/ViewModels/CreateRaceViewModel.cs
class CreateRaceViewModel (line 6) | public class CreateRaceViewModel
FILE: RunGroopWebApp/ViewModels/DashboardViewModel.cs
class DashboardViewModel (line 5) | public class DashboardViewModel
FILE: RunGroopWebApp/ViewModels/EditClubViewModel.cs
class EditClubViewModel (line 6) | public class EditClubViewModel
FILE: RunGroopWebApp/ViewModels/EditProfileViewModel.cs
class EditProfileViewModel (line 3) | public class EditProfileViewModel
FILE: RunGroopWebApp/ViewModels/EditRaceViewModel.cs
class EditRaceViewModel (line 6) | public class EditRaceViewModel
FILE: RunGroopWebApp/ViewModels/HomeUserCreateViewModel.cs
class HomeUserCreateViewModel (line 5) | public class HomeUserCreateViewModel
FILE: RunGroopWebApp/ViewModels/HomeViewModel.cs
class HomeViewModel (line 5) | public class HomeViewModel
FILE: RunGroopWebApp/ViewModels/IndexClubViewModel.cs
class IndexClubViewModel (line 5) | public class IndexClubViewModel
FILE: RunGroopWebApp/ViewModels/IndexRaceViewModel.cs
class IndexRaceViewModel (line 5) | public class IndexRaceViewModel
FILE: RunGroopWebApp/ViewModels/ListClubByCityViewModel.cs
class ListClubByCityViewModel (line 5) | public class ListClubByCityViewModel
FILE: RunGroopWebApp/ViewModels/ListClubByStateViewModel.cs
class ListClubByStateViewModel (line 5) | public class ListClubByStateViewModel
FILE: RunGroopWebApp/ViewModels/LoginViewModel.cs
class LoginViewModel (line 5) | public class LoginViewModel
FILE: RunGroopWebApp/ViewModels/RegisterViewModel.cs
class RegisterViewModel (line 5) | public class RegisterViewModel
FILE: RunGroopWebApp/ViewModels/RunningClubByCity.cs
class RunningClubByCity (line 5) | public class RunningClubByCity
FILE: RunGroopWebApp/ViewModels/RunningClubByState.cs
class RunningClubByState (line 5) | public class RunningClubByState
FILE: RunGroopWebApp/ViewModels/UserDetailViewModel.cs
class UserDetailViewModel (line 5) | public class UserDetailViewModel
FILE: RunGroopWebApp/ViewModels/UserViewModel.cs
class UserViewModel (line 3) | public class UserViewModel
FILE: RunGroopWebApp/ViewModels/WelcomeViewModel.cs
class WelcomeViewModel (line 3) | public class WelcomeViewModel
FILE: RunGroopWebApp/wwwroot/js/aos.js
function t (line 1) | function t(o){if(n[o])return n[o].exports;var i=n[o]={exports:{},id:o,lo...
function o (line 1) | function o(e){return e&&e.__esModule?e:{default:e}}
function n (line 1) | function n(e,t,n){function o(t){var n=b,o=v;return b=v=void 0,k=t,g=e.ap...
function o (line 1) | function o(e,t,o){var r=!0,a=!0;if("function"!=typeof e)throw new TypeEr...
function i (line 1) | function i(e){var t="undefined"==typeof e?"undefined":c(e);return!!e&&("...
function r (line 1) | function r(e){return!!e&&"object"==("undefined"==typeof e?"undefined":c(...
function a (line 1) | function a(e){return"symbol"==("undefined"==typeof e?"undefined":c(e))||...
function u (line 1) | function u(e){if("number"==typeof e)return e;if(a(e))return f;if(i(e)){v...
function n (line 1) | function n(e,t,n){function i(t){var n=b,o=v;return b=v=void 0,O=t,g=e.ap...
function o (line 1) | function o(e){var t="undefined"==typeof e?"undefined":u(e);return!!e&&("...
function i (line 1) | function i(e){return!!e&&"object"==("undefined"==typeof e?"undefined":u(...
function r (line 1) | function r(e){return"symbol"==("undefined"==typeof e?"undefined":u(e))||...
function a (line 1) | function a(e){if("number"==typeof e)return e;if(r(e))return s;if(o(e)){v...
function n (line 1) | function n(e){var t=void 0,o=void 0,i=void 0;for(t=0;t<e.length;t+=1){if...
function o (line 1) | function o(){return window.MutationObserver||window.WebKitMutationObserv...
function i (line 1) | function i(){return!!o()}
function r (line 1) | function r(e,t){var n=window.document,i=o(),r=new i(a);u=t,r.observe(n.d...
function a (line 1) | function a(e){e&&e.forEach(function(e){var t=Array.prototype.slice.call(...
function n (line 1) | function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a ...
function o (line 1) | function o(){return navigator.userAgent||navigator.vendor||window.opera|...
function e (line 1) | function e(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.en...
function e (line 1) | function e(){n(this,e)}
function o (line 1) | function o(e){return e&&e.__esModule?e:{default:e}}
function o (line 1) | function o(e){return e&&e.__esModule?e:{default:e}}
FILE: RunGroopWebApp/wwwroot/js/bootstrap.js
function i (line 6) | function i(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.en...
function s (line 6) | function s(t,e,n){return e&&i(t.prototype,e),n&&i(t,n),t}
function l (line 6) | function l(o){for(var t=1;t<arguments.length;t++){var r=null!=arguments[...
function n (line 6) | function n(t){var e=this,n=!1;return g(this).one(_.TRANSITION_END,functi...
function i (line 6) | function i(t){this._element=t}
function n (line 6) | function n(t){this._element=t}
function r (line 6) | function r(t,e){this._items=null,this._interval=null,this._activeElement...
function a (line 6) | function a(e,t){this._isTransitioning=!1,this._element=e,this._config=th...
function c (line 6) | function c(t,e){this._element=t,this._popper=null,this._config=this._get...
function o (line 6) | function o(t,e){this._config=this._getConfig(e),this._element=t,this._di...
function Se (line 6) | function Se(t,s,e){if(0===t.length)return t;if(e&&"function"==typeof e)r...
function i (line 6) | function i(t,e){if(void 0===u)throw new TypeError("Bootstrap's tooltips ...
function i (line 6) | function i(){return t.apply(this,arguments)||this}
function n (line 6) | function n(t,e){var n=this;this._element=t,this._scrollElement="BODY"===...
function i (line 6) | function i(t){this._element=t}
function i (line 6) | function i(t,e){this._element=t,this._config=this._getConfig(e),this._ti...
FILE: RunGroopWebApp/wwwroot/js/flickity.pkgd.js
function jQueryBridget (line 59) | function jQueryBridget( namespace, PluginClass, $ ) {
function updateJQuery (line 141) | function updateJQuery( $ ) {
function EvEmitter (line 182) | function EvEmitter() {}
function getStyleSize (line 297) | function getStyleSize( value ) {
function noop (line 304) | function noop() {}
function getZeroSize (line 330) | function getZeroSize() {
function getStyle (line 352) | function getStyle( elem ) {
function setup (line 373) | function setup() {
function getSize (line 405) | function getSize( elem ) {
function Cell (line 803) | function Cell( elem, parent ) {
function Slide (line 895) | function Slide( parent ) {
function moveElements (line 1205) | function moveElements( elems, toElem ) {
function Flickity (line 1219) | function Flickity( element, options ) {
function noop (line 2119) | function noop() {}
function Unipointer (line 2121) | function Unipointer() {}
function Unidragger (line 2424) | function Unidragger() {}
function getScrollPosition (line 3046) | function getScrollPosition() {
function PrevNextButton (line 3097) | function PrevNextButton( direction, parent ) {
function getArrowMovements (line 3162) | function getArrowMovements( shape ) {
function PageDots (line 3308) | function PageDots( parent ) {
function Player (line 3495) | function Player( parent ) {
function getCellsFragment (line 3685) | function getCellsFragment( cells ) {
function getCellLazyImages (line 3872) | function getCellLazyImages( cellElem ) {
function LazyLoader (line 3894) | function LazyLoader( img, flickity ) {
function lerp (line 4096) | function lerp( a, b, t ) {
function extend (line 4189) | function extend( a, b ) {
function makeArray (line 4199) | function makeArray( obj ) {
function ImagesLoaded (line 4222) | function ImagesLoaded( elem, options, onAlways ) {
function onProgress (line 4356) | function onProgress( image, elem, message ) {
function LoadingImage (line 4400) | function LoadingImage( img ) {
function Background (line 4466) | function Background( url, element ) {
function onImagesLoadedProgress (line 4571) | function onImagesLoadedProgress( instance, image ) {
FILE: RunGroopWebApp/wwwroot/js/prism.js
function Token (line 458) | function Token(type, content, alias, matchedStr, greedy) {
FILE: RunGroopWebApp/wwwroot/js/scrollMonitor.js
function e (line 1) | function e(o){if(i[o])return i[o].exports;var s=i[o]={exports:{},id:o,lo...
function o (line 1) | function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a ...
function s (line 1) | function s(t){return c?0:t===document.body?window.innerHeight||document....
function n (line 1) | function n(t){return c?0:t===document.body?Math.max(document.body.scroll...
function r (line 1) | function r(t){return c?0:t===document.body?window.pageYOffset||document....
function t (line 1) | function t(e,i){function h(){if(a.viewportTop=r(e),a.viewportBottom=a.vi...
function o (line 1) | function o(t,e,i){function o(t,e){if(0!==t.length)for(E=t.length;E--;)y=...
FILE: RunGroopWebApp/wwwroot/js/theme.js
function c (line 5) | function c(t,e){for(var i=0;i<e.length;i++){var r=e[i];r.enumerable=r.en...
function b (line 5) | function b(t,e,i){return e&&c(t.prototype,e),i&&c(t,i),t}
function i (line 5) | function i(t){this.element=t,this.initflatpickr()}
function i (line 5) | function i(t){var e=s(t),i=e.data(m),r=e.closest("section")||null;this.e...
Condensed preview — 119 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (920K chars).
[
{
"path": ".gitignore",
"chars": 6860,
"preview": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n##\n## "
},
{
"path": "README.md",
"chars": 1079,
"preview": "# RunGroops\n\nRungroops is an online platform for runners. This platform will help you to find clubs, schedule events, an"
},
{
"path": "RunGroopWebApp/ClaimsPrincipalExtensions.cs",
"chars": 277,
"preview": "using System.Security.Claims;\n\nnamespace RunGroopWebApp\n{\n public static class ClaimsPrincipalExtensions\n {\n "
},
{
"path": "RunGroopWebApp/Controllers/AccountController.cs",
"chars": 4157,
"preview": "using Microsoft.AspNetCore.Identity;\nusing Microsoft.AspNetCore.Mvc;\nusing RunGroopWebApp.Data;\nusing RunGroopWebApp.In"
},
{
"path": "RunGroopWebApp/Controllers/ClubController.cs",
"chars": 8611,
"preview": "using Microsoft.AspNetCore.Mvc;\nusing RunGroopWebApp.Data.Enum;\nusing RunGroopWebApp.Helpers;\nusing RunGroopWebApp.Inte"
},
{
"path": "RunGroopWebApp/Controllers/DashboardController.cs",
"chars": 1096,
"preview": "using CloudinaryDotNet.Actions;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc;\nusing RunGroo"
},
{
"path": "RunGroopWebApp/Controllers/HomeController.cs",
"chars": 4331,
"preview": "using Microsoft.AspNetCore.Identity;\nusing Microsoft.AspNetCore.Mvc;\nusing Newtonsoft.Json;\nusing RunGroopWebApp.Data;\n"
},
{
"path": "RunGroopWebApp/Controllers/RaceController.cs",
"chars": 6327,
"preview": "using Microsoft.AspNetCore.Mvc;\nusing Microsoft.EntityFrameworkCore;\nusing RunGroopWebApp.Data;\nusing RunGroopWebApp.Da"
},
{
"path": "RunGroopWebApp/Controllers/UserController.cs",
"chars": 4422,
"preview": "using Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Identity;\nusing Microsoft.AspNetCore.Mvc;\nusing Ru"
},
{
"path": "RunGroopWebApp/Data/ApplicationDbContext.cs",
"chars": 604,
"preview": "using Microsoft.AspNetCore.Identity.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore;\nusing RunGroopWebApp.Mode"
},
{
"path": "RunGroopWebApp/Data/Enum/ClubCategory.cs",
"chars": 164,
"preview": "namespace RunGroopWebApp.Data.Enum\n{\n public enum ClubCategory\n {\n RoadRunner,\n Womens,\n Cit"
},
{
"path": "RunGroopWebApp/Data/Enum/RaceCategory.cs",
"chars": 163,
"preview": "namespace RunGroopWebApp.Data.Enum\n{\n public enum RaceCategory\n {\n Marathon,\n Ultra,\n FiveK,"
},
{
"path": "RunGroopWebApp/Data/Seed.cs",
"chars": 7835,
"preview": "using Microsoft.AspNetCore.Identity;\nusing RunGroopWebApp.Data.Enum;\nusing RunGroopWebApp.Models;\n\nnamespace RunGroopWe"
},
{
"path": "RunGroopWebApp/Data/UserRoles.cs",
"chars": 169,
"preview": "namespace RunGroopWebApp.Data\n{\n public static class UserRoles\n {\n public const string Admin = \"admin\";\n "
},
{
"path": "RunGroopWebApp/Extensions/NumberExtensions.cs",
"chars": 754,
"preview": "namespace RunGroopWebApp.Extensions\n{\n public static class NumberExtensions\n {\n public static bool IsNumer"
},
{
"path": "RunGroopWebApp/Extensions/StringExtensions.cs",
"chars": 1294,
"preview": "using System.Text.RegularExpressions;\n\nnamespace RunGroopWebApp.Extensions\n{\n public static class StringExtensions\n "
},
{
"path": "RunGroopWebApp/Helpers/CloudinarySettings.cs",
"chars": 221,
"preview": "namespace RunGroopWebApp.Helpers\n{\n public class CloudinarySettings\n {\n public string CloudName { get; set"
},
{
"path": "RunGroopWebApp/Helpers/IPInfo.cs",
"chars": 775,
"preview": "using Newtonsoft.Json;\n\nnamespace RunGroopWebApp.Helpers\n{\n public class IPInfo\n {\n [JsonProperty(\"ip\")]\n "
},
{
"path": "RunGroopWebApp/Helpers/Location.cs",
"chars": 159,
"preview": "namespace RunGroopWebApp.Helpers\n{\n public class Location\n {\n public string City { get; set; }\n pub"
},
{
"path": "RunGroopWebApp/Helpers/StateConverter.cs",
"chars": 10000,
"preview": "namespace RunGroopWebApp.Helpers\n{\n public static class StateConverter\n {\n public static string GetState(S"
},
{
"path": "RunGroopWebApp/Interfaces/IClubRepository.cs",
"chars": 920,
"preview": "using RunGroopWebApp.Data.Enum;\nusing RunGroopWebApp.Models;\n\nnamespace RunGroopWebApp.Interfaces\n{\n public interfac"
},
{
"path": "RunGroopWebApp/Interfaces/IDashboardRepository.cs",
"chars": 367,
"preview": "using RunGroopWebApp.Models;\n\nnamespace RunGroopWebApp.Interfaces\n{\n public interface IDashboardRepository\n {\n "
},
{
"path": "RunGroopWebApp/Interfaces/ILocationService.cs",
"chars": 232,
"preview": "using RunGroopWebApp.Models;\n\nnamespace RunGroopWebApp.Interfaces\n{\n public interface ILocationService\n {\n "
},
{
"path": "RunGroopWebApp/Interfaces/IPhotoService.cs",
"chars": 249,
"preview": "using CloudinaryDotNet.Actions;\n\nnamespace RunGroopWebApp.Interfaces\n{\n public interface IPhotoService\n {\n "
},
{
"path": "RunGroopWebApp/Interfaces/IRaceRepository.cs",
"chars": 756,
"preview": "using RunGroopWebApp.Data.Enum;\nusing RunGroopWebApp.Models;\n\nnamespace RunGroopWebApp.Interfaces\n{\n public interfac"
},
{
"path": "RunGroopWebApp/Interfaces/IUserRepository.cs",
"chars": 339,
"preview": "using RunGroopWebApp.Models;\n\nnamespace RunGroopWebApp.Interfaces\n{\n public interface IUserRepository\n {\n "
},
{
"path": "RunGroopWebApp/Migrations/20220215112438_InitialCreate.Designer.cs",
"chars": 6685,
"preview": "// <auto-generated />\nusing System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastruc"
},
{
"path": "RunGroopWebApp/Migrations/20220215112438_InitialCreate.cs",
"chars": 6041,
"preview": "using Microsoft.EntityFrameworkCore.Migrations;\n\n#nullable disable\n\nnamespace RunGroopWebApp.Migrations\n{\n public pa"
},
{
"path": "RunGroopWebApp/Migrations/ApplicationDbContextModelSnapshot.cs",
"chars": 17921,
"preview": "// <auto-generated />\nusing System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastruc"
},
{
"path": "RunGroopWebApp/Models/Address.cs",
"chars": 338,
"preview": "using System.ComponentModel.DataAnnotations;\n\nnamespace RunGroopWebApp.Models\n{\n public class Address\n {\n "
},
{
"path": "RunGroopWebApp/Models/AppUser.cs",
"chars": 671,
"preview": "using Microsoft.AspNetCore.Identity;\nusing System.ComponentModel.DataAnnotations;\nusing System.ComponentModel.DataAnnot"
},
{
"path": "RunGroopWebApp/Models/City.cs",
"chars": 369,
"preview": "namespace RunGroopWebApp.Models\n{\n public class City\n {\n public int Id { get; set; }\n public string"
},
{
"path": "RunGroopWebApp/Models/Club.cs",
"chars": 688,
"preview": "using RunGroopWebApp.Data.Enum;\nusing System.ComponentModel.DataAnnotations;\nusing System.ComponentModel.DataAnnotation"
},
{
"path": "RunGroopWebApp/Models/ErrorViewModel.cs",
"chars": 198,
"preview": "namespace RunGroopWebApp.Models\n{\n public class ErrorViewModel\n {\n public string? RequestId { get; set; }\n\n"
},
{
"path": "RunGroopWebApp/Models/Race.cs",
"chars": 957,
"preview": "using RunGroopWebApp.Data.Enum;\nusing System.ComponentModel.DataAnnotations;\nusing System.ComponentModel.DataAnnotation"
},
{
"path": "RunGroopWebApp/Models/State.cs",
"chars": 200,
"preview": "namespace RunGroopWebApp.Models\n{\n public class State\n {\n public int Id { get; set; }\n public strin"
},
{
"path": "RunGroopWebApp/Program.cs",
"chars": 2040,
"preview": "using Microsoft.AspNetCore.Authentication.Cookies;\nusing Microsoft.AspNetCore.Identity;\nusing Microsoft.EntityFrameworkC"
},
{
"path": "RunGroopWebApp/Properties/launchSettings.json",
"chars": 685,
"preview": "{\n \"iisSettings\": {\n \"windowsAuthentication\": false,\n \"anonymousAuthentication\": true,\n \"iisExpress\": {\n "
},
{
"path": "RunGroopWebApp/Repository/ClubRepository.cs",
"chars": 3019,
"preview": "using Microsoft.EntityFrameworkCore;\nusing RunGroopWebApp.Data;\nusing RunGroopWebApp.Data.Enum;\nusing RunGroopWebApp.In"
},
{
"path": "RunGroopWebApp/Repository/DashboardRepository.cs",
"chars": 1717,
"preview": "using Microsoft.EntityFrameworkCore;\nusing RunGroopWebApp.Data;\nusing RunGroopWebApp.Interfaces;\nusing RunGroopWebApp.M"
},
{
"path": "RunGroopWebApp/Repository/RaceRepository.cs",
"chars": 2482,
"preview": "using Microsoft.EntityFrameworkCore;\nusing RunGroopWebApp.Data;\nusing RunGroopWebApp.Data.Enum;\nusing RunGroopWebApp.In"
},
{
"path": "RunGroopWebApp/Repository/UserRepository.cs",
"chars": 1154,
"preview": "using Microsoft.EntityFrameworkCore;\nusing RunGroopWebApp.Data;\nusing RunGroopWebApp.Interfaces;\nusing RunGroopWebApp.M"
},
{
"path": "RunGroopWebApp/RunGroopWebApp.csproj",
"chars": 834,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n <PropertyGroup>\n <TargetFramework>net6.0</TargetFramework>\n <Nullable>ena"
},
{
"path": "RunGroopWebApp/Services/LocationService.cs",
"chars": 1284,
"preview": "using Microsoft.EntityFrameworkCore;\nusing RunGroopWebApp.Data;\nusing RunGroopWebApp.Extensions;\nusing RunGroopWebApp.H"
},
{
"path": "RunGroopWebApp/Services/PhotoService.cs",
"chars": 1557,
"preview": "using CloudinaryDotNet;\nusing CloudinaryDotNet.Actions;\nusing Microsoft.Extensions.Options;\nusing RunGroopWebApp.Helper"
},
{
"path": "RunGroopWebApp/ViewModels/CreateClubViewModel.cs",
"chars": 469,
"preview": "using RunGroopWebApp.Data.Enum;\nusing RunGroopWebApp.Models;\n\nnamespace RunGroopWebApp.ViewModels\n{\n public class Cr"
},
{
"path": "RunGroopWebApp/ViewModels/CreateRaceViewModel.cs",
"chars": 469,
"preview": "using RunGroopWebApp.Data.Enum;\nusing RunGroopWebApp.Models;\n\nnamespace RunGroopWebApp.ViewModels\n{\n public class Cr"
},
{
"path": "RunGroopWebApp/ViewModels/DashboardViewModel.cs",
"chars": 211,
"preview": "using RunGroopWebApp.Models;\n\nnamespace RunGroopWebApp.ViewModels\n{\n public class DashboardViewModel\n {\n p"
},
{
"path": "RunGroopWebApp/ViewModels/EditClubViewModel.cs",
"chars": 506,
"preview": "using RunGroopWebApp.Data.Enum;\nusing RunGroopWebApp.Models;\n\nnamespace RunGroopWebApp.ViewModels\n{\n public class Ed"
},
{
"path": "RunGroopWebApp/ViewModels/EditProfileViewModel.cs",
"chars": 355,
"preview": "namespace RunGroopWebApp.ViewModels\n{\n public class EditProfileViewModel\n {\n public int? Pace { get; set; "
},
{
"path": "RunGroopWebApp/ViewModels/EditRaceViewModel.cs",
"chars": 505,
"preview": "using RunGroopWebApp.Data.Enum;\nusing RunGroopWebApp.Models;\n\nnamespace RunGroopWebApp.ViewModels\n{\n public class Ed"
},
{
"path": "RunGroopWebApp/ViewModels/HomeUserCreateViewModel.cs",
"chars": 371,
"preview": "using System.ComponentModel.DataAnnotations;\n\nnamespace RunGroopWebApp.ViewModels\n{\n public class HomeUserCreateView"
},
{
"path": "RunGroopWebApp/ViewModels/HomeViewModel.cs",
"chars": 347,
"preview": "using RunGroopWebApp.Models;\n\nnamespace RunGroopWebApp.ViewModels\n{\n public class HomeViewModel\n {\n public"
},
{
"path": "RunGroopWebApp/ViewModels/IndexClubViewModel.cs",
"chars": 439,
"preview": "using RunGroopWebApp.Models;\n\nnamespace RunGroopWebApp.ViewModels;\n\npublic class IndexClubViewModel\n{\n public IEnume"
},
{
"path": "RunGroopWebApp/ViewModels/IndexRaceViewModel.cs",
"chars": 438,
"preview": "using RunGroopWebApp.Models;\n\nnamespace RunGroopWebApp.ViewModels;\n\npublic class IndexRaceViewModel\n{\n public IEnume"
},
{
"path": "RunGroopWebApp/ViewModels/ListClubByCityViewModel.cs",
"chars": 317,
"preview": "using RunGroopWebApp.Models;\n\nnamespace RunGroopWebApp.ViewModels\n{\n public class ListClubByCityViewModel\n {\n "
},
{
"path": "RunGroopWebApp/ViewModels/ListClubByStateViewModel.cs",
"chars": 277,
"preview": "using RunGroopWebApp.Models;\n\nnamespace RunGroopWebApp.ViewModels\n{\n public class ListClubByStateViewModel\n {\n "
},
{
"path": "RunGroopWebApp/ViewModels/LoginViewModel.cs",
"chars": 387,
"preview": "using System.ComponentModel.DataAnnotations;\n\nnamespace RunGroopWebApp.ViewModels\n{\n public class LoginViewModel\n "
},
{
"path": "RunGroopWebApp/ViewModels/RegisterViewModel.cs",
"chars": 661,
"preview": "using System.ComponentModel.DataAnnotations;\n\nnamespace RunGroopWebApp.ViewModels\n{\n public class RegisterViewModel\n"
},
{
"path": "RunGroopWebApp/ViewModels/RunningClubByCity.cs",
"chars": 173,
"preview": "using RunGroopWebApp.Models;\n\nnamespace RunGroopWebApp.ViewModels\n{\n public class RunningClubByCity\n {\n pu"
},
{
"path": "RunGroopWebApp/ViewModels/RunningClubByState.cs",
"chars": 175,
"preview": "using RunGroopWebApp.Models;\n\nnamespace RunGroopWebApp.ViewModels\n{\n public class RunningClubByState\n {\n p"
},
{
"path": "RunGroopWebApp/ViewModels/UserDetailViewModel.cs",
"chars": 607,
"preview": "using RunGroopWebApp.Models;\n\nnamespace RunGroopWebApp.ViewModels;\n\npublic class UserDetailViewModel\n{\n public strin"
},
{
"path": "RunGroopWebApp/ViewModels/UserViewModel.cs",
"chars": 571,
"preview": "namespace RunGroopWebApp.ViewModels;\n\npublic class UserViewModel\n{\n public string Id { get; set; }\n public string"
},
{
"path": "RunGroopWebApp/ViewModels/WelcomeViewModel.cs",
"chars": 352,
"preview": "namespace RunGroopWebApp.ViewModels\n{\n public class WelcomeViewModel\n {\n public int? Pace { get; set; }\n "
},
{
"path": "RunGroopWebApp/Views/Account/Login.cshtml",
"chars": 1622,
"preview": "@using RunGroopWebApp.ViewModels\n@model LoginViewModel\n\n@{\n ViewData[\"Title\"] = \"Login\";\n}\n<div class=\"row\">\n <di"
},
{
"path": "RunGroopWebApp/Views/Account/Register.cshtml",
"chars": 1974,
"preview": "@using RunGroopWebApp.ViewModels\n@model RegisterViewModel\n\n@{\n ViewData[\"Title\"] = \"Sign up\";\n}\n\n<div class=\"row\">\n "
},
{
"path": "RunGroopWebApp/Views/Account/Welcome.cshtml",
"chars": 2300,
"preview": "@using RunGroopWebApp.ViewModels\n@model WelcomeViewModel\n@*\n For more information on enabling MVC for empty projects"
},
{
"path": "RunGroopWebApp/Views/Club/Create.cshtml",
"chars": 4148,
"preview": "@using RunGroopWebApp.Data.Enum\n@using RunGroopWebApp.ViewModels\n@model CreateClubViewModel\n@*\n For more information"
},
{
"path": "RunGroopWebApp/Views/Club/Delete.cshtml",
"chars": 2343,
"preview": "@using RunGroopWebApp.Data.Enum\n@model Club\n\n<h1>Are you sure you want to delete this club?</h1>\n\n<form method=\"post\" a"
},
{
"path": "RunGroopWebApp/Views/Club/DetailClub.cshtml",
"chars": 22332,
"preview": "@model Club\n@*\n For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?Link"
},
{
"path": "RunGroopWebApp/Views/Club/Edit.cshtml",
"chars": 2152,
"preview": "@using RunGroopWebApp.Data.Enum\n@using RunGroopWebApp.ViewModels\n@model EditClubViewModel\n\n\n<form method=\"post\" asp-act"
},
{
"path": "RunGroopWebApp/Views/Club/Index.cshtml",
"chars": 5153,
"preview": "@using RunGroopWebApp.Data.Enum\n@using RunGroopWebApp.Extensions\n@using RunGroopWebApp.ViewModels\n@model IndexClubViewMo"
},
{
"path": "RunGroopWebApp/Views/Club/ListClubsByCity.cshtml",
"chars": 2370,
"preview": "@using Microsoft.AspNetCore.Identity\n@inject SignInManager<AppUser> SignInManager\n\n@using RunGroopWebApp.ViewModels\n@mo"
},
{
"path": "RunGroopWebApp/Views/Club/ListClubsByState.cshtml",
"chars": 2357,
"preview": "@using Microsoft.AspNetCore.Identity\n@inject SignInManager<AppUser> SignInManager\n\n@using RunGroopWebApp.ViewModels\n@mo"
},
{
"path": "RunGroopWebApp/Views/Club/RunningClubsByCityDirectory.cshtml",
"chars": 1516,
"preview": "@using RunGroopWebApp.ViewModels\n@model RunningClubByCity\n\n@{\n var cities = Model.Cities.DistinctBy(city => city.Cit"
},
{
"path": "RunGroopWebApp/Views/Club/RunningClubsByStateDirectory.cshtml",
"chars": 1427,
"preview": "@using RunGroopWebApp.ViewModels\n@model RunningClubByState\n\n\n<section class=\"container\">\n <h1>Find running clubs in "
},
{
"path": "RunGroopWebApp/Views/Club/RunningClubsByStateForCityDirectory.cshtml",
"chars": 1513,
"preview": "@using RunGroopWebApp.ViewModels\n@model RunningClubByState\n\n\n\n\n<section class=\"container\">\n <h1>Select your state</h"
},
{
"path": "RunGroopWebApp/Views/Dashboard/Index.cshtml",
"chars": 3977,
"preview": "@using Microsoft.AspNetCore.Identity\n@inject SignInManager<AppUser> SignInManager\n\n@model RunGroopWebApp.ViewModels.Das"
},
{
"path": "RunGroopWebApp/Views/Home/Index.cshtml",
"chars": 6595,
"preview": "@using RunGroopWebApp.ViewModels\n@model HomeViewModel\n@{\n ViewData[\"Title\"] = \"Home Page\";\n}\n\n<section class=\"bg-dar"
},
{
"path": "RunGroopWebApp/Views/Home/Privacy.cshtml",
"chars": 136,
"preview": "@{\n ViewData[\"Title\"] = \"Privacy Policy\";\n}\n<h1>@ViewData[\"Title\"]</h1>\n\n<p>Use this page to detail your site's priv"
},
{
"path": "RunGroopWebApp/Views/Home/Register.cshtml",
"chars": 3182,
"preview": "@using RunGroopWebApp.ViewModels\n@model HomeUserCreateViewModel\n\n@{\n ViewData[\"Title\"] = \"Register Page\";\n}\n\n <"
},
{
"path": "RunGroopWebApp/Views/Race/Create.cshtml",
"chars": 6025,
"preview": "@using RunGroopWebApp.Data.Enum\n@using RunGroopWebApp.ViewModels\n@model CreateRaceViewModel\n\n\n <div class=\"navbar-conta"
},
{
"path": "RunGroopWebApp/Views/Race/Delete.cshtml",
"chars": 2343,
"preview": "@using RunGroopWebApp.Data.Enum\n@model Race\n\n<h1>Are you sure you want to delete this race?</h1>\n\n<form method=\"post\" a"
},
{
"path": "RunGroopWebApp/Views/Race/DetailRace.cshtml",
"chars": 22331,
"preview": "@model Race\n@*\n For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?Link"
},
{
"path": "RunGroopWebApp/Views/Race/Edit.cshtml",
"chars": 2152,
"preview": "@using RunGroopWebApp.Data.Enum\n@using RunGroopWebApp.ViewModels\n@model EditRaceViewModel\n\n\n<form method=\"post\" asp-act"
},
{
"path": "RunGroopWebApp/Views/Race/Index.cshtml",
"chars": 5122,
"preview": "@using RunGroopWebApp.Data.Enum\n@using RunGroopWebApp.Extensions\n@using RunGroopWebApp.ViewModels\n@model IndexRaceViewM"
},
{
"path": "RunGroopWebApp/Views/Shared/Error.cshtml",
"chars": 868,
"preview": "@model ErrorViewModel\n@{\n ViewData[\"Title\"] = \"Error\";\n}\n\n<h1 class=\"text-danger\">Error.</h1>\n<h2 class=\"text-danger"
},
{
"path": "RunGroopWebApp/Views/Shared/_Layout.cshtml",
"chars": 11017,
"preview": "@using Microsoft.AspNetCore.Identity\n\n@inject SignInManager<AppUser> SignInManager\n@inject UserManager<AppUser> UserMan"
},
{
"path": "RunGroopWebApp/Views/Shared/_Layout.cshtml.css",
"chars": 874,
"preview": "/* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\nfor details"
},
{
"path": "RunGroopWebApp/Views/Shared/_ValidationScriptsPartial.cshtml",
"chars": 172,
"preview": "<script src=\"~/lib/jquery-validation/dist/jquery.validate.min.js\"></script>\n<script src=\"~/lib/jquery-validation-unobtr"
},
{
"path": "RunGroopWebApp/Views/User/Detail.cshtml",
"chars": 54376,
"preview": "@using RunGroopWebApp.ViewModels\n@model UserDetailViewModel\n\n\n<div class=\"main-container\">\n <nav aria-label=\"breadcr"
},
{
"path": "RunGroopWebApp/Views/User/EditProfile.cshtml",
"chars": 17139,
"preview": "@using RunGroopWebApp.ViewModels\n@model EditProfileViewModel\n\n<div class=\"main-container\">\n <section class=\"bg-white"
},
{
"path": "RunGroopWebApp/Views/User/Index.cshtml",
"chars": 2105,
"preview": "@using RunGroopWebApp.ViewModels\n@model List<UserViewModel>\n\n<section class=\"flush-with-above\">\n <div class=\"contain"
},
{
"path": "RunGroopWebApp/Views/_ViewImports.cshtml",
"chars": 105,
"preview": "@using RunGroopWebApp\n@using RunGroopWebApp.Models\n@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
},
{
"path": "RunGroopWebApp/Views/_ViewStart.cshtml",
"chars": 30,
"preview": "@{\n Layout = \"_Layout\";\n}\n"
},
{
"path": "RunGroopWebApp/appsettings.Development.json",
"chars": 119,
"preview": "{\n \"Logging\": {\n \"LogLevel\": {\n \"Default\": \"Information\",\n \"Microsoft.AspNetCore\": \"Warning\"\n }\n }\n}\n"
},
{
"path": "RunGroopWebApp/appsettings.json",
"chars": 531,
"preview": "{\n \"ConnectionStrings\": {\n \"DefaultConnection\": \"Data Source=DESKTOP-EI2TOGP\\\\SQLEXPRESS;Initial Catalog=RunGroops;I"
},
{
"path": "RunGroopWebApp/wwwroot/css/custom.css",
"chars": 705,
"preview": "@import url('https://fonts.googleapis.com/css2?family=Jua&display=swap');\n\n#logo-text {\n font-family: \"Jua\", sans-ser"
},
{
"path": "RunGroopWebApp/wwwroot/css/entypo.css",
"chars": 20125,
"preview": "@font-face {\n font-family: 'entypo';\n src: url('../fonts/entypo.eot?79395234');\n src: url('../fonts/entypo.eot?793952"
},
{
"path": "RunGroopWebApp/wwwroot/css/socicon.css",
"chars": 9144,
"preview": "@charset \"UTF-8\";\n\n@font-face {\n font-family: \"socicon\";\n src:url(\"../fonts/socicon.eot\");\n src:url(\"../fonts/socicon"
},
{
"path": "RunGroopWebApp/wwwroot/css/theme.css",
"chars": 274023,
"preview": "/*!\n * Bootstrap v4.3.1 (https://getbootstrap.com/)\n * Copyright 2011-2019 The Bootstrap Authors\n * Copyright 2011-2019 "
},
{
"path": "RunGroopWebApp/wwwroot/js/aos.js",
"chars": 14690,
"preview": "!function(e,t){\"object\"==typeof exports&&\"object\"==typeof module?module.exports=t():\"function\"==typeof define&&define.am"
},
{
"path": "RunGroopWebApp/wwwroot/js/bootstrap.js",
"chars": 57865,
"preview": "/*!\n * Bootstrap v4.3.1\n * Copyright 2011-2019 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contrib"
},
{
"path": "RunGroopWebApp/wwwroot/js/custom.js",
"chars": 1022,
"preview": "const search = document.getElementById(\"registerLocation\");\nconst matchList = document.getElementById(\"datalistOptions\""
},
{
"path": "RunGroopWebApp/wwwroot/js/flickity.pkgd.js",
"chars": 118623,
"preview": "/*!\n * Flickity PACKAGED v2.2.0\n * Touch, responsive, flickable carousels\n *\n * Licensed GPLv3 for open source use\n * or"
},
{
"path": "RunGroopWebApp/wwwroot/js/prism.js",
"chars": 24473,
"preview": "\n/* **********************************************\n Begin prism-core.js\n********************************************"
},
{
"path": "RunGroopWebApp/wwwroot/js/scrollMonitor.js",
"chars": 8964,
"preview": "!function(t,e){\"object\"==typeof exports&&\"object\"==typeof module?module.exports=e():\"function\"==typeof define&&define.am"
},
{
"path": "RunGroopWebApp/wwwroot/js/theme.js",
"chars": 7414,
"preview": "/*!\n * Wingman Bootstrap Theme\n * Copyright 2018-2019 Medium Rare (undefined)\n */\n!function(t,e){\"object\"==typeof exp"
},
{
"path": "RunGroopWebApp.Scraper/Data/ScraperDBContext.cs",
"chars": 887,
"preview": "using Microsoft.EntityFrameworkCore;\nusing RunGroopWebApp.Models;\nusing System;\nusing System.Collections.Generic;\nusing"
},
{
"path": "RunGroopWebApp.Scraper/Extensions/DateTimeExtension.cs",
"chars": 1156,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Linq;\nusing System.Text;\nusing"
},
{
"path": "RunGroopWebApp.Scraper/Interfaces/IAtraScraper.cs",
"chars": 353,
"preview": "using OpenQA.Selenium;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing Syst"
},
{
"path": "RunGroopWebApp.Scraper/Program.cs",
"chars": 537,
"preview": "// See https://aka.ms/new-console-template for more information\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.Ex"
},
{
"path": "RunGroopWebApp.Scraper/RunGroopWebApp.Scraper.csproj",
"chars": 833,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n <PropertyGroup>\n <OutputType>Exe</OutputType>\n <TargetFramework>net6.0</Targe"
},
{
"path": "RunGroopWebApp.Scraper/Services/AtraScraper.cs",
"chars": 4399,
"preview": "using OpenQA.Selenium;\nusing OpenQA.Selenium.Chrome;\nusing RunGroopWebApp.Data;\nusing RunGroopWebApp.Data.Enum;\nusing R"
},
{
"path": "RunGroopWebApp.Scraper/Services/MeetupScraper.cs",
"chars": 4003,
"preview": "using OpenQA.Selenium;\nusing OpenQA.Selenium.Chrome;\nusing RunGroopWebApp.Data.Enum;\nusing RunGroopWebApp.Extensions;\nu"
},
{
"path": "RunGroopWebApp.Tests/Controller/ClubControllerTests.cs",
"chars": 1893,
"preview": "using FakeItEasy;\nusing FluentAssertions;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.AspNetCore.Mvc;\nusing RunGro"
},
{
"path": "RunGroopWebApp.Tests/Repository/ClubRepositoryTests.cs",
"chars": 7212,
"preview": "using FluentAssertions;\nusing Microsoft.EntityFrameworkCore;\nusing RunGroopWebApp.Data;\nusing RunGroopWebApp.Data.Enum;"
},
{
"path": "RunGroopWebApp.Tests/RunGroopWebApp.Tests.csproj",
"chars": 1164,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n <PropertyGroup>\n <TargetFramework>net6.0</TargetFramework>\n <Nullable>enable"
},
{
"path": "RunGroopWebApp.sln",
"chars": 2143,
"preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.0.3191"
}
]
About this extraction
This page contains the full source code of the teddysmithdev/RunGroop GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 119 files (850.3 KB), approximately 233.7k tokens, and a symbol index with 325 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.