Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ jobs:
with:
args: --acl public-read --follow-symlinks
env:
AWS_S3_BUCKET: ol-mitopen-app-storage-production
AWS_S3_BUCKET: ol-mitlearn-app-storage-production
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID_PROD }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY_PROD }}
SOURCE_DIR: "frontends/mit-learn/build" # optional: defaults to entire repository
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-candidate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ jobs:
with:
args: --acl public-read --follow-symlinks
env:
AWS_S3_BUCKET: ol-mitopen-app-storage-rc
AWS_S3_BUCKET: ol-mitlearn-app-storage-rc
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID_RC }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY_RC }}
SOURCE_DIR: "frontends/mit-learn/build" # optional: defaults to entire repository
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,12 @@ any emails sent from the app will be delivered to you.

### Loading fixture files

Run the following to load platforms, departments, and offers. This populates the database with the fixture files contained in [learning_resources/fixtures](learning_resources/fixtures). Note that you will first need to run the Django models to schema migrations detailed in the [Handbook Initial Setup](https://mitodl.github.io/handbook/how-to/common-web-app-guide.html#3-create-database-tables-from-the-django-models) step. This is already done for you when bringing up your local (development) environment.
Run the following to load platforms, departments, and offers. This populates the database with the fixture files contained in [learning_resources/fixtures](learning_resources/fixtures). Note that you will first need to run the Django models to schema migrations detailed in the [Handbook Initial Setup](https://mitodl.github.io/handbook/how-to/common-web-app-guide.html#3-create-database-tables-from-the-django-models) step.

```bash
# Note!
# This is already done for you when bringing up your local (development)
# environment.
docker compose run --rm web python manage.py loaddata platforms departments offered_by
```

Expand Down
8 changes: 8 additions & 0 deletions RELEASE.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
Release Notes
=============

Version 0.17.8
--------------

- search box adornment buttons should be 56px wide on mobile (#1457)
- homepage hero search updates (#1454)
- Fix departments and schools fixtures (#1453)
- Renaming the s3 buckets used for storing the app. (#1455)

Version 0.17.7 (Released August 21, 2024)
--------------

Expand Down
150 changes: 69 additions & 81 deletions frontends/mit-learn/src/pages/HomePage/HeroSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,58 @@ import type { ChipLinkProps } from "ol-components"
import { SearchInput, SearchInputProps } from "./SearchInput"
import { ABOUT } from "@/common/urls"
import { NON_DEGREE_LEARNING_FRAGMENT_IDENTIFIER } from "../AboutPage/AboutPage"
import {
RiAddBoxLine,
RiAwardLine,
RiSearch2Line,
RiThumbUpLine,
RiTimeLine,
RiVerifiedBadgeLine,
} from "@remixicon/react"

type SearchChip = {
label: string
href: string
variant?: ChipLinkProps["variant"]
icon?: React.ReactElement
}

const SEARCH_CHIPS: SearchChip[] = [
{
label: "New",
label: "Recently Added",
href: "/search?sortby=new",
variant: "outlined",
variant: "outlinedWhite",
icon: <RiTimeLine />,
},
{
label: "Popular",
href: "/search?sortby=-views",
variant: "outlinedWhite",
icon: <RiThumbUpLine />,
},
{
label: "Upcoming",
href: "/search?sortby=upcoming",
variant: "outlinedWhite",
icon: <RiAddBoxLine />,
},
{
label: "Free",
href: "/search?free=true",
variant: "outlinedWhite",
icon: <RiVerifiedBadgeLine />,
},
{
label: "With Certificate",
href: "/search?certification=true",
variant: "outlinedWhite",
icon: <RiAwardLine />,
},
{
label: "Explore All",
href: "/search/",
variant: "gray",
icon: <RiSearch2Line />,
},
]

Expand Down Expand Up @@ -70,44 +94,16 @@ const ImageContainer = styled.div(({ theme }) => ({
},
}))

const SquaredChip = styled(ChipLink, {
shouldForwardProp: (propName) => !["noBorder", "grow"].includes(propName),
})<{ noBorder?: boolean; grow?: boolean }>(({ noBorder, theme, grow }) => [
{
borderRadius: "4px",
[theme.breakpoints.down("sm")]: {
...theme.typography.body4,
padding: "4px 0px",
},
},
grow && {
[theme.breakpoints.down("sm")]: {
flex: 1,
height: "32px",
},
},
noBorder && {
"&:not(:hover)": {
borderColor: "white",
},
},
])

const ControlsContainer = styled.div(({ theme }) => ({
marginTop: "24px",
display: "flex",
width: "100%",
flexDirection: "column",
alignItems: "flex-start",
justifyContent: "center",
gap: "20px",
padding: "24px",
backgroundColor: theme.custom.colors.white,
borderRadius: "8px",
boxShadow:
"0px 2px 4px 0px rgba(37, 38, 43, 0.10), 0px 2px 4px 0px rgba(37, 38, 43, 0.10)",
[theme.breakpoints.down("sm")]: {
padding: "12px",
marginTop: "12px",
padding: "0",
gap: "16px",
},
[theme.breakpoints.up("sm")]: {
Expand All @@ -116,35 +112,41 @@ const ControlsContainer = styled.div(({ theme }) => ({
},
},
}))
const LinksContainer = styled.div(({ theme }) => ({
width: "100%",
display: "flex",
flexDirection: "row",
flexWrap: "wrap",
gap: "12px",
justifyContent: "space-between",

const BrowseByTopicContainer = styled.div(({ theme }) => ({
marginTop: "16px",
marginBottom: "24px",
[theme.breakpoints.down("sm")]: {
flexDirection: "column",
marginTop: "0",
},
}))
const TrenderingContainer = styled.div(({ theme }) => ({
display: "flex",
flexDirection: "row",
alignItems: "center",
flexWrap: "wrap",

const BrowseByTopicText = styled(Typography)(({ theme }) => ({
color: theme.custom.colors.silverGrayDark,
...theme.typography.body2,
[theme.breakpoints.down("sm")]: {
gap: "8px",
...theme.typography.body3,
},
}))
const BrowseContainer = styled.div(({ theme }) => ({

const TopicLink = styled(Link)({
textDecoration: "underline",
})

const StyledChipLink = styled(ChipLink)(({ theme, variant }) => [
variant === "outlinedWhite" ?? {
borderColor: theme.custom.colors.lightGray2,
color: theme.custom.colors.silverGrayDark,
},
])

const TrendingContainer = styled.div({
display: "flex",
flexDirection: "row",
alignItems: "center",
flexWrap: "wrap",
gap: "8px",

[theme.breakpoints.down("sm")]: {
flex: 1,
},
}))
})

const BoldLink = styled(Link)(({ theme }) => ({
...theme.typography.subtitle1,
Expand Down Expand Up @@ -185,50 +187,36 @@ const HeroSearch: React.FC = () => {
</Typography>
<ControlsContainer>
<SearchInput
placeholder="Search for courses, programs, learning, and teaching materials"
placeholder="Search for courses, programs, and learning materials..."
size="hero"
fullWidth
value={searchText}
onChange={onSearchChange}
onClear={onSearchClear}
onSubmit={onSearchSubmit}
/>
<LinksContainer>
<TrenderingContainer>
<Typography
sx={{ marginRight: "8px" }}
typography={{ xs: "subtitle4", md: "subtitle3" }}
>
Trending
</Typography>
<div>
<BrowseByTopicContainer>
<BrowseByTopicText>
or browse by{" "}
<TopicLink href="/topics/" color="red">
Topic
</TopicLink>
</BrowseByTopicText>
</BrowseByTopicContainer>
<TrendingContainer>
{SEARCH_CHIPS.map((chip) => (
<SquaredChip
noBorder
<StyledChipLink
key={chip.label}
variant={chip.variant}
size="medium"
label={chip.label}
href={chip.href}
{...(chip.icon && { icon: chip.icon })}
/>
))}
</TrenderingContainer>
<BrowseContainer>
<SquaredChip
grow
variant="outlined"
size="medium"
label="Browse by Topic"
href="/topics/"
/>
<SquaredChip
grow
variant="filled"
size="medium"
label="Explore All"
href="/search/"
/>
</BrowseContainer>
</LinksContainer>
</TrendingContainer>
</div>
</ControlsContainer>
</TitleAndControls>
<ImageContainer>
Expand Down
4 changes: 2 additions & 2 deletions frontends/mit-learn/src/pages/HomePage/HomePage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,12 @@ describe("Home Page Hero", () => {
setupAPIs()
renderWithProviders(<HomePage />)
const expected = [
{ label: "New", href: "/search?sortby=new" },
{ label: "Topic", href: "/topics/" },
{ label: "Recently Added", href: "/search?sortby=new" },
{ label: "Popular", href: "/search?sortby=-views" },
{ label: "Upcoming", href: "/search?sortby=upcoming" },
{ label: "Free", href: "/search?free=true" },
{ label: "With Certificate", href: "/search?certification=true" },
{ label: "Browse by Topic", href: "/topics/" },
{ label: "Explore All", href: "/search/" },
]
expected.forEach(({ label, href }) => {
Expand Down
68 changes: 49 additions & 19 deletions frontends/mit-learn/src/pages/HomePage/SearchInput.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,38 @@
import React, { useCallback } from "react"
import { RiSearch2Line, RiCloseLine } from "@remixicon/react"
import { Input, AdornmentButton } from "ol-components"
import { Input, AdornmentButton, styled, pxToRem } from "ol-components"
import type { InputProps } from "ol-components"

const StyledInput = styled(Input)(({ theme }) => ({
height: "72px",
borderRadius: "6px",
"&.MuiInputBase-adornedEnd": {
paddingRight: "0 !important",
},
[theme.breakpoints.down("sm")]: {
height: "56px",
gap: "8px",
},
}))

const StyledAdornmentButton = styled(AdornmentButton)(({ theme }) => ({
".MuiInputBase-sizeHero &": {
width: "72px",
height: "100%",
flexShrink: 0,
".MuiSvgIcon-root": {
fontSize: pxToRem(24),
},
[theme.breakpoints.down("sm")]: {
width: "56px",
height: "100%",
".MuiSvgIcon-root": {
fontSize: pxToRem(16),
},
},
},
}))

export interface SearchSubmissionEvent {
target: {
value: string
Expand Down Expand Up @@ -50,7 +80,7 @@ const SearchInput: React.FC<SearchInputProps> = (props) => {
)

return (
<Input
<StyledInput
fullWidth={props.fullWidth}
size={props.size}
inputProps={muiInputProps}
Expand All @@ -62,25 +92,25 @@ const SearchInput: React.FC<SearchInputProps> = (props) => {
value={props.value}
onChange={props.onChange}
onKeyDown={onInputKeyDown}
startAdornment={
<AdornmentButton
aria-label="Search"
className={props.classNameSearch}
onClick={handleSubmit}
>
<RiSearch2Line fontSize="inherit" />
</AdornmentButton>
}
endAdornment={
props.value && (
<AdornmentButton
className={props.classNameClear}
aria-label="Clear search text"
onClick={props.onClear}
<>
{props.value && (
<StyledAdornmentButton
className={props.classNameClear}
aria-label="Clear search text"
onClick={props.onClear}
>
<RiCloseLine />
</StyledAdornmentButton>
)}
<StyledAdornmentButton
aria-label="Search"
className={props.classNameSearch}
onClick={handleSubmit}
>
<RiCloseLine />
</AdornmentButton>
)
<RiSearch2Line fontSize="inherit" />
</StyledAdornmentButton>
</>
}
/>
)
Expand Down
Loading