├── Reactivities ├── client-app │ ├── .env.production │ ├── src │ │ ├── react-app-env.d.ts │ │ ├── app │ │ │ ├── model │ │ │ │ ├── serverError.ts │ │ │ │ ├── comment.ts │ │ │ │ ├── user.ts │ │ │ │ ├── pagination.ts │ │ │ │ ├── profile.ts │ │ │ │ └── activity.ts │ │ │ ├── common │ │ │ │ ├── options │ │ │ │ │ └── categoryOptions.ts │ │ │ │ ├── modals │ │ │ │ │ └── ModalContainer.tsx │ │ │ │ ├── imageUpload │ │ │ │ │ ├── PhotoWidgetCropper.tsx │ │ │ │ │ ├── PhotoWidgetDropzone.tsx │ │ │ │ │ └── PhotoUploadWidget.tsx │ │ │ │ └── form │ │ │ │ │ ├── MyTextArea.tsx │ │ │ │ │ ├── MyTextInput.tsx │ │ │ │ │ ├── MyDateInput.tsx │ │ │ │ │ └── MySelectInput.tsx │ │ │ ├── layout │ │ │ │ ├── ScrollToTop.tsx │ │ │ │ ├── LoadingComponent.tsx │ │ │ │ ├── PrivateRoute.tsx │ │ │ │ ├── styles.css │ │ │ │ ├── NavBar.tsx │ │ │ │ └── App.tsx │ │ │ └── stores │ │ │ │ ├── modalStore.ts │ │ │ │ ├── store.ts │ │ │ │ ├── commonStore.ts │ │ │ │ ├── userStore.ts │ │ │ │ └── commentStore.ts │ │ ├── features │ │ │ ├── activities │ │ │ │ ├── details │ │ │ │ │ ├── ActivityDetailed.tsx │ │ │ │ │ ├── ActivityDetails.tsx │ │ │ │ │ ├── ActivityDetailedInfo.tsx │ │ │ │ │ └── ActivityDetailedSidebar.tsx │ │ │ │ └── dashboard │ │ │ │ │ ├── ActivityList.tsx │ │ │ │ │ ├── ActivityFilters.tsx │ │ │ │ │ ├── AcivityListItemAttendee.tsx │ │ │ │ │ ├── ActivityListItemPlaceholder.tsx │ │ │ │ │ └── ActivityDashboard.tsx │ │ │ ├── errors │ │ │ │ ├── ValidationErrors.tsx │ │ │ │ ├── NotFound.tsx │ │ │ │ ├── ServerError.tsx │ │ │ │ └── TestError.tsx │ │ │ ├── profiles │ │ │ │ ├── ProfileCard.tsx │ │ │ │ ├── ProfileFollowings.tsx │ │ │ │ ├── ProfilePage.tsx │ │ │ │ ├── ProfileContent.tsx │ │ │ │ ├── ProfileDescription.tsx │ │ │ │ ├── FollowButton.tsx │ │ │ │ ├── ProfileHeader.tsx │ │ │ │ ├── ProfileEditForm.tsx │ │ │ │ └── ProfileActivities.tsx │ │ │ ├── users │ │ │ │ ├── LoginForm.tsx │ │ │ │ └── RegisterForm.tsx │ │ │ └── home │ │ │ │ └── HomePage.tsx │ │ ├── setupTests.ts │ │ ├── reportWebVitals.ts │ │ ├── App.css │ │ ├── index.tsx │ │ └── logo.svg │ ├── public │ │ ├── robots.txt │ │ ├── favicon.ico │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── assets │ │ │ ├── logo.png │ │ │ ├── user.png │ │ │ ├── placeholder.png │ │ │ └── categoryImages │ │ │ │ ├── film.jpg │ │ │ │ ├── food.jpg │ │ │ │ ├── music.jpg │ │ │ │ ├── culture.jpg │ │ │ │ ├── drinks.jpg │ │ │ │ └── travel.jpg │ │ ├── manifest.json │ │ └── index.html │ ├── .env.development │ ├── .gitignore │ ├── tsconfig.json │ ├── README.md │ └── package.json ├── API │ ├── wwwroot │ │ ├── robots.txt │ │ ├── favicon.ico │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── assets │ │ │ ├── logo.png │ │ │ ├── user.png │ │ │ ├── placeholder.png │ │ │ └── categoryImages │ │ │ │ ├── drinks.jpg │ │ │ │ ├── film.jpg │ │ │ │ ├── food.jpg │ │ │ │ ├── music.jpg │ │ │ │ ├── travel.jpg │ │ │ │ └── culture.jpg │ │ ├── static │ │ │ ├── media │ │ │ │ ├── flags.9c74e172.png │ │ │ │ ├── icons.8e3c7f55.eot │ │ │ │ ├── icons.b87b9ba5.ttf │ │ │ │ ├── icons.faff9214.woff │ │ │ │ ├── icons.0ab54153.woff2 │ │ │ │ ├── brand-icons.13db00b7.eot │ │ │ │ ├── brand-icons.c5ebe0b3.ttf │ │ │ │ ├── brand-icons.a046592b.woff │ │ │ │ ├── brand-icons.e8c322de.woff2 │ │ │ │ ├── outline-icons.701ae6ab.eot │ │ │ │ ├── outline-icons.ad97afd3.ttf │ │ │ │ ├── outline-icons.cd6c777f.woff2 │ │ │ │ └── outline-icons.ef60a4f6.woff │ │ │ ├── css │ │ │ │ ├── main.88462492.chunk.css │ │ │ │ └── main.88462492.chunk.css.map │ │ │ └── js │ │ │ │ └── runtime~main.a8a9905a.js │ │ ├── manifest.json │ │ ├── asset-manifest.json │ │ ├── service-worker.js │ │ ├── index.html │ │ ├── precache-manifest.6a292ab25a73b8d93b860646affa8d63.js │ │ └── precache-manifest.aa7497f6b9965e8bb998a85b893d1346.js │ ├── DTOs │ │ ├── LoginDTO.cs │ │ ├── UserDto.cs │ │ └── RegisterDto.cs │ ├── WeatherForecast.cs │ ├── appsettings.json │ ├── appsettings.Development.json │ ├── Controllers │ │ ├── FallbackController.cs │ │ ├── BuggyController.cs │ │ ├── PhotosController.cs │ │ ├── FollowController.cs │ │ ├── ProfilesController.cs │ │ ├── WeatherForecastController.cs │ │ ├── BaseApiController.cs │ │ └── ActivitiesController.cs │ ├── obj │ │ ├── API.csproj.nuget.g.targets │ │ └── API.csproj.nuget.g.props │ ├── Extensions │ │ ├── HttpExtensions.cs │ │ └── IdentityServiceExtensions.cs │ ├── Properties │ │ └── launchSettings.json │ ├── SignalR │ │ └── ChatHub.cs │ ├── API.csproj │ ├── Services │ │ └── TokenService.cs │ ├── Middleware │ │ └── ExceptionMiddleware.cs │ └── Program.cs ├── Domain │ ├── obj │ │ ├── Domain.csproj.nuget.g.targets │ │ ├── Domain.csproj.nuget.g.props │ │ ├── Domain.csproj.nuget.dgspec.json │ │ └── project.nuget.cache │ ├── Photo.cs │ ├── Domain.csproj │ ├── Comment.cs │ ├── UserFollowing.cs │ ├── ActivityAttendee.cs │ ├── AppUser.cs │ └── Activity.cs ├── Application │ ├── obj │ │ ├── Application.csproj.nuget.g.targets │ │ └── Application.csproj.nuget.g.props │ ├── Interfaces │ │ ├── IUserAccessor.cs │ │ └── IPhotoAccessor.cs │ ├── Photos │ │ ├── PhotoUploadResult.cs │ │ ├── SetMain.cs │ │ ├── Add.cs │ │ └── Delete.cs │ ├── Activities │ │ ├── ActivityParams.cs │ │ ├── AttendeeDto.cs │ │ ├── ActivityValidator.cs │ │ ├── ActivityDto.cs │ │ ├── Delete.cs │ │ ├── Details.cs │ │ ├── Edit.cs │ │ ├── Create.cs │ │ ├── List.cs │ │ └── UpdateAttendance.cs │ ├── Comments │ │ ├── CommentDto.cs │ │ ├── List.cs │ │ └── Create.cs │ ├── Profiles │ │ ├── UserActivityDto.cs │ │ ├── Profile.cs │ │ ├── Details.cs │ │ ├── Edit.cs │ │ └── ListActivities.cs │ ├── Core │ │ ├── PagingParams.cs │ │ ├── Result.cs │ │ ├── AppException.cs │ │ ├── PagedList.cs │ │ └── MappinngProfiles.cs │ ├── Application.csproj │ └── Followers │ │ ├── FollowToggle.cs │ │ └── List.cs ├── Persistence │ ├── obj │ │ ├── Persistence.csproj.nuget.g.targets │ │ ├── Persistence.csproj.nuget.g.props │ │ └── project.nuget.cache │ ├── Persistence.csproj │ └── DataContext.cs ├── Infrastructure │ ├── Photos │ │ ├── CloudinarySettings.cs │ │ └── PhotoAccessor.cs │ ├── Infrastructure.csproj │ └── Security │ │ ├── UserAccessor.cs │ │ └── IsHostRequirement.cs └── Reactivities.sln └── README.md /Reactivities/client-app/.env.production: -------------------------------------------------------------------------------- 1 | REACT_APP_API_URL=/api 2 | REACT_APP_CHAT_URL=/chat -------------------------------------------------------------------------------- /Reactivities/client-app/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /Reactivities/client-app/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/favicon.ico -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/logo192.png -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/logo512.png -------------------------------------------------------------------------------- /Reactivities/client-app/.env.development: -------------------------------------------------------------------------------- 1 | REACT_APP_API_URL=https://localhost:7246/api 2 | REACT_APP_CHAT_URL=https://localhost:7246/chat -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/assets/logo.png -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/assets/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/assets/user.png -------------------------------------------------------------------------------- /Reactivities/client-app/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/client-app/public/favicon.ico -------------------------------------------------------------------------------- /Reactivities/client-app/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/client-app/public/logo192.png -------------------------------------------------------------------------------- /Reactivities/client-app/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/client-app/public/logo512.png -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/assets/placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/assets/placeholder.png -------------------------------------------------------------------------------- /Reactivities/client-app/public/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/client-app/public/assets/logo.png -------------------------------------------------------------------------------- /Reactivities/client-app/public/assets/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/client-app/public/assets/user.png -------------------------------------------------------------------------------- /Reactivities/client-app/public/assets/placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/client-app/public/assets/placeholder.png -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/assets/categoryImages/drinks.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/assets/categoryImages/drinks.jpg -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/assets/categoryImages/film.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/assets/categoryImages/film.jpg -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/assets/categoryImages/food.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/assets/categoryImages/food.jpg -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/assets/categoryImages/music.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/assets/categoryImages/music.jpg -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/assets/categoryImages/travel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/assets/categoryImages/travel.jpg -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/static/media/flags.9c74e172.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/static/media/flags.9c74e172.png -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/static/media/icons.8e3c7f55.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/static/media/icons.8e3c7f55.eot -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/static/media/icons.b87b9ba5.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/static/media/icons.b87b9ba5.ttf -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/static/media/icons.faff9214.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/static/media/icons.faff9214.woff -------------------------------------------------------------------------------- /Reactivities/client-app/src/app/model/serverError.ts: -------------------------------------------------------------------------------- 1 | 2 | export interface ServerError { 3 | statusCode: number; 4 | message: string; 5 | details: string; 6 | } -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/assets/categoryImages/culture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/assets/categoryImages/culture.jpg -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/static/media/icons.0ab54153.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/static/media/icons.0ab54153.woff2 -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/static/media/brand-icons.13db00b7.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/static/media/brand-icons.13db00b7.eot -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/static/media/brand-icons.c5ebe0b3.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/static/media/brand-icons.c5ebe0b3.ttf -------------------------------------------------------------------------------- /Reactivities/client-app/public/assets/categoryImages/film.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/client-app/public/assets/categoryImages/film.jpg -------------------------------------------------------------------------------- /Reactivities/client-app/public/assets/categoryImages/food.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/client-app/public/assets/categoryImages/food.jpg -------------------------------------------------------------------------------- /Reactivities/client-app/public/assets/categoryImages/music.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/client-app/public/assets/categoryImages/music.jpg -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/static/media/brand-icons.a046592b.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/static/media/brand-icons.a046592b.woff -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/static/media/brand-icons.e8c322de.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/static/media/brand-icons.e8c322de.woff2 -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/static/media/outline-icons.701ae6ab.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/static/media/outline-icons.701ae6ab.eot -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/static/media/outline-icons.ad97afd3.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/static/media/outline-icons.ad97afd3.ttf -------------------------------------------------------------------------------- /Reactivities/client-app/public/assets/categoryImages/culture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/client-app/public/assets/categoryImages/culture.jpg -------------------------------------------------------------------------------- /Reactivities/client-app/public/assets/categoryImages/drinks.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/client-app/public/assets/categoryImages/drinks.jpg -------------------------------------------------------------------------------- /Reactivities/client-app/public/assets/categoryImages/travel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/client-app/public/assets/categoryImages/travel.jpg -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/static/media/outline-icons.cd6c777f.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/static/media/outline-icons.cd6c777f.woff2 -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/static/media/outline-icons.ef60a4f6.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dragon0513/react-dotnet/HEAD/Reactivities/API/wwwroot/static/media/outline-icons.ef60a4f6.woff -------------------------------------------------------------------------------- /Reactivities/Domain/obj/Domain.csproj.nuget.g.targets: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Reactivities/API/DTOs/LoginDTO.cs: -------------------------------------------------------------------------------- 1 | namespace API.DTOs 2 | { 3 | public class LoginDTO 4 | { 5 | public string Email { get; set; } 6 | public string Password { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Reactivities/Application/obj/Application.csproj.nuget.g.targets: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Reactivities/Persistence/obj/Persistence.csproj.nuget.g.targets: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Reactivities/client-app/src/features/activities/details/ActivityDetailed.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default function ActivityDetailed() { 4 | return ( 5 |

Detailed

6 | ) 7 | } -------------------------------------------------------------------------------- /Reactivities/client-app/src/app/model/comment.ts: -------------------------------------------------------------------------------- 1 | export interface ChatComment { 2 | id: number; 3 | createdAt: string; 4 | body: string; 5 | username: string; 6 | displayName: string; 7 | image: string; 8 | } -------------------------------------------------------------------------------- /Reactivities/client-app/src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /Reactivities/API/DTOs/UserDto.cs: -------------------------------------------------------------------------------- 1 | namespace API.DTOs 2 | { 3 | public class UserDto 4 | { 5 | public string DisplayName { get; set; } 6 | public string Token { get; set; } 7 | public string Username { get; set; } 8 | public string Image { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Reactivities/client-app/src/app/model/user.ts: -------------------------------------------------------------------------------- 1 | export interface User { 2 | username: string; 3 | displayName: string; 4 | token: string; 5 | image?: string; 6 | } 7 | 8 | export interface UserFormValues { 9 | email: string; 10 | password: string; 11 | displayName?: string; 12 | username?: string; 13 | } -------------------------------------------------------------------------------- /Reactivities/Application/Interfaces/IUserAccessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Application.Interfaces 8 | { 9 | public interface IUserAccessor 10 | { 11 | string GetUsername(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Reactivities/client-app/src/app/common/options/categoryOptions.ts: -------------------------------------------------------------------------------- 1 | export const categoryOptions = [ 2 | {text: 'Drinks', value: 'drinks'}, 3 | {text: 'Culture', value: 'culture'}, 4 | {text: 'Film', value: 'film'}, 5 | {text: 'Food', value: 'food'}, 6 | {text: 'Music', value: 'music'}, 7 | {text: 'Travel', value: 'travel'}, 8 | ] -------------------------------------------------------------------------------- /Reactivities/client-app/src/app/layout/ScrollToTop.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect } from "react"; 2 | import { useLocation } from "react-router-dom"; 3 | 4 | export default function ScrollToTop () { 5 | const pathName = useLocation(); 6 | 7 | useEffect(() => { 8 | window.scroll(0, 0); 9 | }, [pathName]); 10 | 11 | return null; 12 | } -------------------------------------------------------------------------------- /Reactivities/API/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | namespace API 2 | { 3 | public class WeatherForecast 4 | { 5 | public DateTime Date { get; set; } 6 | 7 | public int TemperatureC { get; set; } 8 | 9 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 10 | 11 | public string? Summary { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /Reactivities/API/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "Cloudinary": { 10 | "CloudName": "dvbaicnsy", 11 | "ApiKey": "653932124153488", 12 | "ApiSecret": "9cwxO2jxqtR-rXdpyGm_4SvanE4" 13 | } 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /Reactivities/Domain/Photo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Domain 8 | { 9 | public class Photo 10 | { 11 | public string Id { get; set; } 12 | public string Url { get; set; } 13 | public bool IsMain { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Reactivities/API/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "DefaultConnection": "Server=localhost; Port=5432; User Id=admin; Password=secret; Database=reactivities" 4 | }, 5 | "TokenKey": "super secret key", 6 | "Logging": { 7 | "LogLevel": { 8 | "Default": "Information", 9 | "Microsoft.AspNetCore": "Warning" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Reactivities/Application/Photos/PhotoUploadResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Application.Photos 8 | { 9 | public class PhotoUploadResult 10 | { 11 | public string PublicId { get; set; } 12 | 13 | public string Url { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Reactivities/Domain/Domain.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Reactivities/client-app/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /Reactivities/Infrastructure/Photos/CloudinarySettings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Infrastructure.Photos 8 | { 9 | public class CloudinarySettings 10 | { 11 | public string CloudName { get; set; } 12 | 13 | public string ApiKey { get; set; } 14 | 15 | public string ApiSecret { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Reactivities/client-app/src/app/layout/LoadingComponent.tsx: -------------------------------------------------------------------------------- 1 | 2 | import React from 'react'; 3 | import {Dimmer, Loader} from 'semantic-ui-react'; 4 | 5 | interface Props { 6 | inverted?: boolean; 7 | content?: string; 8 | } 9 | 10 | export default function LoadingComponent({inverted = true, content = 'Loading...'}: Props) { 11 | return ( 12 | 13 | 14 | 15 | ) 16 | } -------------------------------------------------------------------------------- /Reactivities/Application/Interfaces/IPhotoAccessor.cs: -------------------------------------------------------------------------------- 1 | using Application.Photos; 2 | using Microsoft.AspNetCore.Http; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Application.Interfaces 10 | { 11 | public interface IPhotoAccessor 12 | { 13 | Task AddPhoto(IFormFile file); 14 | Task DeletePhoto(string publicId); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Reactivities/API/Controllers/FallbackController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | using Microsoft.AspNetCore.Mvc; 3 | 4 | namespace API.Controllers 5 | { 6 | public class FallbackController : Controller 7 | { 8 | [AllowAnonymous] 9 | public IActionResult Index() 10 | { 11 | return PhysicalFile(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", 12 | "index.html"), "text/HTML"); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Reactivities/Application/Activities/ActivityParams.cs: -------------------------------------------------------------------------------- 1 | using Application.Core; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Application.Activities 9 | { 10 | public class ActivityParams : PagingParams 11 | { 12 | public bool IsGoing { get; set; } 13 | public bool IsHost { get; set; } 14 | public DateTime StartDate { get; set; } = DateTime.UtcNow; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Reactivities/Domain/Comment.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Domain 8 | { 9 | public class Comment 10 | { 11 | public int Id { get; set; } 12 | public string Body { get; set; } 13 | public AppUser Author { get; set; } 14 | public Activity Activity { get; set; } 15 | public DateTime CreatedAt { get; set; } = DateTime.UtcNow; 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Reactivities/Domain/UserFollowing.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Domain 9 | { 10 | public class UserFollowing 11 | { 12 | public string ObserverId { get; set; } 13 | public AppUser Observer { get; set; } 14 | 15 | public string TargetId { get; set; } 16 | public AppUser Target { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Reactivities/Infrastructure/Infrastructure.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Reactivities/client-app/src/reportWebVitals.ts: -------------------------------------------------------------------------------- 1 | import { ReportHandler } from 'web-vitals'; 2 | 3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => { 4 | if (onPerfEntry && onPerfEntry instanceof Function) { 5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 6 | getCLS(onPerfEntry); 7 | getFID(onPerfEntry); 8 | getFCP(onPerfEntry); 9 | getLCP(onPerfEntry); 10 | getTTFB(onPerfEntry); 11 | }); 12 | } 13 | }; 14 | 15 | export default reportWebVitals; 16 | -------------------------------------------------------------------------------- /Reactivities/Domain/ActivityAttendee.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Domain 8 | { 9 | public class ActivityAttendee 10 | { 11 | public string AppUserId { get; set; } 12 | 13 | public AppUser AppUser { get; set; } 14 | 15 | public Guid ActivityId { get; set; } 16 | 17 | public Activity Activity { get; set; } 18 | 19 | public bool IsHost { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Reactivities/Application/Comments/CommentDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Application.Comments 8 | { 9 | public class CommentDto 10 | { 11 | public int Id { get; set; } 12 | public DateTime CreatedAt { get; set; } 13 | public string Body { get; set; } 14 | public string Username { get; set; } 15 | public string DisplayName { get; set; } 16 | public string Image { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Reactivities/API/obj/API.csproj.nuget.g.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Reactivities/API/DTOs/RegisterDto.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace API.DTOs 4 | { 5 | public class RegisterDto 6 | { 7 | [Required] 8 | public string DisplayName { get; set; } 9 | 10 | [Required] 11 | [EmailAddress] 12 | public string Email { get; set; } 13 | 14 | [Required] 15 | [RegularExpression("(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{4,8}$", ErrorMessage = "Password must be complex.")] 16 | public string Password { get; set; } 17 | public string Username { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Reactivities/client-app/src/app/common/modals/ModalContainer.tsx: -------------------------------------------------------------------------------- 1 | import { observer } from "mobx-react-lite"; 2 | import React from "react"; 3 | import { Modal } from "semantic-ui-react"; 4 | import { useStore } from "../../stores/store"; 5 | 6 | export default observer(function ModalContainer() { 7 | const {modalStore} = useStore(); 8 | 9 | return ( 10 | 11 | 12 | {modalStore.modal.body} 13 | 14 | 15 | ) 16 | }) -------------------------------------------------------------------------------- /Reactivities/Application/Profiles/UserActivityDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.Json.Serialization; 6 | using System.Threading.Tasks; 7 | 8 | namespace Application.Profiles 9 | { 10 | public class UserActivityDto 11 | { 12 | public Guid Id { get; set; } 13 | public string Title { get; set; } 14 | public string Category { get; set; } 15 | public DateTime Date { get; set; } 16 | 17 | [JsonIgnore] 18 | public string HostUsername { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Reactivities/Application/Core/PagingParams.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Application.Core 8 | { 9 | public class PagingParams 10 | { 11 | private const int MaxPageSize = 50; 12 | public int PageNumber { get; set; } = 1; 13 | 14 | 15 | private int _pageSize = 10; 16 | 17 | public int PageSize 18 | { 19 | get => _pageSize; 20 | set => _pageSize = (value > MaxPageSize) ? MaxPageSize : value; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Reactivities/client-app/src/features/errors/ValidationErrors.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Message } from 'semantic-ui-react'; 3 | 4 | interface Props { 5 | errors: any; 6 | } 7 | 8 | export default function ValidationErrors({errors} : Props) { 9 | return ( 10 | 11 | {errors && ( 12 | 13 | {errors.map((err: any, i: any) => ( 14 | {err} 15 | ))} 16 | 17 | )} 18 | 19 | ) 20 | } -------------------------------------------------------------------------------- /Reactivities/Application/Core/Result.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Application.Core 8 | { 9 | public class Result 10 | { 11 | public bool IsSuccess { get; set; } 12 | public T Value { get; set; } 13 | public string Error { get; set; } 14 | 15 | public static Result Success(T value) => new Result { IsSuccess = true, Value = value }; 16 | public static Result Failure(string error) => new Result { IsSuccess = false, Error = error }; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /Reactivities/client-app/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /Reactivities/API/wwwroot/static/css/main.88462492.chunk.css: -------------------------------------------------------------------------------- 1 | body{background-color:#eaeaea!important}.ui.inverted.top.fixed.menu{background-image:linear-gradient(135deg,#182a73,#218aae 64%,#20a7ac 89%)!important}.react-calendar{width:100%;border:0 rgba(34,36,38,.15)}.react-datepicker-wrapper{width:100%}.masthead{display:flex;align-items:center;background-image:linear-gradient(135deg,#182a73,#218aae 69%,#20a7ac 89%)!important;height:100vh}.masthead .ui.menu .ui.button,.ui.menu a.ui.inverted.button{margin-left:.5em}.masthead h1.ui.header{font-size:4em;font-weight:400}.masthead h2{font-size:1.7em;font-weight:400} 2 | /*# sourceMappingURL=main.88462492.chunk.css.map */ -------------------------------------------------------------------------------- /Reactivities/client-app/src/app/layout/PrivateRoute.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Redirect, Route, RouteComponentProps, RouteProps } from "react-router-dom"; 3 | import { useStore } from "../stores/store"; 4 | 5 | interface Props extends RouteProps { 6 | component: React.ComponentType> | React.ComponentType; 7 | } 8 | 9 | export default function PrivateRoute({component: Component, ...rest}: Props) { 10 | const {userStore: {isLoggedIn}} = useStore(); 11 | 12 | return ( 13 | isLoggedIn ? : } /> 14 | ) 15 | } -------------------------------------------------------------------------------- /Reactivities/client-app/src/app/stores/modalStore.ts: -------------------------------------------------------------------------------- 1 | import { makeAutoObservable } from "mobx"; 2 | 3 | interface Modal { 4 | open: boolean; 5 | body: JSX.Element | null; 6 | } 7 | 8 | export default class ModalStore { 9 | modal: Modal = { 10 | open: false, 11 | body: null 12 | } 13 | 14 | constructor() { 15 | makeAutoObservable(this) 16 | } 17 | 18 | openModal = (content: JSX.Element) => { 19 | this.modal.open = true; 20 | this.modal.body = content; 21 | } 22 | 23 | closeModal = () => { 24 | this.modal.open = false; 25 | this.modal.body = null; 26 | } 27 | } -------------------------------------------------------------------------------- /Reactivities/Application/Core/AppException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Application.Core 8 | { 9 | public class AppException 10 | { 11 | public AppException(int statusCode, string message, string details = "") 12 | { 13 | StatusCode = statusCode; 14 | Message = message; 15 | Details = details; 16 | } 17 | 18 | public int StatusCode { get; set; } 19 | public string Message { get; set; } 20 | public string Details { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Reactivities/Application/Activities/AttendeeDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Application.Activities 8 | { 9 | public class AttendeeDto 10 | { 11 | public string Username { get; set; } 12 | 13 | public string DisplayName { get; set; } 14 | 15 | public string Bio { get; set; } 16 | 17 | public string Image { get; set; } 18 | 19 | 20 | 21 | public bool Following { get; set; } 22 | public int FollowersCount { get; set; } 23 | public int FollowingsCount { get; set; } 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Reactivities/client-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "noFallthroughCasesInSwitch": true, 16 | "module": "esnext", 17 | "moduleResolution": "node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "noEmit": true, 21 | "jsx": "preserve" 22 | }, 23 | "include": [ 24 | "src" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /Reactivities/Domain/AppUser.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Identity; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Domain 9 | { 10 | public class AppUser : IdentityUser 11 | { 12 | public string DisplayName { get; set; } 13 | public string Bio{ get; set; } 14 | public ICollection Activities { get; set; } 15 | public ICollection Photos { get; set; } 16 | 17 | public ICollection Followings { get; set; } 18 | public ICollection Followers { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Reactivities/Persistence/Persistence.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | net6.0 18 | enable 19 | enable 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Reactivities/client-app/src/app/model/pagination.ts: -------------------------------------------------------------------------------- 1 | export interface Pagination { 2 | currentPage: number; 3 | itemsPerPage: number; 4 | totalItems: number; 5 | totalPages: number; 6 | } 7 | 8 | export class PaginatedResult { 9 | data: T; 10 | pagination: Pagination; 11 | 12 | constructor(data: T, pagination: Pagination) { 13 | this.data = data; 14 | this.pagination = pagination; 15 | } 16 | } 17 | 18 | export class PagingParams { 19 | pageNumber: number; 20 | pageSize: number; 21 | 22 | constructor(pageNumber = 1, pageSize = 2) { 23 | this.pageNumber = pageNumber; 24 | this.pageSize = pageSize; 25 | } 26 | } -------------------------------------------------------------------------------- /Reactivities/client-app/src/app/common/imageUpload/PhotoWidgetCropper.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Cropper} from 'react-cropper'; 3 | import 'cropperjs/dist/cropper.css'; 4 | 5 | interface Props { 6 | imagePreview: string; 7 | setCropper: (cropper: Cropper) => void; 8 | } 9 | 10 | export default function PhotoWidgetCropper({imagePreview, setCropper}: Props) { 11 | return ( 12 | setCropper(cropper)} 15 | /> 16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /Reactivities/client-app/src/features/errors/NotFound.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link } from "react-router-dom"; 3 | import { Button, Header, Icon, Segment } from "semantic-ui-react"; 4 | 5 | export default function NotFound () { 6 | return ( 7 | 8 |
9 | 10 | Oops - we've looked everywhere and could not find this. 11 |
12 | 13 | 16 | 17 |
18 | ) 19 | } -------------------------------------------------------------------------------- /Reactivities/Application/Profiles/Profile.cs: -------------------------------------------------------------------------------- 1 | using Domain; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Application.Profiles 9 | { 10 | public class Profile 11 | { 12 | public string Username { get; set; } 13 | 14 | public string DisplayName { get; set; } 15 | 16 | public string Bio { get; set; } 17 | 18 | public string Image { get; set; } 19 | 20 | 21 | public bool Following { get; set; } 22 | public int FollowersCount { get; set; } 23 | public int FollowingsCount { get; set; } 24 | 25 | 26 | public ICollection Photos { get; set; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Reactivities/Application/Activities/ActivityValidator.cs: -------------------------------------------------------------------------------- 1 | using Domain; 2 | using FluentValidation; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Application.Activities 10 | { 11 | public class ActivityValidator : AbstractValidator 12 | { 13 | public ActivityValidator() 14 | { 15 | RuleFor(x => x.Title).NotEmpty(); 16 | RuleFor(x => x.Description).NotEmpty(); 17 | RuleFor(x => x.Date).NotEmpty(); 18 | RuleFor(x => x.Category).NotEmpty(); 19 | RuleFor(x => x.City).NotEmpty(); 20 | RuleFor(x => x.Venue).NotEmpty(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Reactivities/API/Extensions/HttpExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json; 2 | 3 | namespace API.Extensions 4 | { 5 | public static class HttpExtensions 6 | { 7 | public static void AddPaginationHeader(this HttpResponse response, int currentPage, 8 | int itemsPerPage, int totalItems, int totalPages) 9 | { 10 | var paginationHeader = new 11 | { 12 | currentPage, 13 | itemsPerPage, 14 | totalItems, 15 | totalPages 16 | }; 17 | response.Headers.Add("Pagination", JsonSerializer.Serialize(paginationHeader)); 18 | response.Headers.Add("Access-Control-Expose-Headers", "Pagination"); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Reactivities/client-app/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Reactivities/client-app/src/app/common/form/MyTextArea.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { useField } from 'formik'; 3 | import { Form, Label } from 'semantic-ui-react'; 4 | 5 | interface Props { 6 | placeholder: string; 7 | name: string; 8 | rows: number; 9 | label?: string; 10 | } 11 | 12 | export default function MyTextArea(props: Props) { 13 | const[field, meta] = useField(props.name); 14 | return ( 15 | 16 | 17 |