diff --git a/src/registrar/forms/user_profile.py b/src/registrar/forms/user_profile.py index 3dd8cbdce..682e1a5df 100644 --- a/src/registrar/forms/user_profile.py +++ b/src/registrar/forms/user_profile.py @@ -10,6 +10,8 @@ from registrar.models.utility.domain_helper import DomainHelper class UserProfileForm(forms.ModelForm): """Form for updating user profile.""" + redirect = forms.CharField(widget=forms.HiddenInput(), required=False) + class Meta: model = Contact fields = ["first_name", "middle_name", "last_name", "title", "email", "phone"] diff --git a/src/registrar/registrar_middleware.py b/src/registrar/registrar_middleware.py index 7ba304aba..88eb9af2d 100644 --- a/src/registrar/registrar_middleware.py +++ b/src/registrar/registrar_middleware.py @@ -38,21 +38,6 @@ class CheckUserProfileMiddleware: def __init__(self, get_response): self.get_response = get_response - self.setup_page = reverse("finish-user-profile-setup") - self.profile_page = reverse("user-profile") - self.logout_page = reverse("logout") - self.regular_excluded_pages = [ - self.setup_page, - self.logout_page, - "/admin", - ] - self.other_excluded_pages = [ - self.profile_page, - self.logout_page, - "/admin", - ] - - def __init__(self): self.setup_page = reverse("finish-user-profile-setup") self.profile_page = reverse("user-profile") self.logout_page = reverse("logout") diff --git a/src/registrar/templates/domain_request_intro.html b/src/registrar/templates/domain_request_intro.html index 2bfeeeef1..370ea2b2b 100644 --- a/src/registrar/templates/domain_request_intro.html +++ b/src/registrar/templates/domain_request_intro.html @@ -18,7 +18,7 @@ completing your domain request might take around 15 minutes.

{% if has_profile_feature_flag %}

How we’ll reach you

-

While reviewing your domain request, we may need to reach out with questions. We’ll also email you when we complete our review If the contact information below is not correct, visit your profile to make updates.

+

While reviewing your domain request, we may need to reach out with questions. We’ll also email you when we complete our review If the contact information below is not correct, visit your profile to make updates.

{% include "includes/profile_information.html" with user=user%} {% endif %} diff --git a/src/registrar/templates/includes/finish_profile_form.html b/src/registrar/templates/includes/finish_profile_form.html index a40534b48..1e48d5578 100644 --- a/src/registrar/templates/includes/finish_profile_form.html +++ b/src/registrar/templates/includes/finish_profile_form.html @@ -33,6 +33,8 @@ Your contact information + + {% with show_edit_button=True show_readonly=True group_classes="usa-form-editable usa-form-editable--no-border padding-top-2" %} {% input_with_errors form.full_name %} {% endwith %} diff --git a/src/registrar/templates/includes/profile_form.html b/src/registrar/templates/includes/profile_form.html index cb3e734bf..966b92b01 100644 --- a/src/registrar/templates/includes/profile_form.html +++ b/src/registrar/templates/includes/profile_form.html @@ -19,6 +19,9 @@
{% csrf_token %} + {# Include the hidden 'redirect' field #} + + {% input_with_errors form.first_name %} {% input_with_errors form.middle_name %} diff --git a/src/registrar/templates/profile.html b/src/registrar/templates/profile.html index c62d0a7c1..41471fe88 100644 --- a/src/registrar/templates/profile.html +++ b/src/registrar/templates/profile.html @@ -25,19 +25,13 @@ Edit your User Profile | {% include "includes/form_errors.html" with form=form %} {% if show_back_button %} - + - {% if not return_to_request %}

{{ profile_back_button_text }}

- {% else %} -

- Go back to your domain request -

- {% endif %}
{% endif %} diff --git a/src/registrar/views/user_profile.py b/src/registrar/views/user_profile.py index f148f5652..ddb6136f5 100644 --- a/src/registrar/views/user_profile.py +++ b/src/registrar/views/user_profile.py @@ -9,6 +9,7 @@ from urllib.parse import parse_qs, unquote from urllib.parse import quote from django.contrib import messages +from django.http import QueryDict from django.views.generic.edit import FormMixin from registrar.forms.user_profile import UserProfileForm, FinishSetupProfileForm from django.urls import NoReverseMatch, reverse @@ -31,16 +32,48 @@ class UserProfileView(UserProfilePermissionView, FormMixin): Base View for the User Profile. Handles getting and setting the User Profile """ + class RedirectType(Enum): + """ + Enums for each type of redirection. Enforces behaviour on `get_redirect_url()`. + + - HOME: We want to redirect to reverse("home") + - BACK_TO_SELF: We want to redirect back to this page + - TO_SPECIFIC_PAGE: We want to redirect to the page specified in the queryparam "redirect" + - COMPLETE_SETUP: Indicates that we want to navigate BACK_TO_SELF, but the subsequent + redirect after the next POST should be either HOME or TO_SPECIFIC_PAGE + """ + + HOME = "home" + TO_SPECIFIC_PAGE = "domain_request" + BACK_TO_SELF = "back_to_self" + COMPLETE_SETUP = "complete_setup" + + @classmethod + def get_all_redirect_types(cls) -> list[str]: + """Returns the value of every redirect type defined in this enum.""" + return [r.value for r in cls] + model = Contact template_name = "profile.html" form_class = UserProfileForm + base_view_name = "user-profile" + + all_redirect_types = RedirectType.get_all_redirect_types() + redirect_type: RedirectType def get(self, request, *args, **kwargs): """Handle get requests by getting user's contact object and setting object and form to context before rendering.""" - self._refresh_session_and_object(request) - form = self.form_class(instance=self.object) - context = self.get_context_data(object=self.object, form=form) + #self._refresh_session_and_object(request) + self.object = self.get_object() + + # Get the redirect parameter from the query string + redirect = request.GET.get('redirect', 'home') + + logger.info(f"redirect value is {redirect}") + + form = self.form_class(instance=self.object, initial={'redirect': redirect}) + context = self.get_context_data(object=self.object, form=form, redirect=redirect) if ( hasattr(self.user, "finished_setup") @@ -63,8 +96,8 @@ class UserProfileView(UserProfilePermissionView, FormMixin): @waffle_flag("profile_feature") # type: ignore def dispatch(self, request, *args, **kwargs): # type: ignore # Store the original queryparams to persist them - query_params = request.META["QUERY_STRING"] - request.session["query_params"] = query_params + # query_params = request.META["QUERY_STRING"] + # request.session["query_params"] = query_params return super().dispatch(request, *args, **kwargs) def get_context_data(self, **kwargs): @@ -73,10 +106,14 @@ class UserProfileView(UserProfilePermissionView, FormMixin): # This is a django waffle flag which toggles features based off of the "flag" table context["has_profile_feature_flag"] = flag_is_active(self.request, "profile_feature") - # The text for the back button on this page - context["profile_back_button_text"] = "Go to manage your domains" - context["show_back_button"] = False + # Set the profile_back_button_text based on the redirect parameter + if kwargs.get('redirect') == 'domain-request:': + context["profile_back_button_text"] = "Go back to your request" + else: + context["profile_back_button_text"] = "Go to manage your domains" + # Show back button conditional on user having finished setup + context["show_back_button"] = False if hasattr(self.user, "finished_setup") and self.user.finished_setup: context["user_finished_setup"] = True context["show_back_button"] = True @@ -84,21 +121,30 @@ class UserProfileView(UserProfilePermissionView, FormMixin): return context def get_success_url(self): - """Redirect to the user's profile page.""" + """Redirect to the user's profile page with updated query parameters.""" - query_params = {} - if "query_params" in self.session: - params = unquote(self.session["query_params"]) - query_params = parse_qs(params) + # Get the redirect parameter from the form submission + redirect_param = self.request.POST.get('redirect', None) - # Preserve queryparams and add them back to the url - base_url = reverse("user-profile") - new_redirect = replace_url_queryparams(base_url, query_params, convert_list_to_csv=True) - return new_redirect + # Initialize QueryDict with existing query parameters from current request + query_params = QueryDict(mutable=True) + query_params.update(self.request.GET) + + # Update query parameters with the 'redirect' value from form submission + if redirect_param and redirect_param != 'home': + query_params['redirect'] = redirect_param + + # Generate the URL with updated query parameters + base_url = reverse(self.base_view_name) + + # Generate the full url from the given query params + full_url = replace_url_queryparams(base_url, query_params) + return full_url def post(self, request, *args, **kwargs): """Handle post requests (form submissions)""" - self._refresh_session_and_object(request) + #self._refresh_session_and_object(request) + self.object = self.get_object() form = self.form_class(request.POST, instance=self.object) if form.is_valid(): @@ -133,80 +179,75 @@ class FinishProfileSetupView(UserProfileView): """This view forces the user into providing additional details that we may have missed from Login.gov""" - class RedirectType(Enum): - """ - Enums for each type of redirection. Enforces behaviour on `get_redirect_url()`. - - - HOME: We want to redirect to reverse("home") - - BACK_TO_SELF: We want to redirect back to this page - - TO_SPECIFIC_PAGE: We want to redirect to the page specified in the queryparam "redirect" - - COMPLETE_SETUP: Indicates that we want to navigate BACK_TO_SELF, but the subsequent - redirect after the next POST should be either HOME or TO_SPECIFIC_PAGE - """ - - HOME = "home" - TO_SPECIFIC_PAGE = "domain_request" - BACK_TO_SELF = "back_to_self" - COMPLETE_SETUP = "complete_setup" - - @classmethod - def get_all_redirect_types(cls) -> list[str]: - """Returns the value of every redirect type defined in this enum.""" - return [r.value for r in cls] - template_name = "finish_profile_setup.html" form_class = FinishSetupProfileForm model = Contact - all_redirect_types = RedirectType.get_all_redirect_types() - redirect_type: RedirectType + base_view_name = "finish-user-profile-setup" def get_context_data(self, **kwargs): - + """Extend get_context_data to include has_profile_feature_flag""" context = super().get_context_data(**kwargs) - # Hide the back button by default + # Show back button conditional on user having finished setup context["show_back_button"] = False - - if self.redirect_type == self.RedirectType.COMPLETE_SETUP: + if hasattr(self.user, "finished_setup") and self.user.finished_setup: context["confirm_changes"] = True - - if "redirect_viewname" not in self.session: + if kwargs.get('redirect') == 'home': + context["profile_back_button_text"] = "Go to manage your domains" context["show_back_button"] = True else: context["going_to_specific_page"] = True context["redirect_button_text"] = "Continue to your request" - return context + + # def get_context_data(self, **kwargs): - @method_decorator(csrf_protect) - def dispatch(self, request, *args, **kwargs): - """ - Handles dispatching of the view, applying CSRF protection and checking the 'profile_feature' flag. + # context = super().get_context_data(**kwargs) - This method sets the redirect type based on the 'redirect' query parameter, - defaulting to BACK_TO_SELF if not provided. - It updates the session with the redirect view name if the redirect type is TO_SPECIFIC_PAGE. + # # Hide the back button by default + # context["show_back_button"] = False - Returns: - HttpResponse: The response generated by the parent class's dispatch method. - """ + # logger.info(f"self.redirect_type = {self.redirect_type}") + # if self.redirect_type == self.RedirectType.COMPLETE_SETUP: + # context["confirm_changes"] = True - # Update redirect type based on the query parameter if present - default_redirect_value = self.RedirectType.BACK_TO_SELF.value - redirect_value = request.GET.get("redirect", default_redirect_value) + # if "redirect_viewname" not in self.session: + # context["show_back_button"] = True + # else: + # context["going_to_specific_page"] = True + # context["redirect_button_text"] = "Continue to your request" - if redirect_value in self.all_redirect_types: - # If the redirect value is a preexisting value in our enum, set it to that. - self.redirect_type = self.RedirectType(redirect_value) - else: - # If the redirect type is undefined, then we assume that we are specifying a particular page to redirect to. - self.redirect_type = self.RedirectType.TO_SPECIFIC_PAGE + # return context - # Store the page that we want to redirect to for later use - request.session["redirect_viewname"] = str(redirect_value) + # @method_decorator(csrf_protect) + # def dispatch(self, request, *args, **kwargs): + # """ + # Handles dispatching of the view, applying CSRF protection and checking the 'profile_feature' flag. - return super().dispatch(request, *args, **kwargs) + # This method sets the redirect type based on the 'redirect' query parameter, + # defaulting to BACK_TO_SELF if not provided. + # It updates the session with the redirect view name if the redirect type is TO_SPECIFIC_PAGE. + + # Returns: + # HttpResponse: The response generated by the parent class's dispatch method. + # """ + + # # Update redirect type based on the query parameter if present + # default_redirect_value = self.RedirectType.BACK_TO_SELF.value + # redirect_value = request.GET.get("redirect", default_redirect_value) + + # if redirect_value in self.all_redirect_types: + # # If the redirect value is a preexisting value in our enum, set it to that. + # self.redirect_type = self.RedirectType(redirect_value) + # else: + # # If the redirect type is undefined, then we assume that we are specifying a particular page to redirect to. + # self.redirect_type = self.RedirectType.TO_SPECIFIC_PAGE + + # # Store the page that we want to redirect to for later use + # request.session["redirect_viewname"] = str(redirect_value) + + # return super().dispatch(request, *args, **kwargs) def post(self, request, *args, **kwargs): """Form submission posts to this view.""" @@ -217,17 +258,23 @@ class FinishProfileSetupView(UserProfileView): if form.is_valid(): if "contact_setup_save_button" in request.POST: # Logic for when the 'Save' button is clicked - self.redirect_type = self.RedirectType.COMPLETE_SETUP + self.redirect_page = False + #self.redirect_type = self.RedirectType.COMPLETE_SETUP elif "contact_setup_submit_button" in request.POST: - specific_redirect = "redirect_viewname" in self.session - self.redirect_type = self.RedirectType.TO_SPECIFIC_PAGE if specific_redirect else self.RedirectType.HOME + self.redirect_page = True + # specific_redirect = "redirect_viewname" in self.session + # self.redirect_type = self.RedirectType.TO_SPECIFIC_PAGE if specific_redirect else self.RedirectType.HOME return self.form_valid(form) else: return self.form_invalid(form) def get_success_url(self): """Redirect to the nameservers page for the domain.""" - return self.get_redirect_url() + # Get the redirect parameter from the form submission + redirect_param = self.request.POST.get('redirect', None) + if self.redirect_page and redirect_param: + return reverse(redirect_param) + return super().get_success_url() def get_redirect_url(self): """