Lk/update responsive view (#58)

This commit is contained in:
leangseu-edx
2022-10-31 13:29:24 -04:00
committed by GitHub
parent 41df13b059
commit 0badf690a6
23 changed files with 485 additions and 301 deletions

View File

@@ -2,6 +2,10 @@
.course-card {
.card {
.pgn__card-wrapper-image-cap.vertical {
display: flex;
min-height: $card-image-vertical-max-height;
}
.pgn__card-image-cap {
border-bottom-left-radius: 0 !important;
}
@@ -11,6 +15,9 @@
.pgn__card-header-content {
margin-top: 1.5rem;
}
.pgn__card-footer .pgn__action-row {
white-space: nowrap;
}
.course-card-verify-ribbon-container {
width: 100%;

View File

@@ -50,7 +50,7 @@ export const CertificateBanner = ({ cardId }) => {
if (isArchived) {
return (
<Banner variant="warning">
{formatMessage(messages.notEligibleForCert)}.
{formatMessage(messages.notEligibleForCert)}
{' '}
<Hyperlink destination={progressUrl}>{formatMessage(messages.viewGrades)}</Hyperlink>
</Banner>

View File

@@ -101,7 +101,6 @@ exports[`CertificateBanner snapshot not passing and has finished 1`] = `
variant="warning"
>
You are not eligible for a certificate.
.
<Hyperlink
destination="progressUrl"

View File

@@ -22,7 +22,7 @@ export const CourseCardContent = ({ cardId, orientation }) => {
const { isVerified } = appHooks.useCardEnrollmentData(cardId);
return (
<>
<a className="pgn__card-wrapper-image-cap horizontal overflow-visible" href={homeUrl}>
<a className={`pgn__card-wrapper-image-cap overflow-visible ${orientation}`} href={homeUrl}>
<img
className="pgn__card-image-cap"
src={bannerImgSrc}

View File

@@ -26,15 +26,14 @@ exports[`CourseCardMenu enrolled, share enabled, email setting enable snapshot 1
>
Email settings
</Dropdown.Item>
<Dropdown.Item>
<TwitterShareButton
className="w-100 text-left"
title="I'm taking test-course-name online with twitter-social-brand. Check it out!"
url="twitter-share-url"
>
Share to Twitter
</TwitterShareButton>
</Dropdown.Item>
<TwitterShareButton
className="pgn__dropdown-item dropdown-item"
resetButtonStyle={false}
title="I'm taking test-course-name online with twitter-social-brand. Check it out!"
url="twitter-share-url"
>
Share to Twitter
</TwitterShareButton>
</Dropdown.Menu>
</Dropdown>
<UnenrollConfirmModal
@@ -76,15 +75,14 @@ exports[`CourseCardMenu masquerading snapshot 1`] = `
>
Email settings
</Dropdown.Item>
<Dropdown.Item>
<TwitterShareButton
className="w-100 text-left"
title="I'm taking test-course-name online with twitter-social-brand. Check it out!"
url="twitter-share-url"
>
Share to Twitter
</TwitterShareButton>
</Dropdown.Item>
<TwitterShareButton
className="pgn__dropdown-item dropdown-item"
resetButtonStyle={false}
title="I'm taking test-course-name online with twitter-social-brand. Check it out!"
url="twitter-share-url"
>
Share to Twitter
</TwitterShareButton>
</Dropdown.Menu>
</Dropdown>
<UnenrollConfirmModal

View File

@@ -71,18 +71,17 @@ export const CourseCardMenu = ({ cardId }) => {
)}
*/}
{twitter.isEnabled && (
<Dropdown.Item>
<ReactShare.TwitterShareButton
url={twitter.shareUrl}
title={formatMessage(messages.shareQuote, {
courseName,
socialBrand: twitter.socialBrand,
})}
className="w-100 text-left"
>
{formatMessage(messages.shareToTwitter)}
</ReactShare.TwitterShareButton>
</Dropdown.Item>
<ReactShare.TwitterShareButton
url={twitter.shareUrl}
title={formatMessage(messages.shareQuote, {
courseName,
socialBrand: twitter.socialBrand,
})}
resetButtonStyle={false}
className="pgn__dropdown-item dropdown-item"
>
{formatMessage(messages.shareToTwitter)}
</ReactShare.TwitterShareButton>
)}
</Dropdown.Menu>
</Dropdown>

View File

@@ -3,7 +3,7 @@
exports[`CourseCardContent snapshot not verified 1`] = `
<Fragment>
<a
className="pgn__card-wrapper-image-cap horizontal overflow-visible"
className="pgn__card-wrapper-image-cap overflow-visible vertical"
href="test-home-url"
>
<img
@@ -55,7 +55,7 @@ exports[`CourseCardContent snapshot not verified 1`] = `
exports[`CourseCardContent snapshot orientation horizontal 1`] = `
<Fragment>
<a
className="pgn__card-wrapper-image-cap horizontal overflow-visible"
className="pgn__card-wrapper-image-cap overflow-visible horizontal"
href="test-home-url"
>
<img
@@ -125,7 +125,7 @@ exports[`CourseCardContent snapshot orientation horizontal 1`] = `
exports[`CourseCardContent snapshot orientation vertical 1`] = `
<Fragment>
<a
className="pgn__card-wrapper-image-cap horizontal overflow-visible"
className="pgn__card-wrapper-image-cap overflow-visible vertical"
href="test-home-url"
>
<img

View File

@@ -1,20 +1,68 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`CourseList snapshots collapsed with multiple courses and pages 1`] = `
<div
className="course-list-container"
>
<div
className="course-list-heading-container"
>
<h2
className="course-list-title"
>
My Courses
</h2>
<div
className="course-filter-controls-container"
>
<CourseFilterControls />
</div>
</div>
<div
id="course-list-active-filters-container"
>
<ActiveCourseFilters />
</div>
<div
className="d-flex flex-column flex-grow-1"
>
<CourseCard
cardId="foo"
key="foo"
/>
<CourseCard
cardId="bar"
key="bar"
/>
<CourseCard
cardId="baz"
key="baz"
/>
<Pagination
className="mx-auto"
onPageSelect={[MockFunction setPageNumber]}
pageCount={3}
paginationLabel="Course List"
variant="reduced"
/>
</div>
</div>
`;
exports[`CourseList snapshots with filters 1`] = `
<div
className="course-list-container"
>
<div
id="course-list-heading-container"
className="course-list-heading-container"
>
<h2
className="mb-4.5"
className="course-list-title"
>
My Courses
</h2>
<div
className="text-right"
id="course-filter-controls-container"
className="course-filter-controls-container"
>
<CourseFilterControls
abitary="filter"
@@ -39,16 +87,15 @@ exports[`CourseList snapshots with multiple courses and pages 1`] = `
className="course-list-container"
>
<div
id="course-list-heading-container"
className="course-list-heading-container"
>
<h2
className="mb-4.5"
className="course-list-title"
>
My Courses
</h2>
<div
className="text-right"
id="course-filter-controls-container"
className="course-filter-controls-container"
>
<CourseFilterControls />
</div>
@@ -84,16 +131,15 @@ exports[`CourseList snapshots with no filters 1`] = `
className="course-list-container"
>
<div
id="course-list-heading-container"
className="course-list-heading-container"
>
<h2
className="mb-4.5"
className="course-list-title"
>
My Courses
</h2>
<div
className="text-right"
id="course-filter-controls-container"
className="course-filter-controls-container"
>
<CourseFilterControls />
</div>

View File

@@ -1,7 +1,7 @@
import React from 'react';
import { useDispatch } from 'react-redux';
import { useCheckboxSetValues } from '@edx/paragon';
import { useCheckboxSetValues, useWindowSize, breakpoints } from '@edx/paragon';
import { StrictDict } from 'utils';
import { actions, hooks as appHooks } from 'data/redux';
@@ -9,6 +9,11 @@ import { ListPageSize, SortKeys } from 'data/constants/app';
import * as module from './hooks';
export const useIsCollapsed = () => {
const { width } = useWindowSize();
return width < breakpoints.medium.maxWidth;
};
export const state = StrictDict({
sortBy: (val) => React.useState(val), // eslint-disable-line
});

View File

@@ -9,7 +9,7 @@ import {
} from 'containers/CourseFilterControls';
import CourseCard from 'containers/CourseCard';
import { useCourseListData } from './hooks';
import { useCourseListData, useIsCollapsed } from './hooks';
import messages from './messages';
@@ -24,11 +24,12 @@ export const CourseList = () => {
showFilters,
visibleList,
} = useCourseListData();
const isCollapsed = useIsCollapsed();
return (
<div className="course-list-container">
<div id="course-list-heading-container">
<h2 className="mb-4.5">{formatMessage(messages.myCourses)}</h2>
<div id="course-filter-controls-container" className="text-right">
<div className="course-list-heading-container">
<h2 className="course-list-title">{formatMessage(messages.myCourses)}</h2>
<div className="course-filter-controls-container">
<CourseFilterControls {...filterOptions} />
</div>
</div>
@@ -43,7 +44,7 @@ export const CourseList = () => {
))}
{numPages > 1 && (
<Pagination
variant="secondary"
variant={isCollapsed ? 'reduced' : 'secondary'}
paginationLabel="Course List"
className="mx-auto"
pageCount={numPages}

View File

@@ -1,6 +1,15 @@
#course-list-heading-container {
@import "@edx/paragon/scss/core/core";
.course-list-heading-container {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.course-list-title {
font-size: $h2-font-size;
margin: map-get($spacers, 3) 0;
}
.course-list-loading {
@@ -8,4 +17,26 @@
justify-content: center;
align-items: center;
height: 100%;
}
}
.course-filter-controls-container {
text-align: right;
align-self: center;
}
@include media-breakpoint-down(md) {
.course-list-heading-container {
flex-direction: column-reverse;
align-items: flex-start;
}
.course-filter-controls-container {
text-align: left;
align-self: flex-start;
}
.course-list-title {
font-size: $h3-font-size;
margin: map-get($spacers, 2) 0;
}
}

View File

@@ -1,10 +1,11 @@
import { shallow } from 'enzyme';
import CourseList from '.';
import { useCourseListData } from './hooks';
import { useCourseListData, useIsCollapsed } from './hooks';
jest.mock('./hooks', () => ({
useCourseListData: jest.fn(),
useIsCollapsed: jest.fn(),
}));
jest.mock('containers/CourseCard', () => 'CourseCard');
@@ -21,6 +22,7 @@ describe('CourseList', () => {
showFilters: false,
visibleList: [],
};
useIsCollapsed.mockReturnValue(false);
const createWrapper = (courseListData) => {
useCourseListData.mockReturnValueOnce({
...defaultCourseListData,
@@ -50,5 +52,14 @@ describe('CourseList', () => {
});
expect(wrapper).toMatchSnapshot();
});
test('collapsed with multiple courses and pages', () => {
useIsCollapsed.mockReturnValueOnce(true);
const wrapper = createWrapper({
visibleList: [{ cardId: 'foo' }, { cardId: 'bar' }, { cardId: 'baz' }],
numPages: 3,
showFilters: true,
});
expect(wrapper).toMatchSnapshot();
});
});
});

View File

@@ -7,13 +7,17 @@ import hooks from './hooks';
export const columnConfig = {
courseList: {
xs: { span: 12, offset: 0 },
sm: { span: 8, offset: 2 },
md: { span: 12, offset: 0 },
lg: { span: 10, offset: 1 },
sm: { span: 12, offset: 0 },
md: { span: 10, offset: 1 },
lg: { span: 12, offset: 0 },
xl: { span: 8, offset: 0 },
},
sidebar: { md: 12, xl: 4 },
sidebar: {
sm: { span: 12, offset: 0 },
md: { span: 10, offset: 1 },
lg: { span: 12, offset: 0 },
xl: { span: 4, offset: 0 },
},
};
export const LoadedView = () => {
@@ -22,11 +26,11 @@ export const LoadedView = () => {
return (
<Container fluid size="xl">
<Row>
<Col {...columnConfig.courseList} className="p-0 px-4">
<Col {...columnConfig.courseList} className="course-list-column">
<CourseList />
</Col>
<Col {...columnConfig.sidebar} className="p-0 pr-4 pl-1">
{!isCollapsed && (<h2 className="mb-4.5 display-block">&nbsp;</h2>)}
<Col {...columnConfig.sidebar} className="sidebar-column">
{!isCollapsed && (<h2 className="course-list-title">&nbsp;</h2>)}
<WidgetSidebar />
</Col>
</Row>

View File

@@ -7,23 +7,23 @@ exports[`LoadedView collapsed snapshot 1`] = `
>
<Row>
<Col
className="p-0 px-4"
className="course-list-column"
lg={
Object {
"offset": 1,
"span": 10,
}
}
md={
Object {
"offset": 0,
"span": 12,
}
}
md={
Object {
"offset": 1,
"span": 10,
}
}
sm={
Object {
"offset": 2,
"span": 8,
"offset": 0,
"span": 12,
}
}
xl={
@@ -32,19 +32,35 @@ exports[`LoadedView collapsed snapshot 1`] = `
"span": 8,
}
}
xs={
>
<CourseList />
</Col>
<Col
className="sidebar-column"
lg={
Object {
"offset": 0,
"span": 12,
}
}
>
<CourseList />
</Col>
<Col
className="p-0 pr-4 pl-1"
md={12}
xl={4}
md={
Object {
"offset": 1,
"span": 10,
}
}
sm={
Object {
"offset": 0,
"span": 12,
}
}
xl={
Object {
"offset": 0,
"span": 4,
}
}
>
<WidgetSidebar />
</Col>
@@ -59,23 +75,23 @@ exports[`LoadedView not collapsed snapshot 1`] = `
>
<Row>
<Col
className="p-0 px-4"
className="course-list-column"
lg={
Object {
"offset": 1,
"span": 10,
}
}
md={
Object {
"offset": 0,
"span": 12,
}
}
md={
Object {
"offset": 1,
"span": 10,
}
}
sm={
Object {
"offset": 2,
"span": 8,
"offset": 0,
"span": 12,
}
}
xl={
@@ -84,22 +100,38 @@ exports[`LoadedView not collapsed snapshot 1`] = `
"span": 8,
}
}
xs={
>
<CourseList />
</Col>
<Col
className="sidebar-column"
lg={
Object {
"offset": 0,
"span": 12,
}
}
>
<CourseList />
</Col>
<Col
className="p-0 pr-4 pl-1"
md={12}
xl={4}
md={
Object {
"offset": 1,
"span": 10,
}
}
sm={
Object {
"offset": 0,
"span": 12,
}
}
xl={
Object {
"offset": 0,
"span": 4,
}
}
>
<h2
className="mb-4.5 display-block"
className="course-list-title"
>
 
</h2>

View File

@@ -0,0 +1,22 @@
@import "@edx/paragon/scss/core/core";
.course-list-column {
padding: 0 map-get($spacers, 4);
margin: auto;
}
.sidebar-column {
padding: 0 map-get($spacers, 3) 0 map-get($spacers, 1);
}
@include media-breakpoint-down(lg) {
.sidebar-column {
// grid are inheriting dir="ltr" from the body, so we need to override it
[dir=ltr] & {
padding: 0 map-get($spacers, 3);
}
[dir=rtl] & {
padding: 0 map-get($spacers, 3);
}
}
}

View File

@@ -36,9 +36,6 @@ exports[`LearnerDashboardHeader snapshots with collapsed 1`] = `
</header>
</div>
<MasqueradeBar />
<hr
className="mt-0"
/>
</Fragment>
`;
@@ -77,8 +74,5 @@ exports[`LearnerDashboardHeader snapshots without collapsed 1`] = `
/>
</div>
<MasqueradeBar />
<hr
className="mt-0"
/>
</Fragment>
`;

View File

@@ -53,7 +53,6 @@ export const LearnerDashboardHeader = () => {
{!isCollapsed && <GreetingBanner size="large" />}
</div>
<MasqueradeBar />
<hr className="mt-0" />
</>
);
};

View File

@@ -1,178 +1,202 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`MasqueradeBar snapshot can masquerade 1`] = `
<Form
className="masquerade-bar"
<div
className="w-100 shadow-sm px-2"
>
<FormLabel
className="masquerade-form-label"
inline={true}
<Form
className="masquerade-bar col-sm-12 col-md-10 col-12"
>
<Icon
src={[MockFunction icons.PersonSearch]}
/>
View as:
</FormLabel>
<FormGroup
className="masquerade-form-input"
isInvalid={false}
>
<FormControl
floatingLabel="Student username or email"
onChange={[MockFunction handleMasqueradeInputChange]}
value=""
/>
</FormGroup>
<StatefulButton
disabled={true}
labels={
Object {
"default": "Submit",
<FormLabel
className="masquerade-form-label"
inline={true}
>
<Icon
src={[MockFunction icons.PersonSearch]}
/>
View as:
</FormLabel>
<FormGroup
className="masquerade-form-input"
isInvalid={false}
>
<FormControl
floatingLabel="Username or email"
onChange={[MockFunction handleMasqueradeInputChange]}
value=""
/>
</FormGroup>
<StatefulButton
className="mr-3"
disabled={true}
labels={
Object {
"default": "Submit",
}
}
}
state="default"
type="submit"
variant="brand"
/>
</Form>
state="default"
type="submit"
variant="brand"
/>
</Form>
</div>
`;
exports[`MasqueradeBar snapshot can masquerade with input 1`] = `
<Form
className="masquerade-bar"
<div
className="w-100 shadow-sm px-2"
>
<FormLabel
className="masquerade-form-label"
inline={true}
<Form
className="masquerade-bar col-sm-12 col-md-10 col-12"
>
<Icon
src={[MockFunction icons.PersonSearch]}
/>
View as:
</FormLabel>
<FormGroup
className="masquerade-form-input"
isInvalid={false}
>
<FormControl
floatingLabel="Student username or email"
onChange={[MockFunction handleMasqueradeInputChange]}
value="test"
/>
</FormGroup>
<StatefulButton
disabled={false}
labels={
Object {
"default": "Submit",
<FormLabel
className="masquerade-form-label"
inline={true}
>
<Icon
src={[MockFunction icons.PersonSearch]}
/>
View as:
</FormLabel>
<FormGroup
className="masquerade-form-input"
isInvalid={false}
>
<FormControl
floatingLabel="Username or email"
onChange={[MockFunction handleMasqueradeInputChange]}
value="test"
/>
</FormGroup>
<StatefulButton
className="mr-3"
disabled={false}
labels={
Object {
"default": "Submit",
}
}
}
state="default"
type="submit"
variant="brand"
/>
</Form>
state="default"
type="submit"
variant="brand"
/>
</Form>
</div>
`;
exports[`MasqueradeBar snapshot cannot masquerade 1`] = `""`;
exports[`MasqueradeBar snapshot is masquerading failed with error 1`] = `
<Form
className="masquerade-bar"
<div
className="w-100 shadow-sm px-2"
>
<FormLabel
className="masquerade-form-label"
inline={true}
<Form
className="masquerade-bar col-sm-12 col-md-10 col-12"
>
<Icon
src={[MockFunction icons.PersonSearch]}
/>
View as:
</FormLabel>
<FormGroup
className="masquerade-form-input"
isInvalid={true}
>
<FormControl
floatingLabel="Student username or email"
onChange={[MockFunction handleMasqueradeInputChange]}
value=""
/>
<FormControlFeedback
hasIcon={false}
type="invalid"
/>
</FormGroup>
<StatefulButton
disabled={true}
labels={
Object {
"default": "Submit",
<FormLabel
className="masquerade-form-label"
inline={true}
>
<Icon
src={[MockFunction icons.PersonSearch]}
/>
View as:
</FormLabel>
<FormGroup
className="masquerade-form-input"
isInvalid={true}
>
<FormControl
floatingLabel="Username or email"
onChange={[MockFunction handleMasqueradeInputChange]}
value=""
/>
<FormControlFeedback
hasIcon={false}
type="invalid"
/>
</FormGroup>
<StatefulButton
className="mr-3"
disabled={true}
labels={
Object {
"default": "Submit",
}
}
}
state="default"
type="submit"
variant="brand"
/>
</Form>
state="default"
type="submit"
variant="brand"
/>
</Form>
</div>
`;
exports[`MasqueradeBar snapshot is masquerading pending 1`] = `
<Form
className="masquerade-bar"
<div
className="w-100 shadow-sm px-2"
>
<FormLabel
className="masquerade-form-label"
inline={true}
<Form
className="masquerade-bar col-sm-12 col-md-10 col-12"
>
<Icon
src={[MockFunction icons.PersonSearch]}
/>
View as:
</FormLabel>
<FormGroup
className="masquerade-form-input"
isInvalid={false}
>
<FormControl
floatingLabel="Student username or email"
onChange={[MockFunction handleMasqueradeInputChange]}
value=""
/>
</FormGroup>
<StatefulButton
disabled={true}
labels={
Object {
"default": "Submit",
<FormLabel
className="masquerade-form-label"
inline={true}
>
<Icon
src={[MockFunction icons.PersonSearch]}
/>
View as:
</FormLabel>
<FormGroup
className="masquerade-form-input"
isInvalid={false}
>
<FormControl
floatingLabel="Username or email"
onChange={[MockFunction handleMasqueradeInputChange]}
value=""
/>
</FormGroup>
<StatefulButton
className="mr-3"
disabled={true}
labels={
Object {
"default": "Submit",
}
}
}
state="pending"
type="submit"
variant="brand"
/>
</Form>
state="pending"
type="submit"
variant="brand"
/>
</Form>
</div>
`;
exports[`MasqueradeBar snapshot is masquerading with input 1`] = `
<Form
className="masquerade-bar"
<div
className="w-100 shadow-sm px-2"
>
<FormLabel
className="masquerade-form-label"
inline={true}
<Form
className="masquerade-bar col-sm-12 col-md-10 col-12"
>
<Icon
src={[MockFunction icons.PersonSearch]}
/>
Viewing as:
</FormLabel>
<Chip
className="masquerade-chip"
iconAfter={[MockFunction icons.Close]}
onClick={[MockFunction handleClearMasquerade]}
>
test
</Chip>
</Form>
<FormLabel
className="masquerade-form-label"
inline={true}
>
<Icon
src={[MockFunction icons.PersonSearch]}
/>
Viewing as:
</FormLabel>
<Chip
className="masquerade-chip"
iconAfter={[MockFunction icons.Close]}
onClick={[MockFunction handleClearMasquerade]}
>
test
</Chip>
</Form>
</div>
`;

View File

@@ -36,52 +36,55 @@ export const MasqueradeBar = () => {
if (!canMasquerade) { return null; }
return (
<Form className="masquerade-bar">
{isMasquerading ? (
<>
<FormLabel inline className="masquerade-form-label">
<Icon src={PersonSearch} />
{formatMessage(messages.ViewingAs)}
</FormLabel>
<Chip
className="masquerade-chip"
iconAfter={Close}
onClick={handleClearMasquerade}
>
{masqueradeInput}
</Chip>
</>
) : (
<>
<FormLabel inline className="masquerade-form-label">
<Icon src={PersonSearch} />
{formatMessage(messages.ViewAs)}
</FormLabel>
<FormGroup isInvalid={isMasqueradingFailed} className="masquerade-form-input">
<FormControl
value={masqueradeInput}
onChange={handleMasqueradeInputChange}
floatingLabel={formatMessage(messages.StudentNameInput)}
<div className="w-100 shadow-sm px-2">
<Form className="masquerade-bar col-sm-12 col-md-10 col-12">
{isMasquerading ? (
<>
<FormLabel inline className="masquerade-form-label">
<Icon src={PersonSearch} />
{formatMessage(messages.ViewingAs)}
</FormLabel>
<Chip
className="masquerade-chip"
iconAfter={Close}
onClick={handleClearMasquerade}
>
{masqueradeInput}
</Chip>
</>
) : (
<>
<FormLabel inline className="masquerade-form-label">
<Icon src={PersonSearch} />
{formatMessage(messages.ViewAs)}
</FormLabel>
<FormGroup isInvalid={isMasqueradingFailed} className="masquerade-form-input">
<FormControl
value={masqueradeInput}
onChange={handleMasqueradeInputChange}
floatingLabel={formatMessage(messages.StudentNameInput)}
/>
{isMasqueradingFailed && (
<FormControlFeedback type="invalid" hasIcon={false}>
{formatMessage(masqueradeErrorMessage)}
</FormControlFeedback>
)}
</FormGroup>
<StatefulButton
disabled={!masqueradeInput.length}
variant="brand"
onClick={handleMasqueradeSubmit(masqueradeInput)}
labels={{
default: formatMessage(messages.SubmitButton),
}}
className="mr-3"
state={isMasqueradingPending ? 'pending' : 'default'}
type="submit"
/>
{isMasqueradingFailed && (
<FormControlFeedback type="invalid" hasIcon={false}>
{formatMessage(masqueradeErrorMessage)}
</FormControlFeedback>
)}
</FormGroup>
<StatefulButton
disabled={!masqueradeInput.length}
variant="brand"
onClick={handleMasqueradeSubmit(masqueradeInput)}
labels={{
default: formatMessage(messages.SubmitButton),
}}
state={isMasqueradingPending ? 'pending' : 'default'}
type="submit"
/>
</>
)}
</Form>
</>
)}
</Form>
</div>
);
};

View File

@@ -4,12 +4,14 @@
display: flex;
align-items: flex-start;
padding: map-get($spacers, 3);
margin-bottom: map-get($spacers, 2);
.masquerade-form-label {
padding: map-get($spacers, 2) map-get($spacers, 3);
display: flex;
align-items: center;
margin-bottom: 0;
white-space: nowrap;
&>.pgn__icon {
margin-right: map-get($spacers, 3);
@@ -26,4 +28,11 @@
padding: map-get($spacers, 2) map-get($spacers, 3);
font-size: $font-size-base;
}
}
@include media-breakpoint-down(md) {
.masquerade-bar {
margin: auto;
padding: map-get($spacers, 3) map-get($spacers, 4);
}
}

View File

@@ -18,7 +18,7 @@ const messages = defineMessages({
},
StudentNameInput: {
id: 'MasqueradeBar.StudentNameInput',
defaultMessage: 'Student username or email',
defaultMessage: 'Username or email',
description: 'Label for the Student Name or email input',
},
NoStudentFound: {

View File

@@ -2,7 +2,7 @@
exports[`WidgetSidebar snapshots default 1`] = `
<div
className="widget-sidebar px-2"
className="widget-sidebar"
>
<div
className="d-flex"

View File

@@ -3,7 +3,7 @@ import React from 'react';
import LookingForChallengeWidget from './widgets/LookingForChallengeWidget';
export const WidgetSidebar = () => (
<div className="widget-sidebar px-2">
<div className="widget-sidebar">
<div className="d-flex">
<LookingForChallengeWidget />
</div>