Skip to content
This repository was archived by the owner on Dec 6, 2025. It is now read-only.

Commit 57b1170

Browse files
authored
feat: Update styling and add dark mode (#1212)
* chore: add style-variables file and add it to config * chore: use style variables * chore: add color theme package * chore: update config * chore: add tailwind * feat: adopt tailwind for lib * feat: update storybook preview * fix: fix styling on various components * fix: geometry stories and objects * fix: using old color names * chore: replace all color variables * fix: fix lint * chore: use styling in landing page * chore: use styling in landing page * fix: styling propagation * fix: styling for landing page * chore: merge main * chore: add types for nodejs * fix: fix lint * fix: fix lint * fix: fix build by reverting react-query version * fix: fix alignment in vision section on landing page * chore: remove style-theme package and merge it into lib * feat: add dark mode to landing page * feat: update several components for dark mode * chore: remove useless clsx usages and imports * fix: fix type in variable name * chore: make indentation equal * chore: remove unnecessary todo * chore: use action instead of a print in stories * chore: disable buttons that have no defined function * fix: fix card selection behavior * fix: fix lint
1 parent 3857035 commit 57b1170

283 files changed

Lines changed: 10171 additions & 12536 deletions

File tree

Some content is hidden

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

api-services/mutations/users/user_mutations.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ export const useUserQuery = (userId: string | undefined) => {
99
return useQuery({
1010
queryKey: [QueryKeys.users, userId],
1111
enabled,
12-
staleTime: 5 * 60 * 1000, // 5 minutes
13-
cacheTime: 30 * 60 * 1000, // 30 minutes
1412
queryFn: async () => {
1513
if (!enabled || !userId) return
1614
const req = new ReadPublicProfileRequest()

api-services/package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
"dependencies": {
1010
"@helpwave/common": "workspace:*",
1111
"@helpwave/proto-ts": "0.64.0-89e2023.0",
12-
"@tanstack/react-query": "4.36.1",
13-
"@tanstack/react-query-devtools": "5.62.7",
12+
"@tanstack/react-query": "^4.36.1",
13+
"@tanstack/react-query-devtools": "^4.36.1",
1414
"@types/google-protobuf": "3.15.12",
1515
"cookies-next": "2.1.2",
1616
"google-protobuf": "3.21.4",
@@ -26,6 +26,7 @@
2626
"@helpwave/eslint-config": "workspace:*",
2727
"@types/js-cookie": "3.0.6",
2828
"@types/node": "20.17.10",
29-
"@types/react": "18.3.17"
29+
"@types/react": "18.3.17",
30+
"eslint": "9.17.0"
3031
}
3132
}

customer/components/ContractList.tsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { useContractsForProductsQuery } from '@/api/mutations/contract_mutations
55
import { LoadingAndErrorComponent } from '@helpwave/common/components/LoadingAndErrorComponent'
66
import Link from 'next/link'
77
import { ExternalLink } from 'lucide-react'
8-
import { tw } from '@twind/core'
98

109
type ContractListTranslation = {
1110
contracts: string,
@@ -44,22 +43,22 @@ export const ContractList = ({
4443
return (
4544
<LoadingAndErrorComponent isLoading={isLoading} hasError={isError}>
4645
{contracts && (
47-
<div className={tw('flex flex-col gap-y-1')}>
48-
<h3 className={tw('text-lg font-semibold')}>{translation.contracts}</h3>
46+
<div className="flex flex-col gap-y-1">
47+
<h3 className="text-lg font-semibold">{translation.contracts}</h3>
4948
{contracts.length === 0 ? (
50-
<span className={tw('text-bg-gray-300')}>{translation.noContracts}</span>
49+
<span className="text-bg-gray-300">{translation.noContracts}</span>
5150
) : (
5251
contracts.map(contract => (
5352
<Link
5453
href={contract.url}
5554
target="_blank"
5655
key={contract.uuid}
57-
className={tw('inline-flex flex-row gap-x-2')}
56+
className="inline-flex flex-row gap-x-2"
5857
>
5958
{contract.key}
60-
<span className={tw('inline-flex flex-row items-center')}>
59+
<span className="inline-flex flex-row items-center">
6160
(
62-
<div className={tw('inline-flex flex-row items-center gap-x-0.5')}>
61+
<div className="inline-flex flex-row items-center gap-x-0.5">
6362
{`${translation.show}`}
6463
<ExternalLink size={16}/>
6564
</div>

customer/components/forms/ContactInformationForm.tsx

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import type { CustomerCreate } from '@/api/dataclasses/customer'
22
import type { Translation } from '@helpwave/common/hooks/useTranslation'
33
import { useTranslation } from '@helpwave/common/hooks/useTranslation'
4-
import { tw, tx } from '@twind/core'
4+
import clsx from 'clsx'
5+
import { SolidButton } from '@helpwave/common/components/Button'
56
import { FormInput } from '@helpwave/common/components/user-input/Input'
6-
import { Button } from '@helpwave/common/components/Button'
77
import { useForm } from 'react-hook-form'
88

99
type ContactInformationTranslation = {
@@ -110,9 +110,9 @@ export const ContactInformationForm = ({ initialValue, onSubmit, className }: Co
110110
onSubmit(data)
111111
event?.preventDefault()
112112
})}
113-
className={tx('flex flex-col gap-y-2 max-w-[700px]', className)}
113+
className={clsx('flex flex-col gap-y-2 max-w-[700px]', className)}
114114
>
115-
<h3 className={tw('font-space font-bold text-2xl')}>{translation.contactInfo}</h3>
115+
<h3 className="font-space font-bold text-2xl">{translation.contactInfo}</h3>
116116
<FormInput
117117
id="name"
118118
autoComplete="name"
@@ -148,17 +148,17 @@ export const ContactInformationForm = ({ initialValue, onSubmit, className }: Co
148148
labelText={translation.phone}
149149
errorText={errors.phoneNumber?.message}
150150
/>
151-
<h4 className={tw('font-space font-bold text-lg mt-2')}>{translation.address}</h4>
151+
<h4 className="font-space font-bold text-lg mt-2">{translation.address}</h4>
152152

153-
<div className={tw('flex flex-row gap-x-2')}>
153+
<div className="row">
154154
<FormInput
155155
id="address"
156156
autoComplete="street-address"
157157
required={true}
158158
{...register('address', { required: translation.fieldRequired })}
159159
labelText={translation.address}
160160
errorText={errors.address?.message}
161-
containerClassName={tw('w-full')}
161+
containerClassName="w-full"
162162
/>
163163
<FormInput
164164
id="houseNumber"
@@ -172,7 +172,7 @@ export const ContactInformationForm = ({ initialValue, onSubmit, className }: Co
172172
})}
173173
labelText={translation.houseNumber}
174174
errorText={errors.houseNumber?.message}
175-
containerClassName={tw('max-w-[180px]')}
175+
containerClassName="max-w-[180px]"
176176
/>
177177
</div>
178178

@@ -183,15 +183,15 @@ export const ContactInformationForm = ({ initialValue, onSubmit, className }: Co
183183
errorText={errors.careOf?.message}
184184
/>
185185

186-
<div className={tw('flex flex-row gap-x-2')}>
186+
<div className="row">
187187
<FormInput
188188
id="city"
189189
autoComplete="address-level1"
190190
required={true}
191191
{...register('city', { required: translation.fieldRequired })}
192192
labelText={translation.city}
193193
errorText={errors.city?.message}
194-
containerClassName={tw('w-full')}
194+
containerClassName="w-full"
195195
/>
196196
<FormInput
197197
id="postalCode"
@@ -206,7 +206,7 @@ export const ContactInformationForm = ({ initialValue, onSubmit, className }: Co
206206
})}
207207
labelText={translation.postalCode}
208208
errorText={errors.postalCode?.message}
209-
containerClassName={tw('max-w-[180px]')}
209+
containerClassName="max-w-[180px]"
210210
/>
211211
</div>
212212

@@ -219,7 +219,7 @@ export const ContactInformationForm = ({ initialValue, onSubmit, className }: Co
219219
errorText={errors.country?.message}
220220
/>
221221

222-
<h4 className={tw('font-space font-bold text-lg mt-2')}>{translation.additionalInformation}</h4>
222+
<h4 className="font-space font-bold text-lg mt-2">{translation.additionalInformation}</h4>
223223
<FormInput
224224
id="websiteURL"
225225
autoComplete="url"
@@ -233,8 +233,8 @@ export const ContactInformationForm = ({ initialValue, onSubmit, className }: Co
233233
errorText={errors.websiteURL?.message}
234234
/>
235235

236-
<div className={tw('flex flex-row justify-end mt-2')}>
237-
<Button type="submit">{translation.save}</Button>
236+
<div className="row justify-end mt-2">
237+
<SolidButton type="submit">{translation.save}</SolidButton>
238238
</div>
239239
</form>
240240
)

customer/components/forms/StripeCheckOutForm.tsx

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,11 @@ import type { PropsWithChildren } from 'react'
88
import { useCallback, useRef, useState } from 'react'
99
import { InvoiceAPI } from '@/api/services/invoice'
1010
import { useAuth } from '@/hooks/useAuth'
11-
import { Button } from '@helpwave/common/components/Button'
1211
import { STRIPE_PUBLISHABLE_KEY } from '@/api/config'
1312
import type { Translation } from '@helpwave/common/hooks/useTranslation'
1413
import { useTranslation } from '@helpwave/common/hooks/useTranslation'
15-
import { tw } from '@twind/core'
1614
import { useLanguage } from '@helpwave/common/hooks/useLanguage'
15+
import { SolidButton } from '@helpwave/common/components/Button'
1716

1817
type EmbeddedCheckoutButtonTranslation = {
1918
cancel: string,
@@ -64,21 +63,21 @@ export default function EmbeddedCheckoutButton({ children, invoiceId }: Embedded
6463

6564
return (
6665
<div id="checkout">
67-
<Button onClick={handleCheckoutClick}>
66+
<SolidButton onClick={handleCheckoutClick}>
6867
{children}
69-
</Button>
70-
<dialog ref={modalRef} className={tw('w-full h-full max-w-[90vw] max-h-[90vh] rounded-lg overflow-hidden')}>
71-
<div className={tw('flex flex-col justify-between gap-y-4 w-full h-full overflow-auto')}>
72-
<h3 className={tw('font-bold text-2xl')}>{translation.checkout}</h3>
68+
</SolidButton>
69+
<dialog ref={modalRef} className="w-full h-full max-w-[90vw] max-h-[90vh] rounded-lg overflow-hidden">
70+
<div className="flex flex-col justify-between gap-y-4 w-full h-full overflow-auto">
71+
<h3 className="font-bold text-2xl">{translation.checkout}</h3>
7372
{showCheckout && (
7473
<EmbeddedCheckoutProvider stripe={stripePromise} options={options}>
75-
<EmbeddedCheckout />
74+
<EmbeddedCheckout/>
7675
</EmbeddedCheckoutProvider>
7776
)}
7877
<form method="dialog">
79-
<Button onClick={handleCloseModal}>
78+
<SolidButton onClick={handleCloseModal}>
8079
{translation.cancel}
81-
</Button>
80+
</SolidButton>
8281
</form>
8382
</div>
8483
</dialog>

customer/components/layout/Footer.tsx

Whitespace-only changes.

customer/components/layout/FooterLinkGroup.tsx

Whitespace-only changes.

customer/components/layout/Header.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { ReactNode } from 'react'
2-
import { tw, tx } from '@twind/core'
2+
import clsx from 'clsx'
33

44
export type HeaderProps = {
55
leading?: ReactNode,
@@ -14,22 +14,22 @@ export type HeaderProps = {
1414
export const Header = ({ leading, leftSide, rightSide, className }: HeaderProps) => {
1515
return (
1616
<header
17-
className={tx(
18-
'@(sticky top-0 flex flex-row items-center justify-between px-2 py-2 w-full min-h-[64px] max-h-[64px] shadow-md bg-white)',
17+
className={clsx(
18+
'sticky top-0 row items-center justify-between px-2 py-2 w-full min-h-[64px] max-h-[64px] shadow-md bg-white',
1919
className
2020
)}
2121
>
22-
<div className={tw('flex flex-row items-center gap-x-4')}>
22+
<div className="row items-center gap-x-4">
2323
{leading}
24-
{leading && leftSide && (<div className={tw('h-8 w-[2px] rounded bg-gray-200')}/>)}
24+
{leading && leftSide && (<div className="h-8 w-[2px] rounded bg-gray-200"/>)}
2525
{leftSide && (
26-
<div className={tw('flex flex-row items-center gap-x-2')}>
26+
<div className="row items-center gap-x-2">
2727
{leftSide}
2828
</div>
2929
)}
3030
</div>
3131
{rightSide && (
32-
<div className={tw('flex flex-row items-center gap-x-2')}>
32+
<div className="row items-center gap-x-2">
3333
{rightSide}
3434
</div>
3535
)}

customer/components/layout/MobileNavigationOverlay.tsx

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import type { Languages } from '@helpwave/common/hooks/useLanguage'
22
import { languagesLocalNames } from '@helpwave/common/hooks/useLanguage'
33
import { useLanguage } from '@helpwave/common/hooks/useLanguage'
4-
import { tw, tx } from '@twind/core'
54
import { useRouter } from 'next/router'
65
import Link from 'next/link'
76
import { noop } from '@helpwave/common/util/noop'
@@ -11,8 +10,9 @@ import type { NavItem } from '@/components/layout/NavigationSidebar'
1110
import { Avatar } from '@helpwave/common/components/Avatar'
1211
import { LanguageModal } from '@helpwave/common/components/modals/LanguageModal'
1312
import { useState } from 'react'
14-
import { Button } from '@helpwave/common/components/Button'
1513
import { logout } from '@/api/auth/authService'
14+
import clsx from 'clsx'
15+
import { SolidButton } from '@helpwave/common/components/Button'
1616

1717
type MobileNavigationOverlayTranslation = { navigation: string, logout: string }
1818

@@ -47,19 +47,19 @@ export const MobileNavigationOverlay = ({ items, onCloseClick = noop, className
4747

4848
return (
4949
<div
50-
className={tw('@(flex flex-col bg-white h-full w-full top-0 absolute px-8 py-6 z-[100] not-mobile:hidden justify-between)')}>
50+
className="col bg-white h-full w-full top-0 absolute px-8 py-6 z-[100] tablet:hidden justify-between">
5151
<LanguageModal
5252
id="language-modal-mobile"
5353
isOpen={isLanguageModalOpen}
5454
onCloseClick={() => setIsLanguageModalOpen(false)}
5555
onBackgroundClick={() => setIsLanguageModalOpen(false)}
5656
onDone={() => setIsLanguageModalOpen(false)}
57-
containerClassName={tw('z-[102]')}
57+
containerClassName="z-[102]"
5858
/>
59-
<nav className={tx('@(flex flex-col gap-y-4 items-center)', className)}>
60-
<div className={tw('flex flex-row w-full items-center justify-between mb-2')}>
61-
<h2 className={tw('font-bold font-space text-2xl')}>{translation.navigation}</h2>
62-
<button className={tw('rounded-md p-1')} onClick={onCloseClick}>
59+
<nav className={clsx('col gap-y-4 items-center', className)}>
60+
<div className="row w-full items-center justify-between mb-2">
61+
<h2 className="font-bold font-space text-2xl">{translation.navigation}</h2>
62+
<button className="rounded-md p-1" onClick={onCloseClick}>
6363
<X size={24}/>
6464
</button>
6565
</div>
@@ -68,33 +68,33 @@ export const MobileNavigationOverlay = ({ items, onCloseClick = noop, className
6868
href={item.url}
6969
key={i}
7070
target={item.isExternal ?? false ? '_blank' : undefined}
71-
className={tx(
72-
'flex flex-row justify-between items-center px-4 py-2 hover:bg-hw-primary-500/40 w-full text-lg font-semibold rounded-md',
71+
className={clsx(
72+
'flex flex-row justify-between items-center px-4 py-2 hover:bg-primary/40 hover:text-on-primary w-full text-lg font-semibold rounded-md',
7373
{ 'bg-gray-100': router.pathname === item.url, 'bg-white': router.pathname !== item.url }
7474
)}
7575
>
76-
<div className={tw('flex flex-row gap-x-2 items-center')}>
76+
<div className="row gap-x-2 items-center">
7777
{item.icon}
7878
{item.name[language]}
7979
</div>
8080
<ArrowRightIcon size={24}/>
8181
</Link>
8282
))}
8383
</nav>
84-
<div className={tw('flex flex-col gap-y-4 items-center w-full')}>
84+
<div className="col gap-y-4 items-center w-full">
8585
<button
86-
className={tw('flex flex-row w-full justify-between items-center px-4 py-2 bg-gray-100 hover:bg-hw-primary-500/40 font-semibold rounded-md')}
86+
className="row w-full justify-between items-center px-4 py-2 bg-gray-100 hover:bg-hw-primary-500/40 font-semibold rounded-md"
8787
onClick={() => setIsLanguageModalOpen(true)}
8888
>
8989
{languagesLocalNames[language]}
9090
<ArrowRightLeft size={24}/>
9191
</button>
9292
<button
93-
className={tw('flex flex-row w-full gap-x-2 items-center p-4 bg-white bg-gray-100 hover:bg-hw-primary-500/40 font-semibold rounded-md')}>
93+
className="row w-full items-center p-4 bg-white bg-gray-100 hover:bg-hw-primary-500/40 font-semibold rounded-md">
9494
<Avatar avatarUrl="https://helpwave.de/favicon.ico" alt="" size="small"/>
9595
{'Max Mustermann'}
9696
</button>
97-
<Button onClick={logout} color="hw-negative">{translation.logout}</Button>
97+
<SolidButton onClick={logout} color="negative">{translation.logout}</SolidButton>
9898
</div>
9999
</div>
100100
)

0 commit comments

Comments
 (0)