Add Blazor WebApp and rework data handling to utilize Entity Framework
This commit is contained in:
@@ -1,10 +0,0 @@
|
||||
namespace Core.Entities;
|
||||
|
||||
public class AssignmentAssumption(CompetitiveEvent @event, Student student, Assumption assumption)
|
||||
{
|
||||
public CompetitiveEvent Event { get; } = @event;
|
||||
public Student Student { get; } = student;
|
||||
public Assumption Assumption { get; } = assumption;
|
||||
|
||||
public EventAssignment EventAssignment => new(@event, student);
|
||||
}
|
||||
@@ -3,8 +3,8 @@
|
||||
public class AssignmentParameters(
|
||||
int effortLowerBound = 6,
|
||||
int effortUpperBound = 8,
|
||||
int assignmentLowerBound = 2,
|
||||
int assignmentUpperBound = 4,
|
||||
int eventsLowerBound = 2,
|
||||
int eventsUpperBound = 4,
|
||||
int teamSizeLimit = 4,
|
||||
bool limitTeamsToOne = true,
|
||||
bool requireRegional = true,
|
||||
@@ -12,11 +12,20 @@
|
||||
{
|
||||
public int EffortLowerBound { get; set; } = effortLowerBound;
|
||||
public int EffortUpperBound { get; set; } = effortUpperBound;
|
||||
public int AssignmentLowerBound { get; set; } = assignmentLowerBound;
|
||||
public int AssignmentUpperBound { get; set; } = assignmentUpperBound;
|
||||
public int EventsLowerBound { get; set; } = eventsLowerBound;
|
||||
public int EventsUpperBound { get; set; } = eventsUpperBound;
|
||||
public int TeamSizeLimit { get; set; } = teamSizeLimit;
|
||||
public bool LimitTeamsToOne { get; set; } = limitTeamsToOne;
|
||||
public bool RequireRegional { get; set; } = requireRegional;
|
||||
public bool RequireOnSite { get; set; } = requireOnSite;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Team Size Limit: {TeamSizeLimit}" + Environment.NewLine +
|
||||
$"Require Regional: {RequireRegional}" + Environment.NewLine +
|
||||
$"Require On-site: {RequireOnSite}" + Environment.NewLine +
|
||||
$"Events Range: [{EventsLowerBound}-{EventsUpperBound}]" + Environment.NewLine +
|
||||
$"Effort Range: [{EffortLowerBound}-{EffortUpperBound}]";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Core.Entities;
|
||||
|
||||
public class AssignmentRequirement(EventDefinition eventDefinition, Student student, Requirement requirement)
|
||||
{
|
||||
public EventDefinition EventDefinition { get; } = eventDefinition;
|
||||
public Student Student { get; } = student;
|
||||
public Requirement Requirement { get; } = requirement;
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
namespace Core.Entities;
|
||||
|
||||
public class CompetitiveEvent
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string ShortName { get; set; }
|
||||
public EventFormat Format { get; set; }
|
||||
public int MinTeamSize { get; set; }
|
||||
public int MaxTeamSize { get; set; }
|
||||
|
||||
public string TeamSize =>
|
||||
MinTeamSize == MaxTeamSize
|
||||
? MinTeamSize.ToString()
|
||||
: $"{MinTeamSize.ToString()}-{MaxTeamSize.ToString()}";
|
||||
|
||||
public string SemifinalistActivity { get; set; }
|
||||
|
||||
public bool InterviewOrPresentation
|
||||
=> SemifinalistActivity.Contains("Interview") || SemifinalistActivity.Contains("Presentation");
|
||||
|
||||
public bool OnSiteActivity
|
||||
=> SemifinalistActivity.Contains("Challenge")
|
||||
|| SemifinalistActivity.Contains("Race")
|
||||
|| SemifinalistActivity.Contains("Speech")
|
||||
|| SemifinalistActivity.Contains("Test")
|
||||
|| SemifinalistActivity.Contains("Flight")
|
||||
|| SemifinalistActivity.Contains("Debate")
|
||||
|| SemifinalistActivity.Contains("Photography")
|
||||
|| SemifinalistActivity.Contains("Build")
|
||||
|| Name.Contains("Chapter")
|
||||
|| Name.Contains("Essay")
|
||||
|| SemifinalistActivity.Contains("Fly");
|
||||
|
||||
public string RegionalNotes { get; set; }
|
||||
|
||||
public int MaxTeamCountState { get; set; }
|
||||
public bool RegionalEvent { get; set; }
|
||||
|
||||
public bool RegionalPresubmit { get; set; }
|
||||
public bool StatePresubmission { get; set; }
|
||||
public bool StatePretesting { get; set; }
|
||||
public bool StatePreliminaryRound { get; set; }
|
||||
|
||||
public string Documentation { get; set; }
|
||||
|
||||
public string Eligibility { get; set; }
|
||||
public string Theme { get; set; }
|
||||
public string Description { get; set; }
|
||||
public int? LevelOfEffort { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
public static readonly CompetitiveEvent GeneralSchedule = new(){Name = "General Schedule"};
|
||||
public static readonly CompetitiveEvent VotingDelegates = new(){Name = "Voting Delegates"};
|
||||
|
||||
|
||||
public string EventAttributes ()
|
||||
{
|
||||
var st = new List<string>();
|
||||
|
||||
if (Format is EventFormat.Individual)
|
||||
st.Add( "Ind.");
|
||||
if (RegionalEvent)
|
||||
st.Add( "Reg.");
|
||||
|
||||
return string.Join(", ", st);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,7 @@
|
||||
namespace Core.Entities;
|
||||
|
||||
public class EventAssignment
|
||||
public class EventAssignment(EventDefinition eventDefinition, Student student)
|
||||
{
|
||||
public CompetitiveEvent Event { get; }
|
||||
public Student Student { get; }
|
||||
|
||||
public EventAssignment(CompetitiveEvent @event, Student student)
|
||||
{
|
||||
Event = @event;
|
||||
Student = student;
|
||||
}
|
||||
public EventDefinition EventDefinition { get; } = eventDefinition;
|
||||
public Student Student { get; } = student;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Core.Entities;
|
||||
|
||||
public class EventDefinition
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string? ShortName { get; set; }
|
||||
public EventFormat EventFormat { get; set; }
|
||||
|
||||
[Range(1, 6)]
|
||||
public int MinTeamSize { get; set; }
|
||||
|
||||
[Range(1, 6)]
|
||||
public int MaxTeamSize { get; set; }
|
||||
|
||||
public string TeamSize =>
|
||||
MinTeamSize == MaxTeamSize
|
||||
? MinTeamSize.ToString()
|
||||
: $"{MinTeamSize.ToString()}-{MaxTeamSize.ToString()}";
|
||||
|
||||
public string? SemifinalistActivity { get; set; }
|
||||
|
||||
public bool InterviewOrPresentation
|
||||
=> SemifinalistActivity != null && (SemifinalistActivity.Contains("Interview") || SemifinalistActivity.Contains("Presentation"));
|
||||
|
||||
public bool OnSiteActivity
|
||||
=> SemifinalistActivity != null
|
||||
&& (SemifinalistActivity.Contains("Challenge")
|
||||
|| SemifinalistActivity.Contains("Race")
|
||||
|| SemifinalistActivity.Contains("Speech")
|
||||
|| SemifinalistActivity.Contains("Test")
|
||||
|| SemifinalistActivity.Contains("Flight")
|
||||
|| Name.Contains("Flight")
|
||||
|| SemifinalistActivity.Contains("Debate")
|
||||
|| SemifinalistActivity.Contains("Photography")
|
||||
|| SemifinalistActivity.Contains("Build")
|
||||
|| Name.Contains("Chapter")
|
||||
|| Name.Contains("Podcast"));
|
||||
|
||||
public string? Notes { get; set; }
|
||||
|
||||
[Range(1, 3)]
|
||||
public int MaxTeamCountState { get; set; }
|
||||
public bool RegionalEvent { get; set; }
|
||||
|
||||
public bool RegionalPresubmit { get; set; }
|
||||
public bool StatePresubmission { get; set; }
|
||||
public bool StatePretesting { get; set; }
|
||||
public bool StatePreliminaryRound { get; set; }
|
||||
|
||||
public string? Documentation { get; set; }
|
||||
|
||||
public string Eligibility { get; set; }
|
||||
public string? Theme { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public int? LevelOfEffort { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
public static readonly EventDefinition GeneralSchedule = new(){Name = "General Schedule"};
|
||||
public static readonly EventDefinition VotingDelegates = new(){Name = "Voting Delegates"};
|
||||
|
||||
|
||||
public string EventAttributes ()
|
||||
{
|
||||
var st = new List<string>();
|
||||
|
||||
if (EventFormat is EventFormat.Individual)
|
||||
st.Add( "Ind.");
|
||||
if (RegionalEvent)
|
||||
st.Add( "Reg.");
|
||||
|
||||
return string.Join(", ", st);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
namespace Core.Entities;
|
||||
|
||||
public class EventStudentPicks
|
||||
{
|
||||
public CompetitiveEvent Event { get; }
|
||||
public IList<Tuple<Student,int>> StudentPicks { get; }
|
||||
|
||||
public EventStudentPicks(CompetitiveEvent @event, IList<Tuple<Student, int>> studentPicks)
|
||||
{
|
||||
Event = @event;
|
||||
StudentPicks = studentPicks;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Core.Entities;
|
||||
|
||||
public enum OfficerRole
|
||||
{
|
||||
President=1,
|
||||
[Display(Name = "Vice President")]
|
||||
VicePresident=2,
|
||||
Secretary=3,
|
||||
Treasurer=4,
|
||||
Reporter=5,
|
||||
[Display(Name = "Sergeant at Arms")]
|
||||
SergeantAtArms =6
|
||||
}
|
||||
@@ -2,17 +2,12 @@
|
||||
|
||||
public class PartialTeam : Team
|
||||
{
|
||||
public IList<Student> OmittedStudents { get; }
|
||||
public IList<Student> OmittedStudents { get; set; }
|
||||
|
||||
public PartialTeam(string name, CompetitiveEvent @event, IList<Student> students, IList<Student> omittedStudents) : base(name, @event, students)
|
||||
{
|
||||
OmittedStudents = omittedStudents;
|
||||
}
|
||||
|
||||
public override Team CloneWithOmittedStudents(IEnumerable<Student> studentsToOmit)
|
||||
public override Team CloneWithOmittedStudents(IEnumerable<Student> studentsToOmit)
|
||||
{
|
||||
var remainingStudents = Students.Where(s => !studentsToOmit.Contains(s)).ToList();
|
||||
var omittedStudents = OmittedStudents.Union(Students.Where(studentsToOmit.Contains)).Distinct().ToList();
|
||||
return new PartialTeam(Name, Event, remainingStudents, omittedStudents );
|
||||
return new PartialTeam{TeamId = Name, Event = Event, Students = remainingStudents, OmittedStudents = omittedStudents };
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace Core.Entities;
|
||||
|
||||
public enum Assumption
|
||||
public enum Requirement
|
||||
{
|
||||
Include,
|
||||
Exclude
|
||||
+62
-59
@@ -1,74 +1,77 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using static System.Text.RegularExpressions.Regex;
|
||||
|
||||
namespace Core.Entities;
|
||||
|
||||
public class Student
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Id { get; set; }
|
||||
|
||||
public string LastNameFirstName
|
||||
[Required]
|
||||
[StringLength(50,MinimumLength = 2)]
|
||||
[Display(Name = "First Name")]
|
||||
public string FirstName { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(50, MinimumLength = 2)]
|
||||
[Display(Name = "Last Name")]
|
||||
public string LastName { get; set; }
|
||||
|
||||
[Range(5,12)]
|
||||
[Display(Name = "Grade")]
|
||||
public int Grade { get; set; }
|
||||
|
||||
[EmailAddress]
|
||||
[Display(Name = "Email Address")]
|
||||
public string? Email { get; set; }
|
||||
|
||||
[Phone]
|
||||
[Display(Name = "Phone Number")]
|
||||
public string? PhoneNumber { get; set; }
|
||||
|
||||
[Display(Name = "TSA Year")]
|
||||
public int TsaYear { get; set; }
|
||||
|
||||
[Display(Name = "State Id")]
|
||||
public string? StateId { get; set; }
|
||||
|
||||
[Display(Name = "Regional Id")]
|
||||
public string? RegionalId { get; set; }
|
||||
|
||||
[Display(Name = "National Id")]
|
||||
public string? NationalId { get; set; }
|
||||
|
||||
[Display(Name = "Officer Role")]
|
||||
public OfficerRole? OfficerRole { get; set; }
|
||||
|
||||
public List<Team> Teams { get; set; } = null;
|
||||
public List<EventDefinition> RankedEvents { get; } = [];
|
||||
public List<StudentEventRanking> EventRankings { get; } = [];
|
||||
|
||||
|
||||
public string Name => FirstNameLastName;
|
||||
|
||||
public string LastNameFirstName => $"{LastName}, {FirstName}";
|
||||
|
||||
public string FirstNameLastName => $"{FirstName} {LastName}";
|
||||
|
||||
public static Tuple<string, string> ParseNameParts(string fullName)
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Name.Contains(',')) return Name;
|
||||
var match = Regex.Match(Name, @"(.*)\s(.*)");
|
||||
if (match.Success)
|
||||
return $"{match.Groups[2].Value}, {match.Groups[2].Value} ";
|
||||
return Name;
|
||||
}
|
||||
var match = Match(fullName, @"(.*),\s*(.*)");
|
||||
if (match.Success)
|
||||
return Tuple.Create(match.Groups[2].Value, match.Groups[1].Value);
|
||||
match = Match(fullName, @"(.*)\s*(.*)");
|
||||
return
|
||||
match.Success
|
||||
? Tuple.Create(match.Groups[1].Value, match.Groups[2].Value)
|
||||
: new Tuple<string, string>(fullName, string.Empty);
|
||||
}
|
||||
|
||||
|
||||
public string FirstNameLastName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Name.Contains(',')) return Name;
|
||||
var match = Regex.Match(Name, @"(.*),\s*(.*)");
|
||||
if (match.Success)
|
||||
return $"{match.Groups[2].Value} {match.Groups[1].Value}";
|
||||
return Name;
|
||||
}
|
||||
}
|
||||
|
||||
public string FirstName
|
||||
{
|
||||
get
|
||||
{
|
||||
var match = Regex.Match(LastNameFirstName, @"(.*),\s*(.*)");
|
||||
if (match.Success)
|
||||
return $"{match.Groups[2].Value}";
|
||||
return Name;
|
||||
}
|
||||
}
|
||||
|
||||
public int Grade { get; }
|
||||
public string StateID { get; }
|
||||
public string RegionalID { get; }
|
||||
public string NationalID { get; }
|
||||
public int TsaYear { get; }
|
||||
public string Officer { get; }
|
||||
public IList<CompetitiveEvent> RankedEventPicks { get; }
|
||||
|
||||
public ICollection<Team> Teams { get; set; }
|
||||
|
||||
public Student(string name, int grade, int tsaYear, string officer, IList<CompetitiveEvent> rankedEventPicks,
|
||||
string stateID, string regionalID, string nationalId)
|
||||
{
|
||||
Name = name;
|
||||
Grade = grade;
|
||||
TsaYear = tsaYear;
|
||||
Officer = officer;
|
||||
RankedEventPicks = rankedEventPicks;
|
||||
StateID=stateID;
|
||||
RegionalID = regionalID;
|
||||
NationalID = nationalId;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return FirstName;
|
||||
}
|
||||
|
||||
public bool VotingDelegate => Officer.Contains("Pres");
|
||||
public bool VotingDelegate => OfficerRole is Entities.OfficerRole.President or Entities.OfficerRole.VicePresident;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace Core.Entities;
|
||||
|
||||
public class StudentEventRanking
|
||||
{
|
||||
public Student Student { get; set; } = null!;
|
||||
|
||||
public EventDefinition EventDefinition { get; set; } = null!;
|
||||
public int Rank { get; set; }
|
||||
|
||||
public const int MaxRank = 6;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
namespace Core.Entities;
|
||||
|
||||
public class StudentEventStatistics
|
||||
{
|
||||
public Student Student { get; set; }
|
||||
public List<EventDefinition> Events { get; set; } = [];
|
||||
|
||||
public int? TotalLevelOfEffort => Events.Sum(e => e.LevelOfEffort);
|
||||
|
||||
public int EventCount => Events.Count;
|
||||
|
||||
public bool HasRegionalEvent => Events.Any(e => e.RegionalEvent);
|
||||
|
||||
public bool HasOnSiteActivity => Events.Any(e => e.OnSiteActivity);
|
||||
|
||||
public static List<StudentEventStatistics> Generate(ICollection<Team> teams)
|
||||
{
|
||||
Dictionary<Student, StudentEventStatistics> statistics = [];
|
||||
|
||||
foreach (var team in teams)
|
||||
{
|
||||
foreach (var student in team.Students)
|
||||
{
|
||||
if (!statistics.ContainsKey(student))
|
||||
statistics.Add(student, new StudentEventStatistics(){Student = student});
|
||||
statistics[student].Events.Add(team.Event);
|
||||
}
|
||||
}
|
||||
|
||||
return statistics.Values.ToList();
|
||||
}
|
||||
}
|
||||
+35
-41
@@ -1,40 +1,44 @@
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Core.Entities;
|
||||
|
||||
public class Team
|
||||
{
|
||||
public string Name { get; }
|
||||
public CompetitiveEvent Event { get; }
|
||||
public IList<Student> Students { get; }
|
||||
public int Id { get; set; }
|
||||
|
||||
public Student? Captain { get; set; }
|
||||
[Required]
|
||||
[Display(Name = "Team Name")]
|
||||
public string Name { get; set; }
|
||||
public EventDefinition Event { get; set; }
|
||||
public List<Student> Students { get; set; } = [];
|
||||
|
||||
public string TeamNumber { get; set; }
|
||||
public Student? Captain { get; set; }
|
||||
|
||||
public string RegionalTimeSlot { get; set; }
|
||||
[Display(Name = "Team Id")]
|
||||
public string? TeamId { get; set; }
|
||||
|
||||
public Tuple<DateTime,DateTime?>? RegionalTimeSlotObj
|
||||
{
|
||||
get
|
||||
{
|
||||
//public string? RegionalTimeSlot { get; set; }
|
||||
|
||||
|
||||
// public Tuple<DateTime,DateTime?>? RegionalTimeSlotObj
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
|
||||
if (string.IsNullOrEmpty(RegionalTimeSlot))
|
||||
return null;
|
||||
var times = Regex.Matches(RegionalTimeSlot, @"(.*)\s*-\s*(.*)");
|
||||
if (times.Count == 0)
|
||||
return Tuple.Create(P(RegionalTimeSlot), (DateTime?)null);
|
||||
var match = times[0];
|
||||
if (!match.Success)
|
||||
return Tuple.Create(P(RegionalTimeSlot), (DateTime?)null);
|
||||
// if (string.IsNullOrEmpty(RegionalTimeSlot))
|
||||
// return null;
|
||||
// var times = Regex.Matches(RegionalTimeSlot, @"(.*)\s*-\s*(.*)");
|
||||
// if (times.Count == 0)
|
||||
// return Tuple.Create(P(RegionalTimeSlot), (DateTime?)null);
|
||||
// var match = times[0];
|
||||
// if (!match.Success)
|
||||
// return Tuple.Create(P(RegionalTimeSlot), (DateTime?)null);
|
||||
|
||||
return Tuple.Create(P(match.Groups[1].Value), (DateTime?)P(match.Groups[2].Value));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// return Tuple.Create(P(match.Groups[1].Value), (DateTime?)P(match.Groups[2].Value));
|
||||
// return null;
|
||||
// }
|
||||
//}
|
||||
|
||||
private DateTime P(string s)
|
||||
private DateTime P(string s)
|
||||
{
|
||||
var dt = DateTime.Parse(s);
|
||||
if (dt.TimeOfDay < TimeSpan.FromHours(7))
|
||||
@@ -42,28 +46,18 @@ public class Team
|
||||
return dt;
|
||||
}
|
||||
|
||||
public Team(string name, CompetitiveEvent @event, IList<Student> students, Student? captain = null, string teamNumber = null, string regionalTimeSlot = null)
|
||||
{
|
||||
Name = name;
|
||||
Event = @event;
|
||||
Students = students;
|
||||
Captain = captain;
|
||||
TeamNumber = teamNumber;
|
||||
RegionalTimeSlot = regionalTimeSlot;
|
||||
}
|
||||
|
||||
public virtual Team CloneWithOmittedStudents(IEnumerable<Student> studentsToOmit)
|
||||
{
|
||||
var studentsToOmitList = studentsToOmit.ToList();
|
||||
var omittedStudents = Students.Where(studentsToOmitList.Contains).ToList();
|
||||
if (!omittedStudents.Any())
|
||||
return new Team(Name, Event, Students.ToList(), Captain);
|
||||
return new Team{Captain = Captain, Event = Event, Students = Students.ToList(), TeamId = Name};
|
||||
|
||||
var remainingStudents = Students.Where(s => !studentsToOmitList.Contains(s)).ToList();
|
||||
return new PartialTeam(Name, Event, remainingStudents, omittedStudents);
|
||||
return new PartialTeam { Name = Name, Event = Event, Students = remainingStudents, OmittedStudents = omittedStudents};
|
||||
}
|
||||
|
||||
public Team Clone() => CloneWithOmittedStudents(Array.Empty<Student>());
|
||||
public Team Clone() => CloneWithOmittedStudents([]);
|
||||
|
||||
public static int GetStudentTeamOverlapCount(IList<Team>[] timeSlots)
|
||||
{
|
||||
@@ -75,7 +69,7 @@ public class Team
|
||||
return GetStudentTeamOverlaps(timeSlot).Count();
|
||||
}
|
||||
|
||||
public static IEnumerable<Tuple<Student, IEnumerable<Team>>> GetStudentTeamOverlaps(IList<Team> timeSlot)
|
||||
public static IEnumerable<Tuple<Student, IEnumerable<Team>>> GetStudentTeamOverlaps(IList<Team> timeSlot)
|
||||
{
|
||||
return
|
||||
from s in timeSlot.SelectMany(ts => ts.Students).Distinct()
|
||||
@@ -92,7 +86,7 @@ public class Team
|
||||
|
||||
public string ToStringWithIndividualAndRegional()
|
||||
{
|
||||
var ind = Event.Format is EventFormat.Individual ? " (Ind.)" : string.Empty;
|
||||
var ind = Event.EventFormat is EventFormat.Individual ? " (Ind.)" : string.Empty;
|
||||
var regional= Event.RegionalEvent ? " (Reg.)" : string.Empty;
|
||||
//var regional= Event.RegionalEvent ? " (Reg.)" : string.Empty;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user