Skip to content

Commit d5e1c64

Browse files
author
FalkWolsky
committed
Update Home Page
1 parent 79fcd60 commit d5e1c64

File tree

7 files changed

+110
-136
lines changed

7 files changed

+110
-136
lines changed

client/packages/lowcoder-design/src/icons/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ export { ReactComponent as HomeListIcon } from "./v1/icon-application-list.svg";
127127
export { ReactComponent as HomeCardIcon } from "./v1/icon-application-card.svg";
128128
export { ReactComponent as APIDocsIcon } from "./remix/instance-line.svg";
129129
export { ReactComponent as SubscriptionIcon } from "./remix/award-fill.svg";
130+
export { ReactComponent as SupportIcon } from "./remix/user-heart-line.svg";
130131
// export { ReactComponent as AllAppIcon } from "./v1/icon-all-app.svg";
131132

132133

client/packages/lowcoder/src/api/subscriptionApi.ts

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,29 @@ export interface SubscriptionItem {
9494
quantity: number;
9595
}
9696

97+
export interface Subscription {
98+
id: string;
99+
collection_method: string;
100+
current_period_end: number;
101+
current_period_start: number;
102+
product: string;
103+
currency: string;
104+
interval: string;
105+
tiers_mode: string;
106+
status: string;
107+
start_date: number;
108+
quantity: number;
109+
billing_scheme: string;
110+
price: string;
111+
}
112+
113+
export interface SubscriptionsData {
114+
subscriptions: Subscription[];
115+
subscriptionDataLoaded: boolean;
116+
subscriptionDataError: boolean;
117+
loading: boolean;
118+
}
119+
97120
export type ResponseType = {
98121
response: any;
99122
};
@@ -398,12 +421,28 @@ export const InitializeSubscription = () => {
398421
};
399422
};
400423

424+
export enum SubscriptionProducts {
425+
SUPPORT = "QW8L3WPMiNjQjI",
426+
MEDIAPACKAGE = 'standard',
427+
AZUREAPIS = 'premium',
428+
GOOGLEAPIS = 'enterprise',
429+
AWSAPIS = 'enterprise-global',
430+
PRIVATECLOUD = 'private-cloud',
431+
MATRIXCLOUD = 'matrix-cloud',
432+
AGORATOKENSERVER = 'agora-tokenserver',
433+
SIGNALSERVER = 'signal-server',
434+
DATABASE = 'database',
435+
STORAGE = 'storage',
436+
IOSAPP = 'ios-app',
437+
ANDROIDAPP = 'android-app',
438+
AUDITLOG = 'audit-log',
439+
APPLOG = 'app-log',
440+
ENVIRONMENTS = 'environments',
441+
GITREPOS = 'git-repos',
442+
}
401443

402-
403-
export const CheckSubscriptions = () => {
404-
const [customer, setCustomer] = useState<StripeCustomer | null>(null);
405-
const [customerDataError, setCustomerDataError] = useState<boolean>(false);
406-
const [subscriptions, setSubscriptions] = useState<SubscriptionItem[]>([]);
444+
export const checkSubscriptions = () => {
445+
const [subscriptions, setSubscriptions] = useState<Subscription[]>([]);
407446
const [subscriptionDataLoaded, setSubscriptionDataLoaded] = useState<boolean>(false);
408447
const [subscriptionDataError, setSubscriptionDataError] = useState<boolean>(false);
409448
const [loading, setLoading] = useState<boolean>(true);
@@ -433,7 +472,7 @@ export const CheckSubscriptions = () => {
433472
}
434473
};
435474
fetchCustomerAndSubscriptions();
436-
}, []);
475+
}, [subscriptionSearchCustomer]);
437476

438477
return {
439478
subscriptions,

client/packages/lowcoder/src/constants/routesURL.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export const NEWS_URL = "/news";
1010
export const ORG_HOME_URL = "/org/home";
1111
export const COMPONENT_DOC_URL = "/components";
1212
export const SETTING = "/setting";
13+
export const SUPPORT = `/support`;
1314
export const PERMISSION_SETTING = "/setting/permission";
1415
export const ORGANIZATION_SETTING = "/setting/organization";
1516
export const SUBSCRIPTION_SETTING = "/setting/subscription";

client/packages/lowcoder/src/i18n/locales/en.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3020,7 +3020,7 @@ export const en = {
30203020
"appMarketplace": "Application Marketplace",
30213021
"allApplications": "Your Apps",
30223022
"allModules": "Your Modules",
3023-
"allFolders": "All Folders",
3023+
"allFolders": "Your Folders",
30243024
"yourFolders" : "Your Folders",
30253025
"modules": "Modules",
30263026
"module": "Module",
@@ -3109,6 +3109,9 @@ export const en = {
31093109
"chooseNavType": "Please choose navigation type",
31103110
"createNavigation": "Create Navigation",
31113111
"howToUseAPI": "How to use the Open Rest API",
3112+
"support": "Support",
3113+
"supportTitle": "Lowcoder Support",
3114+
"supportContent": "If you have any questions or need help, please use the ticket system get your issue solved fast.",
31123115
},
31133116
"carousel": {
31143117
"dotPosition": "Navigation Dots position",

client/packages/lowcoder/src/pages/ApplicationV2/index.tsx

Lines changed: 49 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
MODULE_APPLICATIONS_URL,
1010
QUERY_LIBRARY_URL,
1111
SETTING,
12+
SUPPORT,
1213
TRASH_URL,
1314
// ADMIN_APP_URL,
1415
NEWS_URL,
@@ -26,6 +27,7 @@ import {
2627
HomeModuleIcon,
2728
HomeQueryLibraryIcon,
2829
HomeSettingIcon,
30+
SupportIcon,
2931
PlusIcon,
3032
PointIcon,
3133
RecyclerIcon,
@@ -34,7 +36,7 @@ import {
3436
EnterpriseIcon,
3537
UserIcon,
3638
} from "lowcoder-design";
37-
import React, { useEffect, useState } from "react";
39+
import React, { useEffect, useState, useMemo } from "react";
3840
import { fetchAllApplications, fetchHomeData } from "redux/reduxActions/applicationActions";
3941
import { getHomeOrg, normalAppListSelector } from "redux/selectors/applicationSelector";
4042
import { DatasourceHome } from "../datasource";
@@ -64,6 +66,7 @@ import Setting from "pages/setting";
6466
import { TypographyText } from "../../components/TypographyText";
6567
import { messageInstance } from "lowcoder-design/src/components/GlobalInstances";
6668
import { isEE } from "util/envUtils";
69+
import { checkSubscriptions, SubscriptionProducts } from "@lowcoder-ee/api/subscriptionApi";
6770

6871
// adding App Editor, so we can show Apps inside the Admin Area
6972
import AppEditor from "../editor/AppEditor";
@@ -149,24 +152,20 @@ const FolderName = (props: { id: string; name: string }) => {
149152
);
150153
};
151154

152-
const MoreFoldersWrapper = styled.div<{ $selected: boolean }>`
155+
const MoreFoldersWrapper = styled.div`
153156
${(props) => {
154-
if (props.$selected) {
155-
return css`
156-
font-weight: 500;
157-
`;
158-
}
157+
return css` font-weight: 500;`;
159158
}}
160159
`;
161160

162-
const MoreFoldersIcon = styled(PointIcon)<{ $selected: boolean }>`
161+
/* const MoreFoldersIcon = styled(PointIcon)<{ $selected: boolean }>`
163162
cursor: pointer;
164163
flex-shrink: 0;
165164
166165
g {
167166
fill: ${(props) => (props.$selected ? "#4965f2" : "#8b8fa3")};
168167
}
169-
`;
168+
`; */
170169

171170
const PopoverIcon = styled(PointIcon)`
172171
cursor: pointer;
@@ -188,26 +187,6 @@ const PopoverIcon = styled(PointIcon)`
188187
}
189188
`;
190189

191-
const InviteUser = styled.div`
192-
position: absolute;
193-
display: flex;
194-
align-items: center;
195-
left: 10px;
196-
top: calc(100vh - 60px);
197-
padding: 12px 26px;
198-
font-size: 14px;
199-
cursor: pointer;
200-
width: 219px;
201-
202-
&:hover {
203-
color: #315efb;
204-
205-
svg g g {
206-
stroke: #315efb;
207-
}
208-
}
209-
`;
210-
211190
const CreateFolderIcon = styled.div`
212191
margin-left: auto;
213192
cursor: pointer;
@@ -259,10 +238,29 @@ export default function ApplicationHome() {
259238
const orgHomeId = "root";
260239
const isSelfHost = window.location.host !== 'app.lowcoder.cloud';
261240

262-
const handleFolderCreate = useCreateFolder();
241+
const subscriptions = useSelector(state => state.subscriptions.subscriptions);
242+
const subscriptionDataLoaded = useSelector(state => !state.subscriptions.loading);
243+
const subscriptionDataError = useSelector(state => state.subscriptions.error);
244+
245+
// const handleFolderCreate = useCreateFolder();
263246

264247
const isOrgAdmin = org?.createdBy == user.id ? true : false;
265248

249+
// Fetch subscriptions once on component mount
250+
useEffect(() => {
251+
dispatch(checkSubscriptions());
252+
}, [dispatch]);
253+
254+
// Calculate support subscription status
255+
const supportSubscription = useMemo(() => {
256+
return subscriptions.some((sub: { product: SubscriptionProducts; }) => sub.product === SubscriptionProducts.SUPPORT);
257+
}, [subscriptions]);
258+
259+
// Early return if data is still loading or there was an error
260+
if (fetchingUser || !subscriptionDataLoaded || subscriptionDataError) {
261+
return <ProductLoading />;
262+
}
263+
266264
useEffect(() => {
267265
dispatch(fetchHomeData({}));
268266
}, [user.currentOrgId]);
@@ -298,52 +296,8 @@ export default function ApplicationHome() {
298296
return <ProductLoading />;
299297
}
300298

301-
let folderItems: SideBarItemType[] = allFolders
302-
.sort((a, b) => {
303-
if (a.createAt === b.createAt) {
304-
return 0;
305-
}
306-
return a.createAt < b.createAt ? 1 : -1;
307-
})
308-
.slice(0, 5)
309-
.map((folder) => {
310-
const path = FOLDER_URL_PREFIX + `/${folder.folderId}`;
311-
return {
312-
onSelected: (_, currentPath) => currentPath === path,
313-
text: (props: { selected?: boolean }) => (
314-
<FolderNameWrapper $selected={Boolean(props.selected)}>
315-
<FolderName name={folder.name} id={folder.folderId} />
316-
</FolderNameWrapper>
317-
),
318-
routePath: FOLDER_URL,
319-
routePathExact: false,
320-
routeComp: FolderView,
321-
icon: FolderIcon,
322-
size: "small",
323-
onClick: (currentPath) => currentPath !== path && history.push(path),
324-
};
325-
});
326-
327-
if (allFolders.length > 1) {
328-
folderItems = [
329-
...folderItems,
330-
{
331-
text: (props: { selected?: boolean }) => (
332-
<MoreFoldersWrapper $selected={Boolean(props.selected)}>{trans("home.allFolders")}</MoreFoldersWrapper>
333-
),
334-
routePath: FOLDERS_URL,
335-
routeComp: RootFolderListView,
336-
icon: MoreFoldersIcon,
337-
size: "small",
338-
},
339-
];
340-
}
341-
342-
if (folderItems.length > 0) {
343-
folderItems[folderItems.length - 1] = {
344-
...folderItems[folderItems.length - 1],
345-
style: { marginBottom: "4px" },
346-
};
299+
if (fetchingUser || !isPreloadCompleted || !subscriptionDataLoaded || subscriptionDataError) {
300+
return <ProductLoading />;
347301
}
348302

349303
return (
@@ -386,41 +340,21 @@ export default function ApplicationHome() {
386340

387341
{
388342
items: [
343+
{
344+
text: <MoreFoldersWrapper>{trans("home.allFolders")}</MoreFoldersWrapper>,
345+
routePath: FOLDERS_URL,
346+
routeComp: RootFolderListView,
347+
icon: ({ selected, ...otherProps }) => selected ? <FolderIcon {...otherProps} width={"24px"}/> : <FolderIcon {...otherProps} width={"24px"}/>,
348+
},
389349
{
390350
text: <TabLabel>{trans("home.allApplications")}</TabLabel>,
391351
routePath: ALL_APPLICATIONS_URL,
392352
routeComp: HomeView,
393353
icon: ({ selected, ...otherProps }) => selected ? <AppsIcon {...otherProps} width={"24px"}/> : <AppsIcon {...otherProps} width={"24px"}/>,
394354
},
395-
{
396-
text: <TabLabel>{trans("home.allModules")}</TabLabel>,
397-
routePath: MODULE_APPLICATIONS_URL,
398-
routeComp: ModuleView,
399-
icon: ({ selected, ...otherProps }) => selected ? <HomeModuleIcon {...otherProps} width={"24px"}/> : <HomeModuleIcon {...otherProps} width={"24px"}/>,
400-
visible: ({ user }) => isOrgAdmin,
401-
},
402-
403355
],
404356
},
405-
406-
allFolders.length > 0
407-
? {
408-
title: (
409-
<FolderSectionLabel>
410-
{trans("home.yourFolders")}
411-
<FolderCountLabel>{`(${allFolders.length})`}</FolderCountLabel>
412-
{user.orgDev && (
413-
<CreateFolderIcon onClick={handleFolderCreate}>
414-
<PlusIcon />
415-
</CreateFolderIcon>
416-
)}
417-
</FolderSectionLabel>
418-
),
419-
items: folderItems,
420-
style: { marginTop: "8px" },
421-
}
422-
: { items: [] },
423-
357+
424358
{
425359
items: [
426360

@@ -455,6 +389,17 @@ export default function ApplicationHome() {
455389
],
456390
} : { items: [] },
457391

392+
supportSubscription ? {
393+
items: [
394+
{
395+
text: <TabLabel>{trans("home.trash")}</TabLabel>,
396+
routePath: TRASH_URL,
397+
routeComp: TrashView,
398+
icon: ({ selected, ...otherProps }) => selected ? <RecyclerIcon {...otherProps} width={"24px"}/> : <RecyclerIcon {...otherProps} width={"24px"}/>,
399+
},
400+
],
401+
} : { items: [] },
402+
458403
{
459404
items: [
460405
{
@@ -465,7 +410,7 @@ export default function ApplicationHome() {
465410
icon: ({ selected, ...otherProps }) => selected ? <HomeSettingIcon {...otherProps} width={"24px"}/> : <HomeSettingIcon {...otherProps} width={"24px"}/>,
466411
visible: ({ user }) => user.orgDev,
467412
onSelected: (_, currentPath) => currentPath.split("/")[1] === "setting",
468-
},
413+
}
469414
]
470415
},
471416

@@ -483,20 +428,6 @@ export default function ApplicationHome() {
483428

484429
]}
485430
/>
486-
487-
{/*
488-
// we have the invite dialog in the Admin Area, so we don't need it here
489-
{user.orgDev && (
490-
<InviteDialog
491-
trigger={
492-
<InviteUser>
493-
<InviteUserIcon style={{ marginRight: "8px" }} />
494-
{trans("home.inviteUser")}
495-
</InviteUser>
496-
}
497-
style={{ marginLeft: "auto" }}
498-
/>
499-
)} */}
500431
</DivStyled>
501432
);
502433
}

0 commit comments

Comments
 (0)