Skip to content

Commit a5a206c

Browse files
committed
accordions are stylish (and clean u user prefs)
1 parent a69c12d commit a5a206c

File tree

2 files changed

+80
-94
lines changed

2 files changed

+80
-94
lines changed

components/dashboard/src/user-settings/Preferences.tsx

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ import { converter, userClient } from "../service/public-api";
2525
import { LoadingButton } from "@podkit/buttons/LoadingButton";
2626
import { useOrgSettingsQuery } from "../data/organizations/org-settings-query";
2727
import Alert from "../components/Alert";
28-
import { GETTING_STARTED_DISMISSAL_KEY } from "../workspaces/Workspaces";
29-
import { useFeatureFlag } from "../data/featureflag-query";
3028

3129
export type IDEChangedTrackLocation = "workspace_list" | "workspace_start" | "preferences";
3230

@@ -46,8 +44,6 @@ export default function Preferences() {
4644
const [timeoutUpdating, setTimeoutUpdating] = useState(false);
4745
const [creationError, setCreationError] = useState<Error>();
4846

49-
const isEnterpriseOnboardingEnabled = useFeatureFlag("enterprise_onboarding_enabled");
50-
5147
const saveDotfileRepo = useCallback(
5248
async (e) => {
5349
e.preventDefault();
@@ -118,30 +114,6 @@ export default function Preferences() {
118114
toast("Workspace options have been cleared.");
119115
}, [updateUser, setUser, toast, user]);
120116

121-
const restartOrgOnboarding = useCallback(async () => {
122-
const updatedUser = await updateUser.mutateAsync(
123-
{
124-
additionalData: {
125-
profile: {
126-
coachmarksDismissals: {
127-
[GETTING_STARTED_DISMISSAL_KEY]: "",
128-
},
129-
},
130-
},
131-
},
132-
{
133-
onError: (e) => {
134-
toast("Failed to reset onboarding.");
135-
},
136-
},
137-
);
138-
139-
if (updatedUser) {
140-
setUser(updatedUser);
141-
toast("Onboarding has been restarted.");
142-
}
143-
}, [updateUser, toast, setUser]);
144-
145117
return (
146118
<div>
147119
<PageWithSettingsSubMenu>
@@ -164,16 +136,6 @@ export default function Preferences() {
164136
Reset Options
165137
</Button>
166138

167-
{isEnterpriseOnboardingEnabled && (
168-
<>
169-
<Heading3 className="mt-12">Organization onboarding</Heading3>
170-
<Subheading>If you dismissed the onboarding process, you can restart it here.</Subheading>
171-
<Button className="mt-4" variant="secondary" onClick={restartOrgOnboarding}>
172-
Restart Onboarding
173-
</Button>
174-
</>
175-
)}
176-
177139
<ThemeSelector className="mt-12" />
178140

179141
<Heading2 className="mt-12">Dotfiles</Heading2>

components/dashboard/src/workspaces/Workspaces.tsx

Lines changed: 80 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* See License.AGPL.txt in the project root for license information.
55
*/
66

7-
import { FunctionComponent, useCallback, useMemo, useState } from "react";
7+
import { FunctionComponent, useCallback, useEffect, useMemo, useState } from "react";
88
import Header from "../components/Header";
99
import { WorkspaceEntry } from "./WorkspaceEntry";
1010
import { ItemsList } from "../components/ItemsList";
@@ -20,7 +20,7 @@ import { Workspace, WorkspacePhase_Phase } from "@gitpod/public-api/lib/gitpod/v
2020
import { Button } from "@podkit/buttons/Button";
2121
import { VideoCarousel } from "./VideoCarousel";
2222
import { BlogBanners } from "./BlogBanners";
23-
import { Book, BookOpen, Building, Code, GraduationCap } from "lucide-react";
23+
import { Book, BookOpen, Building, ChevronRight, Code, GraduationCap } from "lucide-react";
2424
import { ReactComponent as GitpodStrokedSVG } from "../icons/gitpod-stroked.svg";
2525
import PersonalizedContent from "./PersonalizedContent";
2626
import { useListenToWorkspacesWSMessages as useListenToWorkspacesStatusUpdates } from "../data/workspaces/listen-to-workspace-ws-messages";
@@ -119,28 +119,41 @@ const WorkspacesPage: FunctionComponent = () => {
119119
} catch (e) {}
120120
}, [deleteInactiveWorkspaces, inactiveWorkspaces, toast]);
121121

122-
const [showGettingStarted, setShowGettingStarted] = useState(true);
123-
const dismissGettingStarted = useCallback(() => {
124-
setShowGettingStarted(false);
125-
126-
mutateUser(
127-
{
128-
additionalData: {
129-
profile: {
130-
coachmarksDismissals: {
131-
[GETTING_STARTED_DISMISSAL_KEY]: new Date().toISOString(),
122+
// initialize a state so that we can be optimistic and reactive, but also use an effect to sync the state with the user's actual profile
123+
const [showGettingStarted, setShowGettingStarted] = useState<boolean | undefined>(undefined);
124+
useEffect(() => {
125+
if (!user?.profile?.coachmarksDismissals[GETTING_STARTED_DISMISSAL_KEY]) {
126+
setShowGettingStarted(true);
127+
} else {
128+
setShowGettingStarted(false);
129+
}
130+
}, [user?.profile?.coachmarksDismissals]);
131+
132+
const toggleGettingStarted = useCallback(
133+
(show: boolean) => {
134+
setShowGettingStarted(show);
135+
console.log("toggleGettingStarted", show);
136+
137+
mutateUser(
138+
{
139+
additionalData: {
140+
profile: {
141+
coachmarksDismissals: {
142+
[GETTING_STARTED_DISMISSAL_KEY]: !show ? new Date().toISOString() : "",
143+
},
132144
},
133145
},
134146
},
135-
},
136-
{
137-
onError: (e) => {
138-
toast("Failed to dismiss getting started");
139-
setShowGettingStarted(true);
147+
{
148+
onError: (e) => {
149+
toast("Failed to dismiss getting started");
150+
setShowGettingStarted(true);
151+
},
140152
},
141-
},
142-
);
143-
}, [mutateUser, toast]);
153+
);
154+
},
155+
[mutateUser, toast],
156+
);
144157

145158
const [isVideoModalVisible, setVideoModalVisible] = useState(false);
146159
const handleVideoModalClose = useCallback(() => {
@@ -154,20 +167,30 @@ const WorkspacesPage: FunctionComponent = () => {
154167
subtitle="Manage, start and stop your personal development environments in the cloud."
155168
/>
156169

157-
{isEnterpriseOnboardingEnabled &&
158-
isDedicatedInstallation &&
159-
showGettingStarted &&
160-
!user?.profile?.coachmarksDismissals[GETTING_STARTED_DISMISSAL_KEY] && (
161-
<>
162-
<div className="app-container flex flex-row items-center justify-between mt-4 mb-2">
163-
<Subheading className="font-semibold text-pk-content-primary">Getting started</Subheading>
164-
<Tooltip content={`Hide "Getting started" - can be restored in your user preferences`}>
165-
<Button variant={"ghost"} onClick={dismissGettingStarted}>
166-
Hide
170+
{isEnterpriseOnboardingEnabled && isDedicatedInstallation && (
171+
<>
172+
<div className="app-container flex flex-row items-center justify-between mt-4 mb-2">
173+
<div className="flex flex-row items-center gap-2">
174+
<Tooltip content="Toggle helpful resources for getting started with Gitpod">
175+
<Button
176+
variant="ghost"
177+
onClick={() => toggleGettingStarted(!showGettingStarted)}
178+
className="p-2"
179+
>
180+
<ChevronRight
181+
className={`text-gray-400 dark:text-gray-500 transform transition-transform duration-100 ${
182+
showGettingStarted ? "rotate-90" : ""
183+
}`}
184+
size={24}
185+
/>
167186
</Button>
168187
</Tooltip>
188+
189+
<Subheading className="font-semibold text-pk-content-primary">Getting started</Subheading>
169190
</div>
191+
</div>
170192

193+
{showGettingStarted && (
171194
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-5 lg:px-28 px-4">
172195
<Card onClick={() => setVideoModalVisible(true)}>
173196
<GraduationCap className="flex-shrink-0" size={24} />
@@ -211,32 +234,33 @@ const WorkspacesPage: FunctionComponent = () => {
211234
</div>
212235
</Card>
213236
</div>
214-
215-
<Modal
216-
visible={isVideoModalVisible}
217-
onClose={handleVideoModalClose}
218-
containerClassName="min-[576px]:max-w-[600px]"
219-
>
220-
<ModalHeader>Demo video</ModalHeader>
221-
<ModalBody>
222-
<div className="flex flex-row items-center justify-center">
223-
<VideoSection
224-
metadataVideoTitle="Gitpod demo"
225-
playbackId="m01BUvCkTz7HzQKFoIcQmK00Rx5laLLoMViWBstetmvLs"
226-
poster="https://i.ytimg.com/vi_webp/1ZBN-b2cIB8/maxresdefault.webp"
227-
playerProps={{ onPlay: handlePlay, defaultHiddenCaptions: true }}
228-
className="w-[535px] rounded-xl"
229-
/>
230-
</div>
231-
</ModalBody>
232-
<ModalBaseFooter>
233-
<Button variant="secondary" onClick={handleVideoModalClose}>
234-
Close
235-
</Button>
236-
</ModalBaseFooter>
237-
</Modal>
238-
</>
239-
)}
237+
)}
238+
239+
<Modal
240+
visible={isVideoModalVisible}
241+
onClose={handleVideoModalClose}
242+
containerClassName="min-[576px]:max-w-[600px]"
243+
>
244+
<ModalHeader>Demo video</ModalHeader>
245+
<ModalBody>
246+
<div className="flex flex-row items-center justify-center">
247+
<VideoSection
248+
metadataVideoTitle="Gitpod demo"
249+
playbackId="m01BUvCkTz7HzQKFoIcQmK00Rx5laLLoMViWBstetmvLs"
250+
poster="https://i.ytimg.com/vi_webp/1ZBN-b2cIB8/maxresdefault.webp"
251+
playerProps={{ onPlay: handlePlay, defaultHiddenCaptions: true }}
252+
className="w-[535px] rounded-xl"
253+
/>
254+
</div>
255+
</ModalBody>
256+
<ModalBaseFooter>
257+
<Button variant="secondary" onClick={handleVideoModalClose}>
258+
Close
259+
</Button>
260+
</ModalBaseFooter>
261+
</Modal>
262+
</>
263+
)}
240264

241265
{deleteModalVisible && (
242266
<ConfirmationModal

0 commit comments

Comments
 (0)