Exemple #1
0
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for
        // more details see https://aka.ms/RazorPagesCRUD.
        public async Task <IActionResult> OnPostAsync()
        {
            if (await QuizBookList.ListNameAlreadyExistsStaticAsync(_context, Name))
            {
                ModelState.AddModelError("Name", "Sorry, this Name is already in use.");
            }
            if (!ModelState.IsValid)
            {
                ViewData["BookSelectList"] = await BibleBook.GetBookSelectListAsync(_context, BibleId);

                return(Page());
            }

            // confirm our user is a valid PBE User.
            IdentityUser user = await _userManager.GetUserAsync(User);

            PBEUser = await QuizUser.GetOrAddPBEUserAsync(_context, user.Email);

            if (!PBEUser.IsQuizModerator())
            {
                return(RedirectToPage("/error", new { errorMessage = "Sorry! You do not have sufficient rights to add a PBE BookList" }));
            }

            // Now let's create an empty BookList
            var emptyBookList = new QuizBookList
            {
                Created  = DateTime.Now,
                Modified = DateTime.Now
            };

            emptyBookList.BookListName = Name;
            emptyBookList.IsDeleted    = false;
            _context.QuizBookLists.Add(emptyBookList);

            // now we need to add the Books
            foreach (int BookNum in Books)
            {
                if (BookNum > 0)
                {
                    QuizBookListBookMap BookMap = new QuizBookListBookMap();
                    BookMap.BookList   = emptyBookList;
                    BookMap.BookNumber = BookNum;
                    BookMap.IsDeleted  = false;
                    BookMap.Created    = DateTime.Now;
                    BookMap.Modified   = DateTime.Now;
                    _context.QuizBookListBookMaps.Add(BookMap);
                    await _context.SaveChangesAsync();
                }
            }
            await _context.SaveChangesAsync();

            return(RedirectToPage("BookLists", new { BibleId = this.BibleId, Message = String.Format("Book List {0} successfully created...", emptyBookList.BookListName) }));
        }
Exemple #2
0
        public async Task <IActionResult> OnPostAsync(int?id)
        {
            if (id == null)
            {
                return(NotFound());
            }

            try
            {
                BookList = await _context.QuizBookLists.Include(B => B.QuizBookListBookMaps).Where(B => B.Id == id).SingleAsync();
            }
            catch {
                return(RedirectToPage("/error", new
                {
                    errorMessage = "That's Odd! We were unable to retrieve this BookList... Maybe try that again"
                }));
            }

            // confirm Path Owner
            IdentityUser user = await _userManager.GetUserAsync(User);

            PBEUser = await QuizUser.GetOrAddPBEUserAsync(_context, user.Email);

            if (!PBEUser.IsQuizModerator())
            {
                return(RedirectToPage("/error", new { errorMessage = "Sorry! You do not have sufficient rights to delete a PBE BookList" }));
            }

            // We only ever soft delete a BookList but we do delete the maps.

            // First we need to iterate through each BookList Map and delete them, these are a leaf node so this should be OK.
            foreach (QuizBookListBookMap book in BookList.QuizBookListBookMaps)
            {
                _context.QuizBookListBookMaps.Remove(book);
            }
            await _context.SaveChangesAsync();

            // Let's track this event
            // _ = await Path.RegisterEventAsync(_context, EventType.PathDeleted, Path.Id.ToString());

            // Then we set the BookList to isDeleted
            if (BookList != null)
            {
                _context.Attach(BookList).State = EntityState.Modified;
                BookList.Modified  = DateTime.Now;
                BookList.IsDeleted = true;
                await _context.SaveChangesAsync();
            }
            return(RedirectToPage("./BookLists"));
        }
        public async Task <IActionResult> OnPostAsync(int?id)
        {
            if (id == null)
            {
                return(NotFound());
            }

            try
            {
                Template = await _context.PredefinedQuizzes.Include(T => T.PredefinedQuizQuestions).Where(T => T.Id == id).SingleAsync();
            }
            catch {
                return(RedirectToPage("/error", new
                {
                    errorMessage = "That's Odd! We were unable to retrieve this Template... Maybe try that again?"
                }));
            }

            // confirm Template Owner
            IdentityUser user = await _userManager.GetUserAsync(User);

            PBEUser = await QuizUser.GetOrAddPBEUserAsync(_context, user.Email);

            if (Template.QuizUser != PBEUser)
            {
                return(RedirectToPage("/error", new { errorMessage = "Sorry! Only a Template Owner may delete a Template" }));
            }

            // First we need to iterate through each Step and delete them one by one, steps are a leaf node so this should be OK.
            foreach (PredefinedQuizQuestion Question in Template.PredefinedQuizQuestions)
            {
                _context.PredefinedQuizQuestions.Remove(Question);
            }
            await _context.SaveChangesAsync();

            // Let's track this event
            // _ = await Path.RegisterEventAsync(_context, EventType.PathDeleted, Path.Id.ToString());

            // Then we set the Template to isDeleted.
            if (Template != null)
            {
                _context.Attach(Template).State = EntityState.Modified;
                Template.Modified  = DateTime.Now;
                Template.IsDeleted = true;
                await _context.SaveChangesAsync();
            }
            return(RedirectToPage("./Templates"));
        }
Exemple #4
0
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for
        // more details see https://aka.ms/RazorPagesCRUD.
        public async Task <IActionResult> OnPostAsync(int Id)
        {
            // confirm our user is a valid PBE User.
            IdentityUser user = await _userManager.GetUserAsync(User);

            PBEUser = await QuizUser.GetOrAddPBEUserAsync(_context, user.Email); // Static method not requiring an instance

            if (!PBEUser.IsQuizModerator())
            {
                return(RedirectToPage("/error", new { errorMessage = "Sorry! You do not have sufficient rights to manage a PBE User" }));
            }

            QuizUser UserToUpdate = await _context.QuizUsers.FindAsync(Id);

            if (UserToUpdate == null)
            {
                return(RedirectToPage("/error", new { errorMessage = "That's Odd! We weren't able to find this User" }));
            }

            if (!ModelState.IsValid)
            {
                return(Page());
            }

            if (await TryUpdateModelAsync <QuizUser>(
                    UserToUpdate,
                    "EditUser",
                    U => U.IsModerator, U => U.IsQuestionBuilderLocked, U => U.IsQuizTakerLocked))
            {
                await _context.SaveChangesAsync();

                return(RedirectToPage("./PBEUsers", new { Message = String.Format("PBE User:  {0} successfully updated...", UserToUpdate.Email) }));
            }
            return(RedirectToPage("./PBEUsers"));
        }
        public async Task <IActionResult> OnPostAsync(int?id)
        {
            if (id == null)
            {
                return(NotFound());
            }

            try
            {
                Path = await _context.Paths.Include(P => P.PathNodes).Where(P => P.Id == id).SingleAsync();
            }
            catch {
                return(RedirectToPage("/error", new
                {
                    errorMessage = "That's Odd! We were unable to retrieve this path... Not sure what to tell you!"
                }));
            }

            // confirm Path Owner
            IdentityUser user = await _userManager.GetUserAsync(User);

            if (!Path.IsPathOwner(user.Email))
            {
                return(RedirectToPage("/error", new { errorMessage = "Sorry! Only a Path Owner may delete a Path" }));
            }

            // First we need to iterate through each Step and delete them one by one, steps are a leaf node so this should be OK.
            foreach (PathNode step in Path.PathNodes)
            {
                _context.PathNodes.Remove(step);
            }
            await _context.SaveChangesAsync();

            // Let's track this event
            _ = await Path.RegisterEventAsync(_context, EventType.PathDeleted, Path.Id.ToString());

            // Then we set the Path to isDeleted, we also unPublish it in case a filter is incorrectly not checking for deleted.
            if (Path != null)
            {
                _context.Attach(Path).State = EntityState.Modified;
                Path.Modified    = DateTime.Now;
                Path.IsPublished = false;
                Path.IsDeleted   = true;
                await _context.SaveChangesAsync();
            }
            return(RedirectToPage("./MyPaths"));
        }
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for
        // more details see https://aka.ms/RazorPagesCRUD.
        public async Task <IActionResult> OnPostAsync()
        {
            IdentityUser user = await _userManager.GetUserAsync(User);

            if (!ModelState.IsValid)
            {
                return(RedirectToPage("Group", new { Id = Group.Id }));
            }

            GameGroup UpdateGroup = await _context.GameGroups.FindAsync(Group.Id);

            if (UpdateGroup == null)
            {
                return(RedirectToPage("/error", new { errorMessage = "That's Odd! We weren't able to find that Group" }));
            }
            if (UpdateGroup.Owner != user.Email)
            {
                return(RedirectToPage("/error", new { errorMessage = "Sorry, Only the owner can manage a Group" }));
            }
            _context.Entry(UpdateGroup)
            .Collection(g => g.GameTeams)
            .Load();

            if (await TryUpdateModelAsync <GameGroup>(
                    UpdateGroup,
                    "Group", // Prefix for form value.
                    t => t.PathId))
            {
                UpdateGroup.GroupState = (int)GameGroup.GameGroupState.InPlay;
                UpdateGroup.Modified   = DateTime.Now;

                // go get the Path so we can set first step
                Path path = await _context.Paths.FindAsync(UpdateGroup.PathId);

                if (path == null)
                {
                    return(RedirectToPage("/error", new { errorMessage = "That's Very Odd! We were not able to find the Path for this Group" }));
                }

                // We will need that first step.
                _ = await path.AddCalculatedPropertiesAsync(_context);

                // Now we need to iterate through each Team and reset it.

                foreach (GameTeam Team in UpdateGroup.GameTeams)
                {
                    Team.CurrentStepId = path.FirstStepId;
                    Team.TeamType      = 0;
                    Team.BoardState    = (int)GameTeam.GameBoardState.WordSelect;
                    Team.StepNumber    = 1;
                    Team.Modified      = DateTime.Now;
                }
                await _context.SaveChangesAsync();

                return(RedirectToPage("Group", new { Id = UpdateGroup.Id, Message = String.Format("Group {0} has been Restarted!", UpdateGroup.Name) }));
            }
            return(Page());
        }
        public async Task <IActionResult> OnPostAsync(int?id, string ReturnPath)
        {
            if (id == null)
            {
                return(NotFound());
            }

            Question = await _context.QuizQuestions.FindAsync((int)id.Value);

            if (Question == null)
            {
                return(RedirectToPage("/error", new
                {
                    errorMessage = "That's Odd! We were unable to retrieve this Question... Maybe try that again?"
                }));
            }

            // confirm our user is a valid PBE User.
            IdentityUser user = await _userManager.GetUserAsync(User);

            PBEUser = await QuizUser.GetOrAddPBEUserAsync(_context, user.Email);

            if (!PBEUser.IsValidPBEQuestionBuilder())
            {
                return(RedirectToPage("/error", new { errorMessage = "Sorry! You do not have sufficient rights to edit a PBE question" }));
            }

            // Questions and Answers are not actually deleted, because they are used to calculate Stats so we just set to IsDeleted = true.
            if (Question != null)
            {
                _context.Attach(Question).State = EntityState.Modified;
                Question.Modified  = DateTime.Now;
                Question.IsDeleted = true;
                await _context.SaveChangesAsync();
            }
            switch (ReturnPath)
            {
            case "Questions":
                return(RedirectToPage("./Questions", new { BibleId = Question.BibleId, BookNumber = Question.BookNumber, Chapter = Question.Chapter }));

            // break; not needed unreachable

            case "ChallengedQuestions":
                return(RedirectToPage("ChallengedQuestions", new { BibleId = Question.BibleId }));

            // break; not needed unreachable

            default:
                return(RedirectToPage("./Questions", new { BibleId = Question.BibleId, BookNumber = Question.BookNumber, Chapter = Question.Chapter }));
                // break; not needed unreachable
            }
        }
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for
        // more details see https://aka.ms/RazorPagesCRUD.
        public async Task <IActionResult> OnPostAsync()
        {
            if (Quiz.BookNumber == 0 && Quiz.PredefinedQuiz == 0)
            {
                ModelState.AddModelError("Quiz.BookNumber", "You must select either a Book/BookList or a Template.");
                ModelState.AddModelError("Quiz.PredefinedQuiz", "You must select either a Book/BookList or a Template.");
            }
            if (!ModelState.IsValid)
            {
                //Initialize Select Lists
                ViewData["BookSelectList"] = await BibleBook.GetBookAndBookListSelectListAsync(_context, BibleId);

                ViewData["TemplateSelectList"] = await PredefinedQuiz.GetTemplateSelectListAsync(_context, PBEUser);

                return(Page());
            }

            // confirm our user is a valid PBE User.
            IdentityUser user = await _userManager.GetUserAsync(User);

            PBEUser = await QuizUser.GetOrAddPBEUserAsync(_context, user.Email);

            if (!PBEUser.IsValidPBEQuizHost())
            {
                return(RedirectToPage("/error", new { errorMessage = "Sorry! You do not have sufficient rights to add a PBE Quiz" }));
            }

            // Now let's create an empty Quiz
            var emptyQuiz = new QuizGroupStat
            {
                Created   = DateTime.Now,
                Modified  = DateTime.Now,
                QuizUser  = PBEUser,
                IsDeleted = false
            };

            if (await TryUpdateModelAsync <QuizGroupStat>(
                    emptyQuiz,
                    "Quiz", // Prefix for form value.
                    q => q.GroupName, q => q.BookNumber, q => q.PredefinedQuiz))
            {
                if (emptyQuiz.PredefinedQuiz > 0)
                {
                    // Template trumps Book/BookList so we set BookNumber 0
                    emptyQuiz.BookNumber = 0;
                }
                _context.QuizGroupStats.Add(emptyQuiz);
                await _context.SaveChangesAsync();
            }

            return(RedirectToPage("./Quizzes", new { BibleId = this.BibleId, Message = String.Format("Quiz {0} successfully created...", emptyQuiz.GroupName) }));
        }
Exemple #9
0
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for
        // more details see https://aka.ms/RazorPagesCRUD.
        public async Task <IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                ViewData["BookSelectList"] = await BibleBook.GetBookAndBookListSelectListAsync(_context, BibleId);

                return(Page());
            }

            // confirm our user is a valid PBE User.
            IdentityUser user = await _userManager.GetUserAsync(User);

            PBEUser = await QuizUser.GetOrAddPBEUserAsync(_context, user.Email);

            if (!PBEUser.IsValidPBEQuestionBuilder())
            {
                return(RedirectToPage("/error", new { errorMessage = "Sorry! You do not have sufficient rights to add a PBE Quiz Template" }));
            }

            // Now let's create an empty template
            var emptyTemplate = new PredefinedQuiz
            {
                Created  = DateTime.Now,
                Modified = DateTime.Now,
                QuizUser = PBEUser
            };

            if (await TryUpdateModelAsync <PredefinedQuiz>(
                    emptyTemplate,
                    "Template", // Prefix for form value.
                    t => t.QuizName, t => t.BookNumber, t => t.NumQuestions))
            {
                emptyTemplate.QuizName  = Name; // Name is handled seperately for remote validation to work.
                emptyTemplate.IsDeleted = false;
                _context.PredefinedQuizzes.Add(emptyTemplate);
                await _context.SaveChangesAsync();

                return(RedirectToPage("./ConfigureTemplate", new { Id = emptyTemplate.Id, BibleId = this.BibleId }));
            }

            return(RedirectToPage("./Templates", new { Message = String.Format("Quiz Template {0} successfully created...", emptyTemplate.QuizName) }));
        }
Exemple #10
0
        public async Task <IActionResult> OnPostAsync(int?id)
        {
            if (id == null)
            {
                return(NotFound());
            }

            try
            {
                Quiz = await _context.QuizGroupStats.Where(Q => Q.Id == id).SingleAsync();
            }
            catch {
                return(RedirectToPage("/error", new
                {
                    errorMessage = "That's Odd! We were unable to retrieve this Quiz... Maybe try that again?"
                }));
            }

            // confirm Quiz Owner
            IdentityUser user = await _userManager.GetUserAsync(User);

            PBEUser = await QuizUser.GetOrAddPBEUserAsync(_context, user.Email);

            if (Quiz.QuizUser != PBEUser)
            {
                return(RedirectToPage("/error", new { errorMessage = "Sorry! Only a Quiz Owner may delete a Quiz" }));
            }

            // Let's track this event
            // _ = await Path.RegisterEventAsync(_context, EventType.PathDeleted, Path.Id.ToString());

            // Then we set the Quiz to isDeleted, we want to keep these around for refrence to QuizQuestion Stats.
            if (Quiz != null)
            {
                _context.Attach(Quiz).State = EntityState.Modified;
                Quiz.Modified  = DateTime.Now;
                Quiz.IsDeleted = true;
                await _context.SaveChangesAsync();
            }
            return(RedirectToPage("./Quizzes"));
        }
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for
        // more details see https://aka.ms/RazorPagesCRUD.
        public async Task <IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return(RedirectToPage("Guide", new
                {
                    GroupId = Team.GroupId,
                    TeamId = Team.Id
                }));
            }

            // Now let's go grab our Team
            GameTeam UpdateTeam = await _context.GameTeams.FindAsync(Team.Id);

            if (UpdateTeam == null)
            {
                return(RedirectToPage("/error", new { errorMessage = "That's Odd! We were not able to find that Team" }));
            }

            if (await TryUpdateModelAsync <GameTeam>(
                    UpdateTeam,
                    "Team", // Prefix for form value.
                    t => t.KeyWord, t => t.GuideWord))
            {
                UpdateTeam.BoardState = (int)GameTeam.GameBoardState.StepSelect;
                await _context.SaveChangesAsync();

                // Let's signal the StateChange to Clients using SignalR
                string GroupName = "\"" + Team.Id.ToString() + "\"";
                await _hubContext.Clients.Group(GroupName).SendAsync("StateChange");
            }

            return(RedirectToPage("Guide", new
            {
                GroupId = UpdateTeam.GroupId,
                TeamId = UpdateTeam.Id
            }));
        }
Exemple #12
0
        public async Task <IActionResult> OnPostAsync(int?id)
        {
            if (id == null)
            {
                return(NotFound());
            }

            try
            {
                Group = await _context.GameGroups.Include(G => G.GameTeams)
                        .Where(G => G.Id == id).SingleAsync();
            }
            catch {
                return(RedirectToPage("/error", new
                {
                    errorMessage = "That's Odd! We were unable to retrieve this Group... Not sure what to tell you!"
                }));
            }

            // confirm Group Owner
            IdentityUser user = await _userManager.GetUserAsync(User);

            if (Group.Owner != user.Email)
            {
                return(RedirectToPage("/error", new { errorMessage = "Sorry! Only a Group Owner may delete a Group" }));
            }

            // First we need to iterate through each Step and delete them one by one, steps are a leaf node so this should be OK.
            foreach (GameTeam team in Group.GameTeams)
            {
                _context.GameTeams.Remove(team);
            }
            _context.GameGroups.Remove(Group);
            await _context.SaveChangesAsync();

            return(RedirectToPage("./MyGroups"));
        }
        public async Task <IActionResult> OnPostAsync(int?id, int pathId)
        {
            if (id == null)
            {
                return(NotFound());
            }

            Step = await _context.PathNodes.FindAsync(id);

            Path = await _context.Paths.FindAsync(pathId);

            if (Path == null)
            {
                return(RedirectToPage("/error", new { errorMessage = "That's Odd! We weren't able to find this Path" }));
            }
            if (Step.PathId != Path.Id)
            {
                return(RedirectToPage("/error", new { errorMessage = "That's Odd! Path/Step mismatch" }));
            }

            IdentityUser user = await _userManager.GetUserAsync(User);

            if (!Path.IsPathOwner(user.Email))
            {
                return(RedirectToPage("/error", new { errorMessage = "Sorry! Only a Path Owner may delete a Step" }));
            }

            if (Step != null)
            {
                _context.PathNodes.Remove(Step);
                await _context.SaveChangesAsync();

                // Finally we need to re-position each node in the path to ensure safe ordering
                _ = await Path.RedistributeStepsAsync(_context);
            }
            return(RedirectToPage("/Paths/Steps", new { PathId = pathId }));
        }
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for
        // more details see https://aka.ms/RazorPagesCRUD.
        public async Task <IActionResult> OnPostAsync()
        {
            BibleSelectList = await GetBibleSelectListAsync();


            Path.Name = Name;

            if (await Path.PathNameAlreadyExistsStaticAsync(_context, Name))
            {
                ModelState.AddModelError("Name", "Sorry, this Name is already in use.");
            }

            if (!ModelState.IsValid)
            {
                return(Page());
            }

            var emptyPath = new Path();
            var user      = await _userManager.GetUserAsync(User);

            emptyPath.SetInitialProperties(user.Email);

            if (await TryUpdateModelAsync <Path>(
                    emptyPath,
                    "Path", // Prefix for form value.
                    p => p.IsPublicEditable, p => p.OwnerBibleId))
            {
                emptyPath.Name = Name;
                _context.Paths.Add(emptyPath);
                await _context.SaveChangesAsync();

                return(RedirectToPage("./Steps", new { PathId = emptyPath.Id }));
            }

            return(Page());
        }
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for
        // more details see https://aka.ms/RazorPagesCRUD.
        public async Task <IActionResult> OnPostAsync(string BibleId, int QuizId)
        {
            if (!ModelState.IsValid)
            {
                // Something bad has happened let's go get a new quiz question.
                UserMessage = "Something has gone wrong! We were unable to save the results for that last question";
                return(RedirectToPage("Quiz", new { BibleId, QuizId, Message = UserMessage }));
            }

            IdentityUser user = await _userManager.GetUserAsync(User);

            PBEUser = await QuizUser.GetOrAddPBEUserAsync(_context, user.Email); // Static method not requiring an instance

            if (!PBEUser.IsValidPBEQuizHost())
            {
                return(RedirectToPage("/error", new { errorMessage = "Sorry! You do not have sufficient rights to host a PBE Quiz" }));
            }
            this.BibleId = await Bible.GetValidPBEBibleIdAsync(_context, BibleId);

            // Let's grab the Quiz Object in order to update it.
            Quiz = await _context.QuizGroupStats.FindAsync(QuizId);

            if (Quiz == null)
            {
                return(RedirectToPage("/error", new { errorMessage = "That's Odd... We were unable to find this Quiz" }));
            }
            if (Quiz.QuizUser != PBEUser)
            {
                return(RedirectToPage("/error", new { errorMessage = "Sorry! Only a Quiz Owner can award points during a Quiz" }));
            }

            // We need to upate the Question object as well so let's go grab it.
            QuizQuestion QuestionToUpdate = await _context.QuizQuestions.FindAsync(Question.Id);

            if (QuestionToUpdate == null)
            {
                return(RedirectToPage("/error", new { errorMessage = "That's Odd... We were unable to find this Question so we can't update it" }));
            }

            // Now we award the points... let's get this right:
            // Let's prevent posting an anomalous number of points.
            int QuestionPointsPossible = QuestionToUpdate.Points;

            if (Question.PointsAwarded > QuestionPointsPossible)
            {
                Question.PointsAwarded = QuestionPointsPossible;
            }
            if (Question.PointsAwarded < 0)
            {
                Question.PointsAwarded = 0;
            }

            // Update the Quiz Object:
            _context.Attach(Quiz);
            Quiz.PointsPossible += QuestionPointsPossible;
            Quiz.PointsAwarded  += Question.PointsAwarded;
            Quiz.QuestionsAsked += 1;
            Quiz.Modified        = DateTime.Now;

            // Update the Question Object
            _context.Attach(QuestionToUpdate);
            QuestionToUpdate.LastAsked = DateTime.Now;

            // We've had some challenges with users challenging many questions often with no comment.
            // We will do a user check and make sure our user isn't blocked, if they are we silently fail the challenge.
            // TODO: We should revisit the silent fail if it becomes a problem.
            if (Question.Challenged && !PBEUser.IsQuestionBuilderLocked)
            {
                QuestionToUpdate.Challenged       = true;
                QuestionToUpdate.ChallengeComment = Question.ChallengeComment;
                QuestionToUpdate.ChallengedBy     = PBEUser.Email;
            }

            // Save both of these changes.
            await _context.SaveChangesAsync();

            // And next let's make sure we log this event.
            // BUG: Note we've had a pretty significant data bug prior to 6/8/2019 where we were setting Points to the cumulative quizGroupStat.PointsAwarded vs. the non-cumulative PointsAwardedByJudge... so all data prior to this date is wrong.
            await QuestionToUpdate.RegisterEventAsync(_context, QuestionEventType.QuestionPointsAwarded, PBEUser.Id, null, Quiz.Id, Question.PointsAwarded);

            return(RedirectToPage("Quiz", new { BibleId, QuizId }));
        }
Exemple #16
0
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for
        // more details see https://aka.ms/RazorPagesCRUD.
        public async Task <IActionResult> OnPostAsync(int Id)
        {
            if (!ModelState.IsValid)
            {
                // Populate Step for display
                _ = await Step.AddBookNameAsync(_context, BibleId);

                Step.Verses = await Step.GetBibleVersesAsync(_context, BibleId, false, false);

                // and now we need a Verse Select List
                ViewData["VerseSelectList"] = new SelectList(Step.Verses, "Verse", "Verse");
                return(Page());
            }
            // Now let's validate a few things, first lets go grab the Step and Path
            PathNode StepToUpdate = await _context.PathNodes.FindAsync(Id);

            Path = await _context.Paths.FindAsync(Step.PathId);

            if (Path == null)
            {
                return(RedirectToPage("/error", new { errorMessage = "That's Odd! We weren't able to find this Path" }));
            }
            if (StepToUpdate == null)
            {
                return(RedirectToPage("/error", new { errorMessage = "That's Odd! We weren't able to find this Step" }));
            }
            if (StepToUpdate.PathId != Path.Id)
            {
                return(RedirectToPage("/error", new { errorMessage = "That's Odd! Path/Step mismatch" }));
            }

            BibleId = await Path.GetValidBibleIdAsync(_context, BibleId);

            // confirm our owner is a valid path editor i.e. owner or the path is publicly editable
            IdentityUser user = await _userManager.GetUserAsync(User);

            if (!Path.IsValidPathEditor(user.Email))
            {
                return(RedirectToPage("/error", new { errorMessage = "Sorry! You do not have sufficient rights to add to this Path" }));
            }

            if (!Path.IsPathOwner(user.Email))
            {
                _ = await Path.RegisterEventAsync(_context, EventType.NonOwnerEdit, user.Email);
            }

            if (await TryUpdateModelAsync <PathNode>(
                    StepToUpdate,
                    "Step",           // Prefix for form value.
                    S => S.StartVerse, S => S.EndVerse, S => S.BookNumber, S => S.Chapter))
            {
                StepToUpdate.Modified = DateTime.Now;
                await _context.SaveChangesAsync();

                // Now we need to update the Path Object with some calculated properties
                if (!Path.IsPathOwner(user.Email))
                {
                    _ = await Path.RegisterEventAsync(_context, EventType.NonOwnerEdit, user.Email);
                }

                // Prepare to update some properties on Path
                _context.Attach(Path);
                Path.Modified = DateTime.Now;
                // Save our now updated Path Object.
                await _context.SaveChangesAsync();
            }

            return(RedirectToPage("/Paths/Steps", new { PathId = Path.Id }));
        }
        public async Task <IActionResult> OnGetAsync(int GroupId, int TeamId, int StepId)
        {
            Group = await _context.GameGroups.FindAsync(GroupId);

            if (Group == null)
            {
                return(RedirectToPage("/error", new { errorMessage = "That's Odd! We weren't able to find that Group" }));
            }
            Team = await _context.GameTeams.FindAsync(TeamId);

            if (Team == null)
            {
                return(RedirectToPage("/error", new { errorMessage = "That's Odd! We were not able to find that Team" }));
            }
            if (Team.GroupId != Group.Id)
            {
                return(RedirectToPage("/error", new { errorMessage = "That's Odd! The Team and Group do not match" }));
            }
            string BibleId = await GameTeam.GetValidBibleIdAsync(_context, null);

            // Now let's check that StepId
            if (StepId == Team.CurrentStepId)
            {
                PathNode CurrentStep = await _context.PathNodes.FindAsync(Team.CurrentStepId);

                if (CurrentStep == null)
                {
                    return(RedirectToPage("/error", new { errorMessage = "That's Very Odd! We couldn't find Current Step" }));
                }
                _ = await CurrentStep.AddGenericStepPropertiesAsync(_context, BibleId);

                _ = await CurrentStep.AddPathStepPropertiesAsync(_context);

                // We have a winner! Let's update the Team Object
                _context.Attach(Team);
                Team.Modified = DateTime.Now;
                if (CurrentStep.FWStepId > 0)
                {
                    Team.CurrentStepId = CurrentStep.FWStepId;
                    Team.StepNumber    = Team.StepNumber + 1;
                    Team.BoardState    = (int)GameTeam.GameBoardState.WordSelect;
                }
                else
                {
                    Team.BoardState = (int)GameTeam.GameBoardState.Completed;
                }
                await _context.SaveChangesAsync();

                // We need to add the Quotes around the TeamID, then signal the StateChange
                string GroupName = "\"" + Team.Id.ToString() + "\"";
                await _hubContext.Clients.Group(GroupName).SendAsync("StateChange");

                return(RedirectToPage("Team", new { GroupId = Team.GroupId, TeamId = Team.Id, Message = "Good Job! You're on the right Path" }));
            }
            else
            {
                _context.Attach(Team);
                Team.Modified   = DateTime.Now;
                Team.BoardState = (int)GameTeam.GameBoardState.WordSelectOffPath;
                await _context.SaveChangesAsync();

                // We need to add the Quotes around the TeamID, then signal the StateChange
                string GroupName = "\"" + Team.Id.ToString() + "\"";
                await _hubContext.Clients.Group(GroupName).SendAsync("StateChange");

                return(RedirectToPage("Team", new { GroupId = Team.GroupId, TeamId = Team.Id, Message = "Uh Oh! You've drifted off Path" }));
            }
        }
Exemple #18
0
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for
        // more details see https://aka.ms/RazorPagesCRUD.
        public async Task <IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                // Setup our PBEBible Object
                Question.BibleId = await QuizQuestion.GetValidBibleIdAsync(_context, Question.BibleId);

                BibleBook PBEBook = await BibleBook.GetPBEBookAndChapterAsync(_context, Question.BibleId, Question.BookNumber, Question.Chapter);

                if (PBEBook == null)
                {
                    return(RedirectToPage("/error", new { errorMessage = "That's Odd! We weren't able to find the PBE Book." }));
                }

                Question.PopulatePBEQuestionInfo(PBEBook);
                Question.Verses = await Question.GetBibleVersesAsync(_context, false);

                // We should still have AnswerText


                IsCommentary = (Question.Chapter == Bible.CommentaryChapter);
                if (IsCommentary == false)
                {
                    ChapterQuestionCount = PBEBook.BibleChapters.Where(c => c.ChapterNumber == Question.Chapter).First().QuestionCount;
                }
                CommentaryQuestionCount = PBEBook.CommentaryQuestionCount;

                // and now we need a Verse and Points Select List
                ViewData["VerseSelectList"]  = new SelectList(Question.Verses, "Verse", "Verse");
                ViewData["PointsSelectList"] = Question.GetPointsSelectList();
                return(Page());
            }

            // confirm our user is a valid PBE User.
            IdentityUser user = await _userManager.GetUserAsync(User);

            PBEUser = await QuizUser.GetOrAddPBEUserAsync(_context, user.Email);

            if (!PBEUser.IsValidPBEQuestionBuilder())
            {
                return(RedirectToPage("/error", new { errorMessage = "Sorry! You do not have sufficient rights to edit a PBE question" }));
            }

            // Now let's create an empty question and put only our validated properties onto it.
            QuizQuestion QuestionToUpdate = await _context.QuizQuestions.FindAsync(Question.Id);

            if (QuestionToUpdate == null)
            {
                return(RedirectToPage("/error", new { errorMessage = "That's Odd! We weren't able to find this Question" }));
            }

            if (await TryUpdateModelAsync <QuizQuestion>(
                    QuestionToUpdate,
                    "Question", // Prefix for form value.
                    Q => Q.BibleId, Q => Q.Points, Q => Q.StartVerse, Q => Q.EndVerse, Q => Q.Question, Q => Q.Challenged, Q => Q.ChallengeComment))
            {
                QuestionToUpdate.Modified = DateTime.Now;

                // now we need to add the Answer if there is one.
                if (AnswerText.Length > 0)
                {
                    // We need the Original Answer and while techincally we support multiple Answers
                    // we are only going to allow operating on the first one in this basic edit experience.
                    await _context.Entry(QuestionToUpdate).Collection(Q => Q.QuizAnswers).LoadAsync();

                    if (QuestionToUpdate.QuizAnswers.Count > 0)
                    {
                        QuizAnswer OriginalAnswer = QuestionToUpdate.QuizAnswers.OrderBy(A => A.Id).First();
                        if (OriginalAnswer.Answer != AnswerText)
                        {
                            _context.Attach(OriginalAnswer);
                            OriginalAnswer.Modified = DateTime.Now;
                            OriginalAnswer.Answer   = AnswerText;

                            QuestionToUpdate.IsAnswered = true;
                        }
                    }
                }
                await _context.SaveChangesAsync();

                switch (ReturnPath)
                {
                case "Questions":
                    return(RedirectToPage("Questions", new { BibleId = QuestionToUpdate.BibleId, BookNumber = QuestionToUpdate.BookNumber, Chapter = QuestionToUpdate.Chapter }));

                // break; not needed unreachable

                case "ChallengedQuestions":
                    return(RedirectToPage("ChallengedQuestions", new { BibleId = QuestionToUpdate.BibleId }));

                // break; not needed unreachable

                default:
                    return(RedirectToPage("AddQuestion", new { BibleId = QuestionToUpdate.BibleId, BookNumber = QuestionToUpdate.BookNumber, Chapter = QuestionToUpdate.Chapter, VerseNum = QuestionToUpdate.EndVerse }));
                    // break; not needed unreachable
                }
            }
            return(RedirectToPage("Index"));
        }
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for
        // more details see https://aka.ms/RazorPagesCRUD.
        public async Task <IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                // Setup our PBEBible Object
                Question.BibleId = await QuizQuestion.GetValidBibleIdAsync(_context, Question.BibleId);

                BibleBook PBEBook = await BibleBook.GetPBEBookAndChapterAsync(_context, Question.BibleId, Question.BookNumber, Question.Chapter);

                if (PBEBook == null)
                {
                    return(RedirectToPage("/error", new { errorMessage = "That's Odd! We weren't able to find the PBE Book." }));
                }

                Question.PopulatePBEQuestionInfo(PBEBook);
                Question.Verses = await Question.GetBibleVersesAsync(_context, false);


                IsCommentary = (Question.Chapter == Bible.CommentaryChapter);
                if (IsCommentary == false)
                {
                    ChapterQuestionCount = PBEBook.BibleChapters.Where(c => c.ChapterNumber == Question.Chapter).First().QuestionCount;
                }
                CommentaryQuestionCount = PBEBook.CommentaryQuestionCount;

                // and now we need a Verse and Points Select List
                ViewData["VerseSelectList"]  = new SelectList(Question.Verses, "Verse", "Verse");
                ViewData["PointsSelectList"] = Question.GetPointsSelectList();
                return(Page());
            }

            // confirm our user is a valid PBE User.
            IdentityUser user = await _userManager.GetUserAsync(User);

            if (User != null)
            {
                PBEUser = await QuizUser.GetOrAddPBEUserAsync(_context, user.Email);

                if (!PBEUser.IsValidPBEQuestionBuilder())
                {
                    return(RedirectToPage("/error", new { errorMessage = "Sorry! You do not have sufficient rights to add a PBE question" }));
                }
            }
            else
            {
                return(RedirectToPage("/error", new { errorMessage = "Oops! We were unable to get our User Object from the UserManager, this question cannot be added!" }));
            }

            // Now let's create an empty question and put only our validated properties onto it.
            var emptyQuestion = new QuizQuestion
            {
                Created  = DateTime.Now,
                Modified = DateTime.Now
            };

            if (await TryUpdateModelAsync <QuizQuestion>(
                    emptyQuestion,
                    "Question", // Prefix for form value.
                    Q => Q.BibleId, Q => Q.Points, Q => Q.BookNumber, Q => Q.Chapter, Q => Q.StartVerse, Q => Q.EndVerse, Q => Q.Question))
            {
                emptyQuestion.Owner  = PBEUser.Email;
                emptyQuestion.Source = "BiblePaths.Net";
                _context.QuizQuestions.Add(emptyQuestion);

                // now we need to add the Answer if there is one.
                if (AnswerText.Length > 0)
                {
                    QuizAnswer Answer = new QuizAnswer
                    {
                        Created   = DateTime.Now,
                        Modified  = DateTime.Now,
                        Question  = emptyQuestion,
                        Answer    = AnswerText,
                        IsPrimary = true
                    };
                    _context.QuizAnswers.Add(Answer);
                    // Register that this question has an answer.
                    emptyQuestion.IsAnswered = true;
                }
                await _context.SaveChangesAsync();

                return(RedirectToPage("AddQuestion", new { BibleId = emptyQuestion.BibleId, BookNumber = emptyQuestion.BookNumber, Chapter = emptyQuestion.Chapter, VerseNum = emptyQuestion.EndVerse }));
            }
            else
            {
                return(RedirectToPage("/error", new { errorMessage = "Oops! We failed to update the question model, this question cannot be added!" }));
            }
            // return RedirectToPage("Index");
        }
Exemple #20
0
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for
        // more details see https://aka.ms/RazorPagesCRUD.
        public async Task <IActionResult> OnPostAsync(int Id)
        {
            IdentityUser user = await _userManager.GetUserAsync(User);

            PBEUser = await QuizUser.GetOrAddPBEUserAsync(_context, user.Email);

            PredefinedQuiz TemplateToUpdate = await _context.PredefinedQuizzes.FindAsync(Id);

            if (TemplateToUpdate == null)
            {
                return(RedirectToPage("/error", new { errorMessage = "Thats Odd! We were unable to find this Quiz Template" }));
            }

            if (!PBEUser.IsValidPBEQuestionBuilder() || PBEUser != TemplateToUpdate.QuizUser)
            {
                return(RedirectToPage("/error", new { errorMessage = "Sorry! You do not have sufficient rights to configure this Quiz Template" }));
            }
            if (TemplateToUpdate.QuizUser != PBEUser)
            {
                return(RedirectToPage("/error", new { errorMessage = "Sorry! Only a Template Owner may edit a Template" }));
            }

            this.BibleId = await Bible.GetValidPBEBibleIdAsync(_context, BibleId);

            _context.Entry(TemplateToUpdate).Collection(T => T.PredefinedQuizQuestions).Load();

            // We need a copy of the Questions list to compare to while the origonal is being updated.
            List <PredefinedQuizQuestion> CompareQuestions = TemplateToUpdate.PredefinedQuizQuestions.ToList();

            if (!ModelState.IsValid)
            {
                //Initialize Our Template Questions
                Questions = TemplateToUpdate.IntiQuestionListForAddEdit();
                // Initialize Template Books
                TemplateBooks = await Template.GetTemplateBooksAsync(_context, this.BibleId);

                JSONBooks = JsonSerializer.Serialize(TemplateBooks);
                // Build Select Lists
                foreach (PredefinedQuizQuestion Question in Questions)
                {
                    Question.AddChapterSelectList(TemplateBooks);
                }
                ViewData["BookSelectList"] = MinBook.GetMinBookSelectListFromList(TemplateBooks);
                return(Page());
            }

            _context.Attach(TemplateToUpdate);
            TemplateToUpdate.Modified = DateTime.Now;

            // Iterate through each of our Questions and make appropriate changes.
            foreach (PredefinedQuizQuestion Question in Questions)
            {
                // See if this is one of our existing Question objects.
                bool ExistingQuestion = true;
                PredefinedQuizQuestion OriginalQuestion = new PredefinedQuizQuestion();
                try
                {
                    OriginalQuestion = CompareQuestions.Where(Q => Q.QuestionNumber == Question.QuestionNumber).Single();
                }
                catch
                {
                    ExistingQuestion = false;
                    // New Question Scenario let's add the Question.
                    if (Question.BookNumber != 0)
                    {
                        PredefinedQuizQuestion QuestionToAdd = new PredefinedQuizQuestion();
                        QuestionToAdd.PredefinedQuiz = TemplateToUpdate;
                        QuestionToAdd.QuestionNumber = Question.QuestionNumber;
                        QuestionToAdd.BookNumber     = Question.BookNumber;
                        QuestionToAdd.Chapter        = Question.Chapter;
                        _context.PredefinedQuizQuestions.Add(QuestionToAdd);
                    }
                }
                if (ExistingQuestion)
                {
                    // Do we need to update OriginalQuestion?
                    if (OriginalQuestion.BookNumber != Question.BookNumber ||
                        OriginalQuestion.Chapter != Question.Chapter)
                    {
                        if (Question.BookNumber != 0)
                        {
                            // this is the update scenario
                            _context.Attach(OriginalQuestion);
                            OriginalQuestion.BookNumber = Question.BookNumber;
                            OriginalQuestion.Chapter    = Question.Chapter;
                        }
                        else
                        {
                            // this is the delete scenario
                            _context.PredefinedQuizQuestions.Remove(OriginalQuestion);
                        }
                    }
                }
                await _context.SaveChangesAsync();
            }
            return(RedirectToPage("./Quizzes", "", new { BibleId = this.BibleId, Message = String.Format("Quiz Template {0} configured successfuly.", TemplateToUpdate.QuizName) }, "Templates"));
        }
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for
        // more details see https://aka.ms/RazorPagesCRUD.
        public async Task <IActionResult> OnPostAsync(int Id)
        {
            // confirm our user is a valid PBE User.
            IdentityUser user = await _userManager.GetUserAsync(User);

            PBEUser = await QuizUser.GetOrAddPBEUserAsync(_context, user.Email);

            if (!PBEUser.IsQuizModerator())
            {
                return(RedirectToPage("/error", new { errorMessage = "Sorry! You do not have sufficient rights to edit a PBE BookList" }));
            }

            QuizBookList BookListToUpdate = await _context.QuizBookLists.FindAsync(Id);

            if (BookListToUpdate == null)
            {
                return(RedirectToPage("/error", new { errorMessage = "That's Odd! We weren't able to find this Book List" }));
            }
            await _context.Entry(BookListToUpdate).Collection(L => L.QuizBookListBookMaps).LoadAsync();

            // We need a copy of the BookListMap to compare to while the origonal is being updated.
            List <QuizBookListBookMap> CompareMap = BookListToUpdate.QuizBookListBookMaps.ToList();

            BibleId = await Bible.GetValidPBEBibleIdAsync(_context, BibleId);

            // Is this an attempted name change... for reals?
            if (Name.ToLower() != BookList.BookListName.ToLower())
            {
                if (await QuizBookList.ListNameAlreadyExistsStaticAsync(_context, Name))
                {
                    ModelState.AddModelError("Name", "Sorry, this Name is already in use.");
                }
                // Update the name since this is a rename attempt.
                BookListToUpdate.BookListName = Name;
            }

            if (!ModelState.IsValid)
            {
                BookList.PadBookListBookMapsForEdit();
                Books = BookList.QuizBookListBookMaps.ToList();
                Name  = BookList.BookListName;
                ViewData["BookSelectList"] = await BibleBook.GetBookSelectListAsync(_context, BibleId);

                return(Page());
            }

            _context.Attach(BookListToUpdate);
            BookListToUpdate.Modified = DateTime.Now;

            // now we need to update the books
            foreach (QuizBookListBookMap Book in Books)
            {
                // See if this is one of our existing BookMaps
                bool ExistingBookMap             = true;
                QuizBookListBookMap OriginalBook = new QuizBookListBookMap();
                try
                {
                    OriginalBook = CompareMap.Where(B => B.Id == Book.Id).Single();
                }
                catch
                {
                    ExistingBookMap = false;
                    // New Book Scenario let's add the book.
                    // But first we won't add it if the Book is already in the List.
                    if (BookListToUpdate.QuizBookListBookMaps.Where(B => B.BookNumber == Book.BookNumber).Any())
                    {
                        // Dupe scenario, don't add
                    }
                    else
                    {
                        if (Book.BookNumber > 0)
                        {
                            QuizBookListBookMap BookToAdd = new QuizBookListBookMap();
                            BookToAdd.BookList   = BookListToUpdate;
                            BookToAdd.IsDeleted  = false;
                            BookToAdd.Created    = DateTime.Now;
                            BookToAdd.Modified   = DateTime.Now;
                            BookToAdd.BookNumber = Book.BookNumber;
                            _context.QuizBookListBookMaps.Add(BookToAdd);
                            //await _context.SaveChangesAsync();
                        }
                    }
                }
                if (ExistingBookMap)
                {
                    // This is the update BookMap scenario
                    if (OriginalBook.BookNumber != Book.BookNumber)
                    {
                        if (Book.BookNumber != 0)
                        {
                            _context.Attach(OriginalBook);
                            OriginalBook.Modified   = DateTime.Now;
                            OriginalBook.BookNumber = Book.BookNumber;
                            // await _context.SaveChangesAsync();
                        }
                        else
                        {
                            // This is the delete BookMap scenario
                            _context.QuizBookListBookMaps.Remove(OriginalBook);
                            // await _context.SaveChangesAsync();
                        }
                    }
                }
            }
            await _context.SaveChangesAsync();

            return(RedirectToPage("BookLists", new { BibleId = this.BibleId, Message = String.Format("Book List {0} successfully updated...", BookListToUpdate.BookListName) }));
        }
Exemple #22
0
        public async Task <IActionResult> OnPostAsync(int?id, int spaces)
        {
            if (id == null)
            {
                return(RedirectToPage("/error", new { errorMessage = "Sorry! The Step Id cannot be null" }));
            }

            Step = await _context.PathNodes.FindAsync(id);

            if (Step == null)
            {
                return(RedirectToPage("/error", new { errorMessage = "That's Odd! We were not able to find this Step" }));
            }
            int StartPosition = Step.Position;
            int TempPosition  = StartPosition;

            Path = await _context.Paths.FindAsync(Step.PathId);

            if (Path == null)
            {
                return(RedirectToPage("/error", new { errorMessage = "That's Odd! We weren't able to find this Path" }));
            }

            IdentityUser user = await _userManager.GetUserAsync(User);

            if (!Path.IsValidPathEditor(user.Email))
            {
                return(RedirectToPage("/error", new { errorMessage = "Sorry! You do not have permissions to move this step." }));
            }

            if (spaces < 0)                                       // this is the move up scenario
            {
                TempPosition = StartPosition + (10 * spaces) - 4; // the minus 4 pushes us above the target step, where want to be and won't conflict with add steps 5.
                if (TempPosition < 0)
                {
                    TempPosition = 0;
                }
            }
            if (spaces > 0)                                       // the move down scenario
            {
                TempPosition = StartPosition + (10 * spaces) + 3; // the plus 3 pushes us above the target step, where want to be and won't conflict with add steps 5.
            }
            // Move the step
            _context.Attach(Step).State = EntityState.Modified;
            Step.Modified = DateTime.Now;
            Step.Position = TempPosition;
            await _context.SaveChangesAsync();

            // Register the event
            if (!Path.IsPathOwner(user.Email))
            {
                _ = await Path.RegisterEventAsync(_context, EventType.NonOwnerEdit, user.Email);
            }
            // Update the Path modified date.
            _context.Attach(Path);
            Path.Modified = DateTime.Now;
            await _context.SaveChangesAsync();

            // Finally we need to re-position each node in the path to ensure safe ordering
            _ = await Path.RedistributeStepsAsync(_context);

            return(RedirectToPage("/Paths/Steps", new { PathId = Step.PathId }));
        }
Exemple #23
0
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for
        // more details see https://aka.ms/RazorPagesCRUD.
        public async Task <IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                // Populate Step for display
                _ = await Step.AddBookNameAsync(_context, BibleId);

                Step.Verses = await Step.GetBibleVersesAsync(_context, BibleId, false, false);

                // and now we need a Verse Select List
                ViewData["VerseSelectList"] = new SelectList(Step.Verses, "Verse", "Verse");
                ViewData["TargetPage"]      = "AddStep";
                return(Page());
            }
            // Now let's validate a few things, first lets go grab the path.
            Path = await _context.Paths.FindAsync(Step.PathId);

            if (Path == null)
            {
                return(RedirectToPage("/error", new { errorMessage = "That's Odd! We weren't able to find this Path" }));
            }

            // confirm our owner is a valid path editor i.e. owner or the path is publicly editable
            IdentityUser user = await _userManager.GetUserAsync(User);

            if (!Path.IsValidPathEditor(user.Email))
            {
                return(RedirectToPage("/error", new { errorMessage = "Sorry! You do not have sufficient rights to add to this Path" }));
            }

            if (!Path.IsPathOwner(user.Email))
            {
                _ = await Path.RegisterEventAsync(_context, EventType.NonOwnerEdit, user.Email);
            }

            // Now let's create an empty Step aka. PathNode object so we can put only our validated properties onto it.
            var emptyStep = new PathNode
            {
                Created  = DateTime.Now,
                Modified = DateTime.Now
            };

            if (await TryUpdateModelAsync <PathNode>(
                    emptyStep,
                    "Step", // Prefix for form value.
                    S => S.StartVerse, S => S.EndVerse, S => S.PathId, S => S.BookNumber, S => S.Chapter, S => S.Position))
            {
                // What we get for Position is actually that of the previous node in the path.
                // We want to replace that with a temporary position that we'll update later.
                int PreviousNodePosition = emptyStep.Position;
                emptyStep.Position = PreviousNodePosition + 5;

                _context.PathNodes.Add(emptyStep);
                await _context.SaveChangesAsync();

                // Now we need to update the Path Object with some calculated properties
                if (!Path.IsPathOwner(user.Email))
                {
                    _ = await Path.RegisterEventAsync(_context, EventType.NonOwnerEdit, user.Email);
                }

                // Prepare to update some properties on Path
                _context.Attach(Path);
                Path.Length = await Path.GetPathVerseCountAsync(_context);

                Path.StepCount = Path.PathNodes.Count;
                Path.Modified  = DateTime.Now;
                // Save our now updated Path Object.
                await _context.SaveChangesAsync();

                // Finally we need to re-position each node in the path to ensure safe ordering
                _ = await Path.RedistributeStepsAsync(_context);

                return(RedirectToPage("/Paths/Steps", new { PathId = Path.Id }));
            }

            //_context.PathNodes.Add(PathNodes);
            //await _context.SaveChangesAsync();

            return(RedirectToPage("./Index"));
        }
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for
        // more details see https://aka.ms/RazorPagesCRUD.
        public async Task <IActionResult> OnPostAsync()
        {
            IdentityUser user = await _userManager.GetUserAsync(User);

            if (!ModelState.IsValid)
            {
                ViewData["PathSelectList"] = await GameGroup.GetPathSelectListAsync(_context);

                return(Page());
            }

            // Now let's create an empty group
            var emptyGroup = new GameGroup
            {
                Created    = DateTime.Now,
                Modified   = DateTime.Now,
                GroupState = (int)GameGroup.GameGroupState.Open,
                Owner      = user.Email
            };

            if (await TryUpdateModelAsync <GameGroup>(
                    emptyGroup,
                    "Group", // Prefix for form value.
                    g => g.Name, g => g.PathId))
            {
                _context.GameGroups.Add(emptyGroup);
                await _context.SaveChangesAsync();

                // go get the Path so we can set first step
                Path path = await _context.Paths.FindAsync(emptyGroup.PathId);

                if (path == null)
                {
                    return(RedirectToPage("/error", new { errorMessage = "That's Very Odd! We were not able to find the Path for this Group" }));
                }
                // We will need that first step.
                _ = await path.AddCalculatedPropertiesAsync(_context);

                // Now we need to parse our Teams and add/remove
                foreach (GameTeam Team in Teams)
                {
                    if (Team.Name != null)
                    {
                        if (Team.Name.Length > 0)
                        {
                            var emptyTeam = new GameTeam
                            {
                                CurrentStepId = path.FirstStepId,
                                TeamType      = 0,
                                BoardState    = (int)GameTeam.GameBoardState.WordSelect,
                                StepNumber    = 1,
                                Created       = DateTime.Now,
                                Modified      = DateTime.Now,
                            };
                            emptyTeam.Name  = Team.Name;
                            emptyTeam.Group = emptyGroup;
                            _context.GameTeams.Add(emptyTeam);
                        }
                    }
                }
                await _context.SaveChangesAsync();

                return(RedirectToPage("Group", new { Id = emptyGroup.Id, Message = String.Format("Group {0} successfully created...", emptyGroup.Name) }));
            }

            return(Page());
        }