Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
0712816
refactor: fusionne les 2 controllers de choix du mode en un wizard Wi…
lordinatrice Aug 6, 2026
c936e1c
test: ajoute le scénario cucumber de reconnexion en mode mixte
lordinatrice Aug 6, 2026
d026168
fix: empêche de rejouer le choix de mode et corrige la liaison user e…
lordinatrice Aug 7, 2026
98d5217
feat: étend GroupingMember pour la composition du groupement
lordinatrice Aug 6, 2026
70580cc
feat: ajoute FetchRaisonSociale, résolution SIRET→raison sociale via …
lordinatrice Aug 14, 2026
ef88c7a
feat: le mandataire ajoute et retire des co-traitants
lordinatrice Aug 6, 2026
72eb748
feat: le mandataire confirme la composition et les invitations sont e…
lordinatrice Aug 6, 2026
ab5fbab
test: ajoute les scénarios cucumber de composition du groupement
lordinatrice Aug 6, 2026
026e8cf
feat: ajoute la détection de l'étape choix du mode par lot au wizard …
lordinatrice Aug 19, 2026
b0b37b4
feat: ajoute l'interactor de répartition des lots seul/groupement (FA…
lordinatrice Aug 19, 2026
28e5baa
feat: ajoute le presenter du choix de mode par lot (FAS-561)
lordinatrice Aug 19, 2026
cbde53e
feat: ajoute l'écran de sélection du mode de réponse par lot (FAS-561)
lordinatrice Aug 19, 2026
f3fb82c
test: ajoute les scénarios cucumber du choix de mode par lot (FAS-561)
lordinatrice Aug 19, 2026
ec896b9
refactor: supprime errors_from, réimplémentation de errors.to_hash natif
lordinatrice Aug 19, 2026
33988ec
fix: stabilise le scénario de reconnexion avant choix du type de grou…
lordinatrice Aug 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
212 changes: 212 additions & 0 deletions app/assets/stylesheets/application.css
Original file line number Diff line number Diff line change
Expand Up @@ -1017,3 +1017,215 @@
display: flex;
justify-content: space-between;
}

.grouping-legal-type-actions .fr-btn[aria-disabled="true"] {
background-color: var(--background-disabled-grey);
color: var(--text-disabled-grey);
pointer-events: none;
cursor: not-allowed;
}

.grouping-member-form {
background-color: var(--background-alt-blue-france);
border-left: 4px solid var(--border-plain-blue-france);
padding: 32px 40px;
}

#grouping_members_table .fr-table,
#grouping_members_table .fr-table__wrapper,
#grouping_members_table .fr-table__container,
#grouping_members_table .fr-table__content {
display: block !important;
width: 100% !important;
max-width: none !important;
border: none !important;
}

#grouping_members_table table {
display: table !important;
width: 100% !important;
table-layout: fixed !important;
border-collapse: collapse !important;
border: 1px solid var(--light-decisions-border-border-default-grey, #ddd) !important;
}

#grouping_members_table th,
#grouping_members_table td {
border: none !important;
background-image: none !important;
border-bottom: 1px solid var(--light-decisions-border-border-default-grey, #ddd) !important;
}

#grouping_members_table thead,
#grouping_members_table tbody,
#grouping_members_table tbody::after,
#grouping_members_table thead::after {
background-image: none !important;
}

#grouping_members_table tbody tr {
background-color: var(--background-default-grey, #fff) !important;
}

.lot-selection-rc-notice {
display: flex;
align-items: stretch;
background-color: var(--background-alt-blue-france, #f5f5fe);
}

.lot-selection-rc-notice__icon {
flex-shrink: 0;
display: flex;
align-items: flex-start;
padding: 1rem 0.5rem;
background-color: var(--background-flat-info, #0063cb);
color: var(--text-inverted-grey, #fff);
}

.lot-selection-rc-notice__content {
padding: 1rem;
}

.lot-selection-rc-notice__title {
font-weight: 700;
font-size: 1.25rem;
line-height: 1.75rem;
margin: 0 0 0.25rem;
color: var(--text-title-grey, #161616);
}

.lot-selection-rc-notice__text {
margin: 0;
font-size: 1rem;
color: var(--text-default-grey, #3a3a3a);
}

.lot-selection-mode-banner {
display: flex;
align-items: center;
gap: 0.5rem;
margin: 0;
font-size: 0.875rem;
color: var(--text-default-grey, #3a3a3a);
}

.lot-selection-mode-bulk {
display: flex;
align-items: center;
gap: 0.5rem;
flex-wrap: nowrap;
white-space: nowrap;
}

.lot-selection-mode-bulk__select {
appearance: none;
background-color: var(--background-default-grey, #fff);
border: 1px solid var(--border-default-grey, #ddd);
color: var(--text-action-high-blue-france, #000091);
font-size: 0.875rem;
font-weight: 500;
padding: 0.25rem 1.75rem 0.25rem 0.75rem;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='%23000091'%3E%3Cpath d='M12 15.5l-6-6 1.4-1.4L12 12.7l4.6-4.6L18 9.5z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 0.5rem center;
}

.lot-mode-choices {
display: inline-flex;
border: 1px solid var(--border-default-grey);
border-radius: 0.25rem;
}

.lot-mode-choice__input {
position: absolute;
opacity: 0;
width: 1px;
height: 1px;
}

.lot-mode-choice__label {
display: inline-block;
padding: 0.25rem 0.75rem;
margin: -1px;
border: 1px solid transparent;
border-radius: 0.25rem;
cursor: pointer;
font-size: 0.875rem;
font-weight: 500;
line-height: 1.5rem;
white-space: nowrap;
color: var(--text-action-high-grey);
}

.lot-mode-choice__input:checked + .lot-mode-choice__label {
border-color: var(--border-action-high-blue-france, #000091);
color: var(--text-action-high-blue-france, #000091);
}

.lot-mode-choice__input:focus-visible + .lot-mode-choice__label {
outline: 2px solid var(--border-action-high-blue-france);
outline-offset: -2px;
}

.lot-selection-mode-section__header {
padding-bottom: 1rem;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 0.5rem;
}

.lot-selection-mode-group__title {
display: flex;
align-items: center;
gap: 0.5rem;
}

.lot-selection-mode-group__title-text {
margin: 0;
font-weight: 700;
font-size: 1.25rem;
line-height: 2rem;
color: var(--text-title-grey, #000);
}

.lot-selection-mode-group__badge .market-type-badge {
border-radius: 1rem;
padding: 0.375rem 0.75rem;
align-items: center;
}

.lot-selection-mode-group__badge .market-type-badge img {
width: 18px;
height: 18px;
vertical-align: middle;
}

.lot-selection-mode-table {
width: 100%;
border-collapse: collapse;
background-color: var(--background-default-grey, #fff);
border: 1px solid var(--border-default-grey, #ddd);
}

.lot-selection-mode-table th,
.lot-selection-mode-table td {
border-bottom: 1px solid var(--border-default-grey, #ddd);
padding: 0.75rem 1rem;
text-align: left;
font-size: 0.875rem;
vertical-align: middle;
}

.lot-selection-mode-table th {
font-weight: 700;
color: var(--text-default-grey, #3a3a3a);
background-color: var(--background-alt-grey, #f6f6f6);
padding-top: 1rem;
padding-bottom: 1rem;
}

.lot-selection-mode-table td:last-child {
text-align: right;
}
66 changes: 66 additions & 0 deletions app/components/grouping_invitation_email_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<table width="100%" cellpadding="0" cellspacing="0" style="font-family: Marianne, arial, sans-serif; background-color: #f6f6f6;">
<tr>
<td align="center" style="padding: 24px 16px;">
<table width="600" cellpadding="0" cellspacing="0" style="background-color: #ffffff; border: 1px solid #dddddd;">

<%# Header %>
<tr>
<td colspan="2" style="background-color: #f5f5fe; padding: 40px 32px; text-align: center;">
<h1 style="margin: 0; font-size: 26px; font-weight: 700; color: #161616; line-height: 1.3;">
<%= t('grouping_invitation_mailer.invitation.subject') %>
</h1>
</td>
</tr>

<%# Body %>
<tr>
<td width="274" valign="top" style="padding: 28px 20px 28px 32px;">
<p style="margin: 0 0 12px; font-size: 18px; font-weight: 700; color: #161616;">
<%= t('grouping_invitation_mailer.invitation.greeting') %>
</p>

<p style="margin: 0 0 12px; font-size: 15px; color: #3a3a3a; line-height: 1.6;">
<%= t('grouping_invitation_mailer.invitation.intro') %>
&ldquo;<strong><%= @market_name %></strong>&rdquo;
</p>

<p style="margin: 0 0 20px; font-size: 15px; color: #3a3a3a;">
<%= t('grouping_invitation_mailer.invitation.cta_intro') %>
</p>

<table cellpadding="0" cellspacing="0" style="margin-bottom: 20px;">
<tr>
<td style="background-color: #000091; border-radius: 4px;">
<%= link_to t('grouping_invitation_mailer.invitation.cta'), @url,
style: "display: inline-block; padding: 12px 24px; color: #ffffff; font-size: 15px; font-weight: 700; text-decoration: none; white-space: nowrap;" %>
</td>
</tr>
</table>
</td>

<%# Logo %>
<td width="326" valign="middle" align="center" style="padding: 28px 32px 28px 0; background-color: #ffffff;">
<img src="<%= logo_data_uri %>"
alt=""
width="120"
style="display: block; width: 120px; height: 153px; margin: 0 auto;" />
</td>
</tr>

<%# Footer %>
<tr>
<td colspan="2" style="padding: 20px 32px; border-top: 1px solid #dddddd; text-align: center; background-color: #f5f5fe;">
<p style="margin: 0 0 8px; font-size: 13px;">
<a href="#" style="color: #0063cb; text-decoration: underline;"><%= t('auth_mailer.magic_link.footer.privacy') %></a>
&nbsp;|&nbsp;
<a href="#" style="color: #0063cb; text-decoration: underline;"><%= t('auth_mailer.magic_link.footer.legal') %></a>
</p>
<p style="margin: 0 0 4px; font-size: 12px; color: #666666;"><%= t('auth_mailer.magic_link.footer.copyright') %></p>
<p style="margin: 0; font-size: 12px; color: #666666;"><%= t('auth_mailer.magic_link.footer.contact') %></p>
</td>
</tr>

</table>
</td>
</tr>
</table>
16 changes: 16 additions & 0 deletions app/components/grouping_invitation_email_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

class GroupingInvitationEmailComponent < ViewComponent::Base
def initialize(url:, market_name:)
@url = url
@market_name = market_name
end

private

def logo_data_uri
image_path = Rails.root.join('app/assets/images/passe-marche-logo-email.jpg')
base64 = Base64.strict_encode64(File.binread(image_path))
"data:image/jpeg;base64,#{base64}"
end
end
13 changes: 8 additions & 5 deletions app/controllers/api/v1/market_applications_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,21 @@ def success_response(market_application)
end

def application_url_for(market_application)
if market_application.application_mode_choice_required?
return Rails.application.routes.url_helpers.application_mode_candidate_market_application_url(
market_application.identifier
)
end
target, step = market_application.next_required_wizard_step
return wizard_step_url(target, step) if target

Rails.application.routes.url_helpers.step_candidate_market_application_url(
market_application.identifier,
:company_identification
)
end

def wizard_step_url(market_application, step)
Rails.application.routes.url_helpers.grouping_wizard_step_candidate_market_application_url(
market_application.identifier, step
)
end

def validate_application_completed
return if @market_application.completed?

Expand Down
65 changes: 0 additions & 65 deletions app/controllers/candidate/application_modes_controller.rb

This file was deleted.

Loading