Skip to content

Commit c7038c6

Browse files
Merge pull request #27 from docusign/DEVDOCS-18114
Devdocs 18114
2 parents 03b2847 + 6c2fb66 commit c7038c6

File tree

16 files changed

+573
-219
lines changed

16 files changed

+573
-219
lines changed

DocuSign.Workspaces/DocuSign.Workspaces/ClientApp/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"name": "clientapp-temp",
33
"version": "0.1.0",
44
"private": true,
5+
"proxy": "http://localhost:5000",
56
"dependencies": {
67
"@testing-library/dom": "^10.4.1",
78
"@testing-library/jest-dom": "^6.9.1",

DocuSign.Workspaces/DocuSign.Workspaces/ClientApp/src/components/AgreementRow.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useTranslation } from 'react-i18next';
22

3-
export const AgreementRow = ({ label, checked, onToggle, onPreview }) => {
3+
export const AgreementRow = ({ label, checked, onToggle, onPreview, showPreview = true }) => {
44
const { t } = useTranslation();
55
return (
66
<div className="agreement-row">
@@ -12,10 +12,11 @@ export const AgreementRow = ({ label, checked, onToggle, onPreview }) => {
1212
className="agreement-row__checkbox"
1313
/>
1414
{label}
15-
16-
<button onClick={onPreview} className="agreement-row__preview-btn">
17-
{t('Common.Preview')}
18-
</button>
15+
{showPreview && onPreview && (
16+
<button onClick={onPreview} className="agreement-row__preview-btn">
17+
{t('Common.Preview')}
18+
</button>
19+
)}
1920
</label>
2021
</div>
2122
);

DocuSign.Workspaces/DocuSign.Workspaces/ClientApp/src/components/Layout.js

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { useEffect, useState } from 'react';
22
import { Link, Outlet, useNavigate, useLocation } from 'react-router-dom';
33
import { useTranslation } from 'react-i18next';
44
import LoginModal from '../loginModal/LoginModal';
5+
import { useAcgLogin } from '../hooks/useAcgLogin';
56
import { ReactComponent as ChevronRightIcon } from '../assets/icons/chevron-right.svg';
67
import { ReactComponent as CrossIcon } from '../assets/icons/cross.svg';
78
import { ReactComponent as LogoIcon } from '../assets/icons/logo_40х40.svg';
@@ -27,6 +28,9 @@ export default function Layout() {
2728
{ key: 'demo', label: t('Layout.Demo'), url: 'https://account-d.docusign.com' },
2829
{ key: 'production', label: t('Layout.Production'), url: 'https://account.docusign.com' },
2930
];
31+
32+
const { loginWithAcg } = useAcgLogin(API_BASE, ENVIRONMENTS[0].url);
33+
3034
const [accountStatus, setAccountStatus] = useState(null);
3135
const [isTestAccount, setIsTestAccount] = useState(() =>
3236
typeof JSON.parse(localStorage.getItem('isTestAccount')) === 'boolean'
@@ -86,9 +90,30 @@ export default function Layout() {
8690
useEffect(() => {
8791
const authStep = getCookie('ds_auth_step');
8892
if (authStep === 'acg-consent' && accountStatus?.isConsentGranted) {
89-
setIsLoginOpen(true);
93+
// Complete ACG login directly without opening modal
94+
setIsTestAccount(false);
95+
loginWithAcg(async () => {
96+
await fetchStatus();
97+
clearAuthCookie();
98+
}).catch(err => {
99+
console.error('Failed to complete ACG login after consent:', err);
100+
clearAuthCookie();
101+
});
90102
}
91-
}, [accountStatus]);
103+
}, [accountStatus, loginWithAcg]);
104+
105+
const handleDirectLogin = async () => {
106+
setIsNavOpen(false);
107+
setIsTestAccount(false);
108+
try {
109+
await loginWithAcg(async () => {
110+
await fetchStatus();
111+
clearAuthCookie();
112+
});
113+
} catch (err) {
114+
console.error('Login failed:', err);
115+
}
116+
};
92117

93118
const openLoginModal = () => {
94119
setIsNavOpen(false);
@@ -167,7 +192,7 @@ export default function Layout() {
167192
<button
168193
className="pill pill--light nav__cta"
169194
type="button"
170-
onClick={openLoginModal}
195+
onClick={handleDirectLogin}
171196
>
172197
{t('Login')}
173198
</button>
@@ -178,7 +203,7 @@ export default function Layout() {
178203
</header>
179204

180205
<main className="main-content">
181-
<Outlet context={{ openLoginModal, accountStatus, isTestAccount }} />
206+
<Outlet context={{ openLoginModal, handleDirectLogin, accountStatus, isTestAccount }} />
182207
</main>
183208

184209
<footer className="footer">

DocuSign.Workspaces/DocuSign.Workspaces/ClientApp/src/components/SelectDocuments.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { ReactComponent as ArrowLeftIcon } from '../assets/icons/arrow-left.svg'
77
const listToSign = [
88
{
99
id: 21,
10-
name: 'Engagement Agreement.pdf',
10+
name: 'Engagement Letter.pdf',
1111
path: '/Engagement Agreement placeholder.pdf',
1212
isForSignature: true,
1313
},
@@ -95,6 +95,7 @@ export const SelectDocuments = ({ onAddDocuments, requesting = false, onPrevious
9595
onPreview={() => {
9696
handlePreview(item);
9797
}}
98+
showPreview={false}
9899
/>
99100
))}
100101
</div>
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { useTranslation } from 'react-i18next';
2+
import './WorkspaceAccessErrorModal.scss';
3+
4+
function WorkspaceAccessErrorModal({ isOpen, onClose }) {
5+
const { t } = useTranslation();
6+
7+
if (!isOpen) return null;
8+
9+
return (
10+
<div className="workspace-error-modal__backdrop" role="dialog" aria-modal="true">
11+
<div className="workspace-error-modal">
12+
<button
13+
className="workspace-error-modal__close"
14+
type="button"
15+
onClick={onClose}
16+
aria-label={t('Common.Close')}
17+
>
18+
×
19+
</button>
20+
<div className="workspace-error-modal__header">
21+
<h2>{t('WorkspaceAccessError.Title')}</h2>
22+
</div>
23+
<div className="workspace-error-modal__content">
24+
<p className="workspace-error-modal__description">
25+
{t('WorkspaceAccessError.Description')}
26+
</p>
27+
<div className="workspace-error-modal__cta">
28+
<a
29+
href="https://apps-d.docusign.com/workspaces"
30+
target="_blank"
31+
rel="noreferrer"
32+
className="workspace-error-modal__primary-button"
33+
>
34+
{t('WorkspaceAccessError.EnableWorkspaces')}
35+
</a>
36+
</div>
37+
<div className="workspace-error-modal__support">
38+
<p>{t('WorkspaceAccessError.NeedHelp')}</p>
39+
<a
40+
href="https://developers.docusign.com/docs/workspaces-api/"
41+
target="_blank"
42+
rel="noreferrer"
43+
className="workspace-error-modal__link"
44+
>
45+
{t('WorkspaceAccessError.ViewDocumentation')}
46+
</a>
47+
<a
48+
href="https://developers.docusign.com/support/"
49+
target="_blank"
50+
rel="noreferrer"
51+
className="workspace-error-modal__link"
52+
>
53+
{t('WorkspaceAccessError.ContactSupport')}
54+
</a>
55+
</div>
56+
</div>
57+
<div className="workspace-error-modal__actions">
58+
<button className="primary-btn" type="button" onClick={onClose}>
59+
{t('Common.Close')}
60+
</button>
61+
</div>
62+
</div>
63+
</div>
64+
);
65+
}
66+
67+
export default WorkspaceAccessErrorModal;
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
.workspace-error-modal__backdrop {
2+
position: fixed;
3+
inset: 0;
4+
background: rgba(3, 12, 26, 0.7);
5+
display: flex;
6+
align-items: center;
7+
justify-content: center;
8+
z-index: 1000;
9+
}
10+
11+
.workspace-error-modal {
12+
background: #fff;
13+
color: #061a2f;
14+
padding: 2rem;
15+
border-radius: 16px;
16+
width: min(600px, calc(100% - 2rem));
17+
max-height: calc(100vh - 4rem);
18+
overflow-y: auto;
19+
box-shadow: 0 30px 70px rgba(0, 0, 0, 0.35);
20+
position: relative;
21+
}
22+
23+
.workspace-error-modal__close {
24+
position: absolute;
25+
top: 1rem;
26+
right: 1rem;
27+
border: none;
28+
background: transparent;
29+
font-size: 2rem;
30+
line-height: 1;
31+
cursor: pointer;
32+
color: #666;
33+
width: 32px;
34+
height: 32px;
35+
display: flex;
36+
align-items: center;
37+
justify-content: center;
38+
border-radius: 4px;
39+
transition: all 0.2s;
40+
41+
&:hover {
42+
background: #f0f0f0;
43+
color: #000;
44+
}
45+
}
46+
47+
.workspace-error-modal__header {
48+
display: flex;
49+
flex-direction: column;
50+
align-items: center;
51+
gap: 1rem;
52+
margin-bottom: 1.5rem;
53+
text-align: center;
54+
}
55+
56+
.workspace-error-modal__header h2 {
57+
margin: 0;
58+
font-family: 'Inter', sans-serif;
59+
font-weight: 600;
60+
font-size: 24px;
61+
line-height: 1.4;
62+
color: #141414;
63+
}
64+
65+
.workspace-error-modal__content {
66+
display: flex;
67+
flex-direction: column;
68+
gap: 1.5rem;
69+
}
70+
71+
.workspace-error-modal__description {
72+
font-size: 16px;
73+
line-height: 1.6;
74+
color: #444;
75+
margin: 0;
76+
}
77+
78+
.workspace-error-modal__cta {
79+
display: flex;
80+
justify-content: center;
81+
margin: 1.5rem 0;
82+
}
83+
84+
.workspace-error-modal__primary-button {
85+
display: inline-flex;
86+
align-items: center;
87+
justify-content: center;
88+
gap: 0.5rem;
89+
padding: 0.875rem 2rem;
90+
background: #2e5bff;
91+
color: white;
92+
text-decoration: none;
93+
font-size: 16px;
94+
font-weight: 600;
95+
border-radius: 8px;
96+
transition: all 0.2s;
97+
box-shadow: 0 2px 4px rgba(46, 91, 255, 0.2);
98+
99+
&:hover {
100+
background: #1e40af;
101+
box-shadow: 0 4px 8px rgba(46, 91, 255, 0.3);
102+
transform: translateY(-1px);
103+
}
104+
105+
&:active {
106+
transform: translateY(0);
107+
}
108+
}
109+
110+
.workspace-error-modal__steps {
111+
background: #f8f9fa;
112+
padding: 1.5rem;
113+
border-radius: 8px;
114+
border-left: 4px solid #2e5bff;
115+
116+
h3 {
117+
margin: 0 0 1rem 0;
118+
font-size: 16px;
119+
font-weight: 600;
120+
color: #141414;
121+
}
122+
123+
ol {
124+
margin: 0;
125+
padding-left: 1.5rem;
126+
127+
li {
128+
margin-bottom: 0.5rem;
129+
line-height: 1.6;
130+
color: #444;
131+
132+
&:last-child {
133+
margin-bottom: 0;
134+
}
135+
}
136+
}
137+
}
138+
139+
.workspace-error-modal__support {
140+
display: flex;
141+
flex-direction: column;
142+
gap: 0.75rem;
143+
padding-top: 1rem;
144+
border-top: 1px solid #e0e0e0;
145+
146+
p {
147+
margin: 0;
148+
font-weight: 600;
149+
color: #141414;
150+
}
151+
}
152+
153+
.workspace-error-modal__link {
154+
display: inline-flex;
155+
align-items: center;
156+
gap: 0.5rem;
157+
color: #2e5bff;
158+
text-decoration: none;
159+
font-size: 14px;
160+
font-weight: 500;
161+
transition: color 0.2s;
162+
163+
&:hover {
164+
color: #1e40af;
165+
text-decoration: underline;
166+
}
167+
}
168+
169+
.workspace-error-modal__actions {
170+
display: flex;
171+
justify-content: center;
172+
margin-top: 2rem;
173+
padding-top: 1.5rem;
174+
border-top: 1px solid #e0e0e0;
175+
176+
button {
177+
min-width: 120px;
178+
}
179+
}
180+
181+
@media (max-width: 640px) {
182+
.workspace-error-modal {
183+
padding: 1.5rem;
184+
}
185+
186+
.workspace-error-modal__header h2 {
187+
font-size: 20px;
188+
}
189+
}

0 commit comments

Comments
 (0)