Skip to content
Open
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
5 changes: 2 additions & 3 deletions frontend/src/components/inputs/BooleanInput/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,8 @@ const BooleanInput = ({ value, onChange, alignCenter = false }) => {
return (
<Box>
<RadioGroup
className={`flex flex-row flex-wrap ${
alignCenter ? 'justify-center' : 'justify-start'
}`}
row
sx={{ justifyContent: alignCenter ? 'center' : 'start' }}
aria-label="yes-no"
value={value}
onChange={handleChange}
Expand Down
63 changes: 43 additions & 20 deletions frontend/src/components/inputs/BottomBar.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useState, useCallback } from 'react'
import {
Box,
Grid,
Grid2 as Grid,
CircularProgress,
ButtonBase,
Typography,
Expand All @@ -11,10 +11,34 @@ import {
ListItemText,
} from '@mui/material'
import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline'
import { styled } from '@mui/material/styles'
import { isArray } from 'lodash-es'

import Button from 'components/generic/Button'
import BlockExitIfDirty from 'components/inputs/BlockExitIfDirty/index'
import { isArray } from 'lodash-es'
import clsx from 'clsx'

const SIDEBAR_WIDTH = '300px'

const Wrapper = styled(Box)(({ theme, dirty, hasErrors }) => ({
display: 'flex',
flexDirection: 'row',
justifyContent: 'flex-end',
alignItems: 'center',
backgroundColor: hasErrors
? theme.palette.error.main
: theme.palette.primary.main,
padding: '1rem',
[theme.breakpoints.up('md')]: {
paddingLeft: `calc(${SIDEBAR_WIDTH} + 1rem)`,
},
position: 'fixed',
transition: 'bottom 0.33s ease',
width: '100%',
bottom: dirty ? 0 : '-100px',
right: 0,
zIndex: 500,
color: 'white',
}))

const BottomBar = ({
errors,
Expand All @@ -36,35 +60,34 @@ const BottomBar = ({
}, [])

const renderErrorsButton = () => (
<ButtonBase className="p-2" onClick={handleShowErrors}>
<Typography variant="button" className="text-white">
<ButtonBase sx={{ padding: '8px' }} onClick={handleShowErrors}>
<Typography sx={{ textTransform: 'uppercase', mr: 1 }}>
{Object.keys(errors).length} errors
</Typography>
<Box mr={1} />
<ErrorOutlineIcon className="text-white" />
<ErrorOutlineIcon />
</ButtonBase>
)

return (
<>
<Box
className={clsx(
'fixed transition-all duration-300 flex flex-row justify-end items-center z-50 w-full p-4',
dirty ? 'bottom-0' : '-bottom-24',
hasErrors ? 'bg-red-500' : 'bg-blue-500',
)}
>
<Wrapper dirty={dirty} hasErrors={hasErrors}>
{loading && (
<Grid container spacing={2}>
<Grid item xs={8}>
<Typography className="font-bold text-white inline-block mr-4 text-lg">
<Grid
container
spacing={2}
sx={{ alignItems: 'center', width: '100%', mr: '1rem' }}
>
<Grid size={{ xs: 10, sm: 11 }}>
<Typography
sx={{ fontWeight: 'bold', fontSize: '1.5rem' }}
>
{loadingText}
</Typography>
</Grid>
<Grid item xs={4}>
<Grid size={{ xs: 2, sm: 1 }}>
<CircularProgress
className="text-white m-2 p-1"
size={24}
sx={{ color: 'inherit' }}
/>
</Grid>
</Grid>
Expand All @@ -81,7 +104,7 @@ const BottomBar = ({
</Button>
)}
{!loading && hasErrors && renderErrorsButton()}
</Box>
</Wrapper>
{dirty && <BlockExitIfDirty dirty={dirty} />}
<Popover
open={showErrors}
Expand Down
23 changes: 19 additions & 4 deletions frontend/src/components/inputs/DateInput/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useCallback } from 'react'

import { Grid, Box, Typography } from '@mui/material'
import { Grid2 as Grid, Box, Typography } from '@mui/material'
import moment from 'moment'
import Select from 'components/inputs/Select'

Expand Down Expand Up @@ -38,23 +38,38 @@ const DateInput = ({ label, value, onChange, onBlur, disableFutureYears }) => {
<Box>
{label && <Typography variant="subtitle1">{label}</Typography>}
<Grid container spacing={3}>
<Grid item xs={4} md={4}>
<Grid
size={{
xs: 4,
md: 4,
}}
>
<Select
label="Day"
options="day"
value={momentValue ? momentValue.date() : null}
onChange={handleDateChange}
/>
</Grid>
<Grid item xs={8} md={4}>
<Grid
size={{
xs: 8,
md: 4,
}}
>
<Select
label="Month"
options="month"
value={momentValue ? momentValue.month() + 1 : null}
onChange={handleMonthChange}
/>
</Grid>
<Grid item xs={12} md={4}>
<Grid
size={{
xs: 12,
md: 4,
}}
>
<Select
label="Year"
options={disableFutureYears ? 'year' : 'year-future'}
Expand Down
12 changes: 6 additions & 6 deletions frontend/src/components/inputs/EducationInput/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useRef, useMemo, useCallback } from 'react'

import { Universities, Countries } from '@hackjunction/shared'
import { Grid } from '@mui/material'
import { Grid2 as Grid } from '@mui/material'

import TextInput from 'components/inputs/TextInput'
import Select from 'components/inputs/Select'
Expand Down Expand Up @@ -93,7 +93,7 @@ const EducationInput = ({ value = {}, onChange, onBlur, autoFocus }) => {
// console.log('counry here', value, country)
return (
<Grid container spacing={3}>
<Grid item xs={12}>
<Grid size={12}>
<Select
autoFocus={autoFocus}
innerRef={selectEl}
Expand All @@ -106,7 +106,7 @@ const EducationInput = ({ value = {}, onChange, onBlur, autoFocus }) => {
</Grid>
{!fieldsDisabled && (
<>
<Grid item xs={6}>
<Grid size={6}>
<Select
label="Country of study"
placeholder="Choose country"
Expand All @@ -117,7 +117,7 @@ const EducationInput = ({ value = {}, onChange, onBlur, autoFocus }) => {
}
/>
</Grid>
<Grid item xs={6}>
<Grid size={6}>
<Select
disabled={fieldsDisabled}
label="University"
Expand All @@ -134,7 +134,7 @@ const EducationInput = ({ value = {}, onChange, onBlur, autoFocus }) => {
allowCreate
/>
</Grid>
<Grid item xs={6}>
<Grid size={6}>
<TextInput
disabled={fieldsDisabled}
label="Field of study"
Expand All @@ -143,7 +143,7 @@ const EducationInput = ({ value = {}, onChange, onBlur, autoFocus }) => {
onChange={degree => handleChange('degree', degree)}
/>
</Grid>
<Grid item xs={6}>
<Grid size={6}>
<Select
disabled={fieldsDisabled}
label="Graduation year"
Expand Down
135 changes: 84 additions & 51 deletions frontend/src/components/inputs/ImageUpload/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,54 @@
import React, { useState, useCallback } from 'react'
import Upload from 'antd/es/upload'
import { useDispatch, useSelector } from 'react-redux'

import { Box, Typography, CircularProgress } from '@mui/material'
import DeleteIcon from '@mui/icons-material/Delete'
import VisibilityIcon from '@mui/icons-material/Visibility'
import { styled } from '@mui/material/styles'

import * as AuthSelectors from 'reducers/auth/selectors'
import * as SnackbarActions from 'reducers/snackbar/actions'
import clsx from 'clsx'

const EmptyWrapper = styled('div')({
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
})

const ButtonOverlay = styled('div')({
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
background: 'rgba(0,0,0,0.6)',
opacity: 0,
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
transition: 'opacity 0.2s ease',
'&:hover': {
opacity: 1,
},
color: 'white',
})

const ImageButton = styled('div')({
padding: '8px',
display: 'flex',
alignItems: 'center',
gap: '16px',
'&:hover': {
background: 'rgba(255,255,255,0.2)',
},
})

const ImageUpload = ({
value,
Expand Down Expand Up @@ -75,65 +117,56 @@ const ImageUpload = ({
)

const renderLoading = () => (
<Box className="absolute top-0 left-0 w-full h-full flex flex-col justify-center items-center cursor-pointer bg-gray-200">
<CircularProgress size={24} className="text-black" />
</Box>
<EmptyWrapper>
<CircularProgress size={24} />
</EmptyWrapper>
)

const renderEmpty = () => (
<EmptyWrapper>
<Typography>Click or drag a file to upload</Typography>
</EmptyWrapper>
)

const renderImage = () => (
<Box className="relative w-full h-full">
<img
className={clsx(
'absolute top-0 left-0 w-full h-full object-contain',
{
'object-contain': resizeMode === 'contain',
'object-cover': resizeMode === 'cover',
},
)}
<>
<Box
component="img"
sx={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
objectFit: resizeMode,
}}
src={value.url}
alt="upload"
/>
<Box className="absolute top-0 left-0 w-full h-full bg-black bg-opacity-60 flex flex-col justify-center items-center opacity-0 transition-opacity duration-200 hover:opacity-100 cursor-pointer">
<Box
className="flex flex-row items-center p-2 hover:bg-white hover:bg-opacity-20"
onClick={handleRemove}
>
<DeleteIcon className="text-white" />
<Box p={1} />
<Typography
variant="button"
className="text-white select-none"
>
Remove image
</Typography>
</Box>
<Box
className="flex flex-row items-center p-2 hover:bg-white hover:bg-opacity-20"
onClick={() => window.open(value.url, '_blank')}
>
<VisibilityIcon className="text-white" />
<Box p={1} />
<Typography
variant="button"
className="text-white select-none"
>
View original
</Typography>
</Box>
</Box>
</Box>
)

const renderEmpty = () => (
<Box className="absolute top-0 left-0 w-full h-full flex flex-col justify-center items-center cursor-pointer bg-gray-200">
<Typography className="text-center text-black select-none">
Click or drag a file to upload
</Typography>
</Box>
<ButtonOverlay>
<ImageButton onClick={handleRemove}>
<DeleteIcon />
<Typography variant="button">Remove image</Typography>
</ImageButton>
<ImageButton onClick={() => window.open(value.url, '_blank')}>
<VisibilityIcon />
<Typography variant="button">View original</Typography>
</ImageButton>
</ButtonOverlay>
</>
)

return (
<Box className="relative w-full h-full bg-gray-100">
<Box
sx={{
backgroundColor: '#f7fafc',
width: '100%',
height: '100%',
position: 'relative',
cursor: 'pointer',
userSelect: 'none',
}}
>
<Upload
name="image"
listType="picture"
Expand Down
Loading