Skip to content

Commit

Permalink
♻️(frontend) reorganize starting frontend code
Browse files Browse the repository at this point in the history
- we now have "features" to try to organize code by intent instead of
code type. everything at the root of frontend, not in feature/, is
global
- customized the panda config a bunch to try to begin to have an actual
design system. The idea is to prevent using arbitrary values here and
there in the code, but rather semantic tokens
- changed the userAuth code logic to handle the fact that a 401 on the
users/me call is not really an error per say, but rather an indication
the user is not logged in
  • Loading branch information
manuhabitela committed Jul 16, 2024
1 parent d9ef64c commit 31ea621
Show file tree
Hide file tree
Showing 55 changed files with 985 additions and 484 deletions.
6 changes: 0 additions & 6 deletions src/frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion src/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
"@livekit/components-styles": "1.0.12",
"@pandacss/preset-panda": "0.41.0",
"@tanstack/react-query": "5.49.2",
"classnames": "2.5.1",
"livekit-client": "2.3.1",
"react": "18.2.0",
"react-aria-components": "1.2.1",
Expand Down
309 changes: 260 additions & 49 deletions src/frontend/panda.config.ts
Original file line number Diff line number Diff line change
@@ -1,69 +1,280 @@
import pandaPreset from '@pandacss/preset-panda'
import { defineConfig, defineTokens } from '@pandacss/dev'
import {
Config,
Tokens,
defineConfig,
defineSemanticTokens,
defineTextStyles,
defineTokens,
} from '@pandacss/dev'

export default defineConfig({
const spacing: Tokens['spacing'] = {
0: { value: '0rem' },
0.125: { value: '0.125rem' },
0.25: { value: '0.25rem' },
0.375: { value: '0.375rem' },
0.5: { value: '0.5rem' },
0.625: { value: '0.625rem' },
0.75: { value: '0.75rem' },
1: { value: '1rem' },
1.25: { value: '1.25rem' },
1.5: { value: '1.5rem' },
1.75: { value: '1.75rem' },
2: { value: '2rem' },
2.25: { value: '2.25rem' },
2.5: { value: '2.5rem' },
2.75: { value: '2.75rem' },
3: { value: '3rem' },
3.5: { value: '3.5rem' },
4: { value: '4rem' },
}

const config: Config = {
preflight: true,
include: ['./src/**/*.{js,jsx,ts,tsx}'],
exclude: [],
jsxFramework: 'react',
outdir: 'src/styled-system',
conditions: {
extend: {
// React Aria builds upon data attributes instead of css pseudo-classes, make sure to only work based on react aria stuff
hover: '&:is([data-hovered])',
focus: '&:is([data-focused])',
focusVisible: '&:is([data-focus-visible])',
disabled: '&:is([data-disabled])',
// React Aria builds upon data attributes instead of css pseudo-classes, in case we style a React Aria component
// we dont want to trigger pseudo class related styles
'ra-hover': '&:is([data-hovered])',
'ra-focus': '&:is([data-focused])',
'ra-focusVisible': '&:is([data-focus-visible])',
'ra-disabled': '&:is([data-disabled])',
pressed: '&:is([data-pressed])',
'ra-pressed': '&:is([data-pressed])',
},
},
theme: {
...pandaPreset.theme,
// media queries are defined in em so that zooming with text-only mode triggers breakpoints
breakpoints: {
xs: '22.6em', // 360px (we assume less than that are old/entry level mobile phones)
sm: '40em', // 640px
md: '48em', // 768px
lg: '64em', // 1024px
xl: '80em', // 1280px
'2xl': '96em', // 1536px
},
tokens: defineTokens({
/* we take a few things from the panda preset but for now we clear out some stuff.
* This way we'll only add the things we need step by step and prevent using lots of differents things.
*/
...pandaPreset.theme.tokens,
animations: {},
blurs: {},
/* just directly use values as tokens. This allows us to follow a specific design scale,
* without having to remember what 'sm' or '2xl' actually means.
*
* see semanticTokens for tokens targeting specific usages
*/
fonts: {
sans: {
value: [
'Source Sans',
'Source Sans fallback',
'ui-sans-serif',
'system-ui',
'-apple-system',
'BlinkMacSystemFont',
'"Segoe UI"',
'Roboto',
'"Helvetica Neue"',
'Arial',
'"Noto Sans"',
'sans-serif',
'"Apple Color Emoji"',
'"Segoe UI Emoji"',
'"Segoe UI Symbol"',
'"Noto Color Emoji"',
],
},
serif: {
value: [
'ui-serif',
'Georgia',
'Cambria',
'"Times New Roman"',
'Times',
'serif',
],
},
mono: {
value: [
'Source Code Pro',
'ui-monospace',
'SFMono-Regular',
'Menlo',
'Monaco',
'Consolas',
'"Liberation Mono"',
'"Courier New"',
'monospace',
],
},
},
fontSizes: {
10: { value: '0.625rem' },
12: { value: '0.75rem' },
14: { value: '0.875rem' },
16: { value: '1rem' },
20: { value: '1.25rem' },
24: { value: '1.5rem' },
28: { value: '1.75rem' },
32: { value: '2rem' },
40: { value: '2.375rem' },
48: { value: '3rem' },
64: { value: '4rem' },
},
letterSpacings: {},
shadows: {
sm: {
value: [
'0 1px 3px 0 rgb(0 0 0 / 0.1)',
'0 1px 2px -1px rgb(0 0 0 / 0.1)',
],
},
},
lineHeights: {
1: { value: '1' },
1.25: { value: '1.25' },
1.375: { value: '1.375' },
1.5: { value: '1.5' },
1.625: { value: '1.625' },
2: { value: '2' },
},
radii: {
6: { value: '0.375rem' },
8: { value: '0.5rem' },
16: { value: '1rem' },
full: { value: '9999px' },
},
sizes: {
...spacing,
full: { value: '100%' },
min: { value: 'min-content' },
max: { value: 'max-content' },
fit: { value: 'fit-content' },
},
spacing,
}),
semanticTokens: defineSemanticTokens({
colors: {
default: {
text: { value: '{colors.gray.900}' },
bg: { value: '{colors.slate.50}' },
subtle: { value: '{colors.gray.100}' },
'subtle-text': { value: '{colors.gray.600}' },
},
box: {
text: { value: '{colors.default.text}' },
bg: { value: '{colors.white}' },
border: { value: '{colors.gray.300}' },
},
control: {
DEFAULT: { value: '{colors.gray.100}' },
hover: { value: '{colors.gray.200}' },
active: { value: '{colors.gray.300}' },
text: { value: '{colors.default.text}' },
border: { value: '{colors.gray.300}' },
},
primary: {
DEFAULT: { value: '{colors.blue.700}' },
hover: { value: '{colors.blue.800}' },
active: { value: '{colors.blue.900}' },
text: { value: '{colors.white}' },
warm: { value: '{colors.blue.300}' },
subtle: { value: '{colors.blue.100}' },
'subtle-text': { value: '{colors.sky.700}' },
},
danger: {
DEFAULT: { value: '{colors.red.600}' },
hover: { value: '{colors.red.700}' },
active: { value: '{colors.red.800}' },
text: { value: '{colors.white}' },
subtle: { value: '{colors.red.100}' },
'subtle-text': { value: '{colors.red.700}' },
},
success: {
DEFAULT: { value: '{colors.emerald.700}' },
hover: { value: '{colors.emerald.800}' },
active: { value: '{colors.emerald.900}' },
text: { value: '{colors.white}' },
subtle: { value: '{colors.emerald.100}' },
'subtle-text': { value: '{colors.emerald.700}' },
},
warning: {
DEFAULT: { value: '{colors.amber.700}' },
hover: { value: '{colors.amber.800}' },
active: { value: '{colors.amber.900}' },
text: { value: '{colors.white}' },
subtle: { value: '{colors.amber.100}' },
'subtle-text': { value: '{colors.amber.700}' },
},
},
shadows: {
box: { value: '{shadows.sm}' },
},
spacing: {
0: { value: '0rem' },
0.125: { value: '0.125rem' },
0.25: { value: '0.25rem' },
0.375: { value: '0.375rem' },
0.5: { value: '0.5rem' },
0.75: { value: '0.75rem' },
1: { value: '1rem' },
1.25: { value: '1.25rem' },
1.5: { value: '1.5rem' },
1.75: { value: '1.75rem' },
2: { value: '2rem' },
2.25: { value: '2.25rem' },
2.5: { value: '2.5rem' },
2.75: { value: '2.75rem' },
3: { value: '3rem' },
3.5: { value: '3.5rem' },
4: { value: '4rem' },
5: { value: '5rem' },
6: { value: '6rem' },
7: { value: '7rem' },
8: { value: '8rem' },
9: { value: '9rem' },
10: { value: '10rem' },
12: { value: '12rem' },
14: { value: '14rem' },
16: { value: '16rem' },
20: { value: '20rem' },
24: { value: '24rem' },
28: { value: '28rem' },
32: { value: '32rem' },
36: { value: '36rem' },
40: { value: '40rem' },
44: { value: '44rem' },
48: { value: '48rem' },
52: { value: '52rem' },
56: { value: '56rem' },
60: { value: '60rem' },
64: { value: '64rem' },
72: { value: '72rem' },
80: { value: '80rem' },
96: { value: '96rem' },
boxPadding: {
DEFAULT: { value: '{spacing.2}' },
sm: { value: '{spacing.1}' },
xs: { value: '{spacing.0.5}' },
},
boxMargin: {
xs: { value: '{spacing.0.5}' },
DEFAULT: { value: '{spacing.1}' },
lg: { value: '{spacing.2}' },
},
paragraph: { value: '{spacing.1}' },
heading: { value: '{spacing.1}' },
gutter: { value: '{spacing.1}' },
},
}),
textStyles: defineTextStyles({
h1: {
value: {
fontSize: '1.5rem',
lineHeight: '2rem',
fontWeight: 700,
},
},
h2: {
value: {
fontSize: '1.25rem',
lineHeight: '1.75rem',
fontWeight: 700,
},
},
h3: {
value: {
fontSize: '1.125rem',
lineHeight: '1.75rem',
fontWeight: 700,
},
},
body: {
value: {
fontSize: '1rem',
lineHeight: '1.5',
},
},
small: {
value: {
fontSize: '0.875rem',
lineHeight: '1.25rem',
},
},
badge: {
value: {
fontSize: '0.75rem',
lineHeight: '1rem',
},
},
}),
},
})
}

export default defineConfig(config)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
8 changes: 4 additions & 4 deletions src/frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { Route, Switch } from 'wouter'
import { Home } from './routes/Home'
import { Conference } from './routes/Conference'
import { NotFoundScreen } from './layout/NotFoundScreen'
import { NotFound } from './routes/NotFound'
import { RoomRoute } from '@/features/rooms'

const queryClient = new QueryClient()

Expand All @@ -14,8 +14,8 @@ function App() {
<QueryClientProvider client={queryClient}>
<Switch>
<Route path="/" component={Home} />
<Route path="/:roomId" component={Conference} />
<Route component={NotFoundScreen} />
<Route path="/:roomId" component={RoomRoute} />
<Route component={NotFound} />
</Switch>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
Expand Down
9 changes: 4 additions & 5 deletions src/frontend/src/api/apiUrl.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
export const apiUrl = (path: string, apiVersion = '1.0') => {

const origin =
import.meta.env.VITE_API_BASE_URL
|| (typeof window !== 'undefined' ? window.location.origin : '');
import.meta.env.VITE_API_BASE_URL ||
(typeof window !== 'undefined' ? window.location.origin : '')

// Remove leading/trailing slashes from origin/path if it exists
const sanitizedOrigin = origin.replace(/\/$/, '')
const sanitizedPath = path.replace(/^\//, '');
const sanitizedPath = path.replace(/^\//, '')

return `${sanitizedOrigin}/api/v${apiVersion}/${sanitizedPath}`;
return `${sanitizedOrigin}/api/v${apiVersion}/${sanitizedPath}`
}
Loading

0 comments on commit 31ea621

Please sign in to comment.