Skip to content

Commit dee584d

Browse files
OscarFavagithub-actions[bot]Copilotjohnny-quesada-developer
authored
VIDSOL-240: Landing page UI/UX refactor (#255)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <[email protected]> Co-authored-by: Johnny Esteban Quesada <[email protected]>
1 parent 211b85a commit dee584d

File tree

119 files changed

+1704
-838
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

119 files changed

+1704
-838
lines changed

.github/workflows/update-screenshots.yml

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -119,15 +119,23 @@ jobs:
119119
- name: Auto-commit updated screenshots
120120
if: always() && steps.check-update-screenshots.outputs.result == 'true'
121121
run: |
122-
echo "Committing screenshots to "$BRANCH_NAME""
123-
FILES_CHANGED=$(git status --porcelain | awk '{print $2}')
124-
for file in $FILES_CHANGED; do
125-
CONTENT=$(base64 -w 0 "$file")
126-
SHA=$(curl -s -H "Authorization: token $GITHUB_TOKEN" "https://api.github.com/repos/$REPO_NAME/contents/$file?ref=$BRANCH_NAME" | jq -r .sha)
127-
if [ "$SHA" == "null" ]; then
128-
SHA=""
129-
fi
130-
curl -s -X PUT -H "Authorization: token $GITHUB_TOKEN" \
131-
-d "{\"message\":\"Commit screenshot file: $file\", \"content\":\"$CONTENT\", \"branch\":\"$BRANCH_NAME\", \"sha\":\"$SHA\"}" \
132-
"https://api.github.com/repos/$REPO_NAME/contents/$file"
133-
done
122+
echo "Committing screenshots to $BRANCH_NAME"
123+
124+
# Configure git user for the commit
125+
git config user.name "github-actions[bot]"
126+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
127+
128+
# Get changed snapshot PNGs under integration-tests/...-snapshots/
129+
FILES_CHANGED=$(git status --porcelain | awk '$2 ~ /^integration-tests\/tests\/visualComparisons\.spec\.ts-snapshots\/.*\.png$/ {print $2}')
130+
131+
if [ -z "$FILES_CHANGED" ]; then
132+
echo "No snapshot files changed, nothing to commit."
133+
exit 0
134+
fi
135+
136+
echo "Files to commit:"
137+
echo "$FILES_CHANGED"
138+
139+
git add $FILES_CHANGED
140+
git commit -m "Update visual comparison screenshots"
141+
git push origin HEAD:$BRANCH_NAME

frontend/index.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33
<head>
44
<meta charset="UTF-8" />
55
<link rel="icon" href="/images/favicon.ico" />
6+
<link
7+
href="https://fonts.googleapis.com/css2?family=Inter:[email protected]&display=swap"
8+
rel="stylesheet"
9+
/>
610
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
711
<title>Vonage Video React Reference App</title>
812
</head>
913
<body>
10-
<div class="bg-darkGray-100 absolute" id="root"></div>
14+
<div id="root"></div>
1115
<script type="module" src="/src/main.tsx"></script>
1216
</body>
1317
</html>

frontend/src/App.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
22
import './css/App.css';
33
import './css/index.css';
4-
import { CssBaseline, ThemeProvider } from '@mui/material';
4+
import { CssBaseline } from '@mui/material';
5+
import { CustomThemeProvider } from '@Context/Theme/themeContext';
56
import Room from './pages/MeetingRoom/index';
67
import GoodBye from './pages/GoodBye/index';
78
import WaitingRoom from './pages/WaitingRoom';
@@ -12,11 +13,10 @@ import { PublisherProvider } from './Context/PublisherProvider';
1213
import RedirectToWaitingRoom from './components/RedirectToWaitingRoom';
1314
import UnsupportedBrowserPage from './pages/UnsupportedBrowserPage';
1415
import RoomContext from './Context/RoomContext';
15-
import customTheme from './utils/customTheme/customTheme';
1616

1717
const App = () => {
1818
return (
19-
<ThemeProvider theme={customTheme}>
19+
<CustomThemeProvider>
2020
<CssBaseline />
2121
<Router>
2222
<Routes>
@@ -47,7 +47,7 @@ const App = () => {
4747
<Route path="/unsupported-browser" element={<UnsupportedBrowserPage />} />
4848
</Routes>
4949
</Router>
50-
</ThemeProvider>
50+
</CustomThemeProvider>
5151
);
5252
};
5353

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { describe, it, expect } from 'vitest';
2+
import getMuiCustomTheme from './getMuiCustomTheme';
3+
import getTokensByMode from './getTokensByMode';
4+
5+
const customTheme = getMuiCustomTheme({
6+
tokens: getTokensByMode('light'),
7+
});
8+
9+
describe('customTheme', () => {
10+
it('should have palette defined', () => {
11+
expect(customTheme.palette).toBeDefined();
12+
});
13+
14+
it('should have primary color defined', () => {
15+
expect(customTheme.palette.primary.main).toBeDefined();
16+
expect(typeof customTheme.palette.primary.main).toBe('string');
17+
});
18+
19+
it('should have shape with borderRadius as number', () => {
20+
expect(customTheme.shape).toBeDefined();
21+
expect(typeof customTheme.shape.borderRadius).toBe('number');
22+
});
23+
24+
it('should have typography variants defined', () => {
25+
expect(customTheme.typography.h1).toBeDefined();
26+
expect(customTheme.typography.h2).toBeDefined();
27+
expect(customTheme.typography.body1).toBeDefined();
28+
expect(customTheme.typography.body2).toBeDefined();
29+
});
30+
31+
it('should have components with styleOverrides', () => {
32+
expect(customTheme.components).toBeDefined();
33+
expect(customTheme.components?.MuiButton).toBeDefined();
34+
expect(customTheme.components?.MuiButton?.styleOverrides).toBeDefined();
35+
});
36+
37+
it('should have custom palette colors', () => {
38+
const { palette } = customTheme;
39+
expect(palette.tertiary).toBeDefined();
40+
expect(palette.hover).toBeDefined();
41+
expect(palette.disabled).toBeDefined();
42+
});
43+
44+
it('should have text colors defined', () => {
45+
const { text } = customTheme.palette;
46+
expect(text.primary).toBeDefined();
47+
expect(text.secondary).toBeDefined();
48+
expect(text.tertiary).toBeDefined();
49+
expect(text.main).toBeDefined();
50+
});
51+
});
Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
import { createTheme, type PaletteColor, type PaletteColorOptions } from '@mui/material';
2+
import type { ThemeTokens } from './getTokensByMode';
3+
import isDarkMode from './isDarkMode';
4+
5+
// Extend theme options
6+
declare module '@mui/material/styles' {
7+
interface TypeText {
8+
tertiary: string;
9+
main: string;
10+
}
11+
12+
interface Palette {
13+
tertiary: PaletteColor;
14+
hover: PaletteColor;
15+
disabled: PaletteColor;
16+
}
17+
18+
interface PaletteOptions {
19+
tertiary?: PaletteColorOptions;
20+
hover?: PaletteColorOptions;
21+
disabled?: PaletteColorOptions;
22+
}
23+
}
24+
25+
const getMuiCustomTheme = ({ tokens }: { tokens: ThemeTokens }) => {
26+
const buttonSx = {
27+
height: 40, // 40px
28+
textTransform: 'none',
29+
borderRadius: tokens.shapes.borderRadiusMedium,
30+
} as const;
31+
32+
const { colors } = tokens;
33+
34+
return createTheme({
35+
palette: {
36+
mode: isDarkMode() ? 'dark' : 'light',
37+
primary: {
38+
main: colors.primary,
39+
contrastText: colors.onPrimary,
40+
dark: colors.primary,
41+
light: colors.background,
42+
},
43+
secondary: {
44+
main: colors.secondary,
45+
contrastText: colors.onSecondary,
46+
dark: colors.secondary,
47+
light: colors.background,
48+
},
49+
tertiary: {
50+
main: colors.tertiary,
51+
contrastText: colors.onTertiary,
52+
dark: colors.tertiary,
53+
light: colors.background,
54+
},
55+
success: {
56+
main: colors.success,
57+
contrastText: colors.onSuccess,
58+
dark: colors.successHover,
59+
light: colors.background,
60+
},
61+
warning: {
62+
main: colors.warning,
63+
contrastText: colors.onWarning,
64+
dark: colors.warningHover,
65+
light: colors.background,
66+
},
67+
error: {
68+
main: colors.error,
69+
contrastText: colors.onError,
70+
dark: colors.errorHover,
71+
light: colors.background,
72+
},
73+
background: {
74+
default: colors.background,
75+
paper: colors.surface,
76+
},
77+
text: {
78+
primary: colors.textSecondary, // This is the default text color
79+
main: colors.textPrimary, // This is primary color for specific uses
80+
secondary: colors.textSecondary,
81+
tertiary: colors.textTertiary,
82+
},
83+
divider: colors.border,
84+
hover: {
85+
main: colors.primaryHover,
86+
},
87+
disabled: {
88+
main: colors.disabled,
89+
},
90+
},
91+
components: {
92+
MuiButton: {
93+
styleOverrides: {
94+
root: {
95+
...buttonSx,
96+
fontSize: tokens.typography.typeScale.desktop['body-base'].fontSize.value,
97+
lineHeight: tokens.typography.typeScale.desktop['body-base'].lineHeight.value,
98+
fontWeight: tokens.typography.weight['caption-semibold'].value,
99+
},
100+
outlined: {
101+
borderColor: colors.primary,
102+
},
103+
},
104+
},
105+
MuiToolbar: {
106+
styleOverrides: {
107+
root: {
108+
paddingLeft: '0',
109+
paddingRight: '0',
110+
'@media (min-width: 600px)': {
111+
paddingLeft: 0,
112+
paddingRight: 0,
113+
},
114+
},
115+
},
116+
},
117+
MuiAppBar: {
118+
styleOverrides: {
119+
root: {
120+
backgroundColor: colors.surface,
121+
color: colors.onSurface,
122+
},
123+
},
124+
},
125+
MuiPaper: {
126+
styleOverrides: {
127+
root: {
128+
backgroundColor: colors.background,
129+
color: colors.onBackground,
130+
},
131+
},
132+
},
133+
MuiOutlinedInput: {
134+
styleOverrides: {
135+
root: {
136+
backgroundColor: colors.surface,
137+
borderRadius: tokens.shapes.borderRadiusMedium,
138+
backgroundClip: 'padding-box',
139+
},
140+
},
141+
},
142+
MuiInputLabel: {
143+
styleOverrides: {
144+
sizeSmall: {
145+
fontSize: tokens.typography.typeScale.desktop['body-base'].fontSize.value,
146+
lineHeight: tokens.typography.typeScale.desktop['body-base'].lineHeight.value,
147+
},
148+
},
149+
},
150+
MuiFormHelperText: {
151+
styleOverrides: {
152+
root: {
153+
color: colors.onSurface,
154+
},
155+
},
156+
},
157+
MuiTypography: {
158+
styleOverrides: {
159+
h1: createResponsiveTypography(tokens, 'headline', 'headline'),
160+
h2: createResponsiveTypography(tokens, 'subtitle', 'subtitle'),
161+
h3: createResponsiveTypography(tokens, 'heading-1', 'heading-1'),
162+
h4: createResponsiveTypography(tokens, 'heading-2', 'heading-2'),
163+
h5: createResponsiveTypography(tokens, 'heading-3', 'heading-3'),
164+
h6: createResponsiveTypography(tokens, 'heading-4', 'heading-4'),
165+
subtitle1: createResponsiveTypography(
166+
tokens,
167+
'body-extended-semibold',
168+
'body-extended-semibold'
169+
),
170+
subtitle2: createResponsiveTypography(tokens, 'body-base-semibold', 'body-base-semibold'),
171+
body1: createResponsiveTypography(tokens, 'body-extended', 'body-extended'),
172+
body2: createResponsiveTypography(tokens, 'body-base', 'body-base'),
173+
caption: createResponsiveTypography(tokens, 'caption', 'caption'),
174+
},
175+
},
176+
},
177+
typography: {
178+
fontFamily: tokens.typography.typeface.plain.value,
179+
h1: {
180+
fontSize: tokens.typography.typeScale.desktop.headline.fontSize.value,
181+
lineHeight: tokens.typography.typeScale.desktop.headline.lineHeight.value,
182+
fontWeight: tokens.typography.typeScale.desktop.headline.fontWeight.value,
183+
},
184+
h2: {
185+
fontSize: tokens.typography.typeScale.desktop.subtitle.fontSize.value,
186+
lineHeight: tokens.typography.typeScale.desktop.subtitle.lineHeight.value,
187+
fontWeight: tokens.typography.typeScale.desktop.subtitle.fontWeight.value,
188+
},
189+
h3: {
190+
fontSize: tokens.typography.typeScale.desktop['heading-1'].fontSize.value,
191+
lineHeight: tokens.typography.typeScale.desktop['heading-1'].lineHeight.value,
192+
fontWeight: tokens.typography.typeScale.desktop['heading-1'].fontWeight.value,
193+
},
194+
h4: {
195+
fontSize: tokens.typography.typeScale.desktop['heading-2'].fontSize.value,
196+
lineHeight: tokens.typography.typeScale.desktop['heading-2'].lineHeight.value,
197+
fontWeight: tokens.typography.typeScale.desktop['heading-2'].fontWeight.value,
198+
},
199+
h5: {
200+
fontSize: tokens.typography.typeScale.desktop['heading-3'].fontSize.value,
201+
lineHeight: tokens.typography.typeScale.desktop['heading-3'].lineHeight.value,
202+
fontWeight: tokens.typography.typeScale.desktop['heading-3'].fontWeight.value,
203+
},
204+
h6: {
205+
fontSize: tokens.typography.typeScale.desktop['heading-4'].fontSize.value,
206+
lineHeight: tokens.typography.typeScale.desktop['heading-4'].lineHeight.value,
207+
fontWeight: tokens.typography.typeScale.desktop['heading-4'].fontWeight.value,
208+
},
209+
subtitle1: {
210+
fontSize: tokens.typography.typeScale.desktop['body-extended-semibold'].fontSize.value,
211+
lineHeight: tokens.typography.typeScale.desktop['body-extended-semibold'].lineHeight.value,
212+
fontWeight: tokens.typography.typeScale.desktop['body-extended-semibold'].fontWeight.value,
213+
},
214+
subtitle2: {
215+
fontSize: tokens.typography.typeScale.desktop['body-base-semibold'].fontSize.value,
216+
lineHeight: tokens.typography.typeScale.desktop['body-base-semibold'].lineHeight.value,
217+
fontWeight: tokens.typography.typeScale.desktop['body-base-semibold'].fontWeight.value,
218+
},
219+
body1: {
220+
fontSize: tokens.typography.typeScale.desktop['body-extended'].fontSize.value,
221+
lineHeight: tokens.typography.typeScale.desktop['body-extended'].lineHeight.value,
222+
fontWeight: tokens.typography.typeScale.desktop['body-extended'].fontWeight.value,
223+
},
224+
body2: {
225+
fontSize: tokens.typography.typeScale.desktop['body-base'].fontSize.value,
226+
lineHeight: tokens.typography.typeScale.desktop['body-base'].lineHeight.value,
227+
fontWeight: tokens.typography.typeScale.desktop['body-base'].fontWeight.value,
228+
},
229+
caption: {
230+
fontSize: tokens.typography.typeScale.desktop.caption.fontSize.value,
231+
lineHeight: tokens.typography.typeScale.desktop.caption.lineHeight.value,
232+
fontWeight: tokens.typography.typeScale.desktop.caption.fontWeight.value,
233+
},
234+
},
235+
});
236+
};
237+
238+
// Helper function to generate responsive typography
239+
function createResponsiveTypography(
240+
tokens: ThemeTokens,
241+
desktopVariant: keyof typeof tokens.typography.typeScale.desktop,
242+
mobileVariant: keyof typeof tokens.typography.typeScale.mobile
243+
) {
244+
return {
245+
'@media (max-width:1199px)': {
246+
fontSize: `calc(${tokens.typography.typeScale.mobile[mobileVariant].fontSize.value} * ${desktopVariant === 'headline' ? 1.5 : 1.15})`,
247+
lineHeight: `calc(${tokens.typography.typeScale.mobile[mobileVariant].lineHeight.value} * ${desktopVariant === 'headline' ? 1.5 : 1.15})`,
248+
fontWeight: tokens.typography.typeScale.mobile[mobileVariant].fontWeight.value,
249+
},
250+
'@media (max-width:899px)': {
251+
fontSize: tokens.typography.typeScale.mobile[mobileVariant].fontSize.value,
252+
lineHeight: tokens.typography.typeScale.mobile[mobileVariant].lineHeight.value,
253+
fontWeight: tokens.typography.typeScale.mobile[mobileVariant].fontWeight.value,
254+
},
255+
};
256+
}
257+
258+
export default getMuiCustomTheme;

0 commit comments

Comments
 (0)