Skip to content

Commit 7299d85

Browse files
committed
Render logo field
1 parent 3449c2b commit 7299d85

File tree

3 files changed

+63
-2
lines changed

3 files changed

+63
-2
lines changed

packages/clerk-js/src/core/resources/OrganizationCreationDefaults.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ export class OrganizationCreationDefaults extends BaseResource implements Organi
1616
form: {
1717
name: string;
1818
slug: string;
19+
logo: string | null;
1920
} = {
2021
name: '',
2122
slug: '',
23+
logo: null,
2224
};
2325

2426
public constructor(data: OrganizationCreationDefaultsJSON | OrganizationCreationDefaultsJSONSnapshot | null = null) {
@@ -38,6 +40,7 @@ export class OrganizationCreationDefaults extends BaseResource implements Organi
3840
if (data.form) {
3941
this.form.name = this.withDefault(data.form.name, this.form.name);
4042
this.form.slug = this.withDefault(data.form.slug, this.form.slug);
43+
this.form.logo = this.withDefault(data.form.logo, this.form.logo);
4144
}
4245

4346
return this;

packages/shared/src/types/organizationCreationDefaults.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export interface OrganizationCreationDefaultsJSON extends ClerkResourceJSON {
1313
form: {
1414
name: string;
1515
slug: string;
16+
logo: string | null;
1617
};
1718
}
1819

@@ -24,5 +25,6 @@ export interface OrganizationCreationDefaultsResource extends ClerkResource {
2425
form: {
2526
name: string;
2627
slug: string;
28+
logo: string | null;
2729
};
2830
}

packages/ui/src/components/SessionTasks/tasks/TaskChooseOrganization/CreateOrganizationScreen.tsx

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,37 @@
11
import { useOrganizationList } from '@clerk/shared/react';
22
import type { CreateOrganizationParams } from '@clerk/shared/types';
3+
import React from 'react';
34

45
import { useEnvironment } from '@/ui/contexts';
56
import { useSessionTasksContext, useTaskChooseOrganizationContext } from '@/ui/contexts/components/SessionTasks';
6-
import { localizationKeys } from '@/ui/customizables';
7+
import { Icon, localizationKeys } from '@/ui/customizables';
78
import { useCardState } from '@/ui/elements/contexts';
89
import { Form } from '@/ui/elements/Form';
910
import { FormButtonContainer } from '@/ui/elements/FormButtons';
1011
import { FormContainer } from '@/ui/elements/FormContainer';
1112
import { Header } from '@/ui/elements/Header';
13+
import { IconButton } from '@/ui/elements/IconButton';
14+
import { Upload } from '@/ui/icons';
1215
import { createSlug } from '@/ui/utils/createSlug';
1316
import { handleError } from '@/ui/utils/errorHandler';
1417
import { useFormControl } from '@/ui/utils/useFormControl';
1518

19+
import { OrganizationProfileAvatarUploader } from '../../../OrganizationProfile/OrganizationProfileAvatarUploader';
1620
import { organizationListParams } from '../../../OrganizationSwitcher/utils';
1721
import { OrganizationCreationDefaultsAlert } from './OrganizationCreationDefaultsAlert';
1822

1923
// TODO: Replace with actual API call to OrganizationCreationDefaults.retrieve()
24+
// TODO - Only replace if .organization_settings.organization_creation_defaults.enabled
2025
const organizationCreationDefaults = {
2126
advisory: {
2227
type: 'existing_org_with_domain' as const,
2328
severity: 'warning' as const,
2429
},
30+
form: {
31+
name: '',
32+
slug: '',
33+
logo: null,
34+
},
2535
pathRoot: '',
2636
reload: () => Promise.resolve({} as any),
2737
};
@@ -38,6 +48,7 @@ export const CreateOrganizationScreen = (props: CreateOrganizationScreenProps) =
3848
userMemberships: organizationListParams.userMemberships,
3949
});
4050
const { organizationSettings } = useEnvironment();
51+
const [file, setFile] = React.useState<File | null>();
4152

4253
const nameField = useFormControl('name', '', {
4354
type: 'text',
@@ -68,6 +79,10 @@ export const CreateOrganizationScreen = (props: CreateOrganizationScreenProps) =
6879

6980
const organization = await createOrganization(createOrgParams);
7081

82+
if (file) {
83+
await organization.setLogo({ file });
84+
}
85+
7186
await setActive({
7287
organization,
7388
navigate: async ({ session }) => {
@@ -88,6 +103,11 @@ export const CreateOrganizationScreen = (props: CreateOrganizationScreenProps) =
88103
slugField.setValue(val);
89104
};
90105

106+
const onAvatarRemove = () => {
107+
card.setIdle();
108+
return setFile(null);
109+
};
110+
91111
const isSubmitButtonDisabled = !nameField.value || !isLoaded;
92112

93113
return (
@@ -101,8 +121,44 @@ export const CreateOrganizationScreen = (props: CreateOrganizationScreenProps) =
101121
</Header.Root>
102122

103123
<FormContainer sx={t => ({ padding: `${t.space.$none} ${t.space.$10} ${t.space.$8}` })}>
104-
<OrganizationCreationDefaultsAlert organizationCreationDefaults={organizationCreationDefaults} />
105124
<Form.Root onSubmit={onSubmit}>
125+
<OrganizationCreationDefaultsAlert organizationCreationDefaults={organizationCreationDefaults} />
126+
<OrganizationProfileAvatarUploader
127+
organization={{ name: nameField.value }}
128+
onAvatarChange={async file => await setFile(file)}
129+
onAvatarRemove={file ? onAvatarRemove : null}
130+
avatarPreviewPlaceholder={
131+
<IconButton
132+
variant='ghost'
133+
aria-label='Upload organization logo'
134+
icon={
135+
<Icon
136+
size='md'
137+
icon={Upload}
138+
sx={t => ({
139+
color: t.colors.$colorMutedForeground,
140+
transitionDuration: t.transitionDuration.$controls,
141+
})}
142+
/>
143+
}
144+
sx={t => ({
145+
width: t.sizes.$16,
146+
height: t.sizes.$16,
147+
borderRadius: t.radii.$md,
148+
borderWidth: t.borderWidths.$normal,
149+
borderStyle: t.borderStyles.$dashed,
150+
borderColor: t.colors.$borderAlpha200,
151+
backgroundColor: t.colors.$neutralAlpha50,
152+
':hover': {
153+
backgroundColor: t.colors.$neutralAlpha50,
154+
svg: {
155+
transform: 'scale(1.2)',
156+
},
157+
},
158+
})}
159+
/>
160+
}
161+
/>
106162
<Form.ControlRow elementId={nameField.id}>
107163
<Form.PlainInput
108164
{...nameField.props}

0 commit comments

Comments
 (0)