Skip to content

Commit d0c0a0c

Browse files
authored
Merge pull request #174 from code0-tech/feat/#10
User profile View
2 parents 1af77a6 + 7917279 commit d0c0a0c

6 files changed

Lines changed: 127 additions & 10 deletions

File tree

src/app/(dashboard)/@tab/users/page.tsx renamed to src/app/(dashboard)/@tab/users/default.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
import React from "react";
44
import {ApplicationTabView} from "@edition/application/views/ApplicationTabView";
55

6-
const Page: React.FC = () => {
6+
const Default: React.FC = () => {
77
return <ApplicationTabView/>
88
}
99

10-
export default Page
10+
export default Default
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
export default function Page() {
2-
return null
3-
}
1+
import {UserPage} from "@edition/user/pages/UserPage";
2+
3+
export default UserPage

src/packages/ce/src/application/views/ApplicationBarView.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {UserService} from "@edition/user/services/User.service";
55
import {useRouter} from "next/navigation";
66
import React from "react";
77
import Link from "next/link";
8-
import {IconBuilding, IconFolders, IconInbox, IconLogout, IconSearch} from "@tabler/icons-react";
8+
import {IconBuilding, IconFolders, IconInbox, IconLogout, IconSearch, IconUser} from "@tabler/icons-react";
99
import {ApplicationBreadcrumbView} from "@edition/application/views/ApplicationBreadcrumbView";
1010
import UserMenuComponent from "@edition/user/components/UserMenuComponent";
1111
import {useUserSession} from "@edition/user/hooks/User.session.hook";
@@ -20,6 +20,7 @@ export const ApplicationBarView: React.FC = () => {
2020

2121
const currentUser = React.useMemo(() => userService.getById(currentSession?.user?.id), [userStore, currentSession])
2222
const namespaceIndex = React.useMemo(() => currentUser?.namespace?.id?.match(/Namespace\/(\d+)$/)?.[1], [currentUser])
23+
const userIndex = currentUser?.id?.match(/User\/(\d+)$/)?.[1]
2324

2425
const userMenu = React.useMemo(() => {
2526

@@ -39,6 +40,12 @@ export const ApplicationBarView: React.FC = () => {
3940
}
4041

4142
return <UserMenuComponent userId={currentSession.user?.id!!}>
43+
<Link href={`/users/${userIndex}`}>
44+
<MenuItem>
45+
<IconUser size={16}/>Profile
46+
</MenuItem>
47+
</Link>
48+
<MenuSeparator/>
4249
<Link href={"/organizations"}>
4350
<MenuItem>
4451
<IconBuilding size={16}/>Organizations

src/packages/ce/src/application/views/ApplicationTabView.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ export const ApplicationTabView: React.FC = () => {
2828
: pathname.includes("runtimes") ? "runtimes"
2929
: "overview"
3030

31-
3231
const adminLinks = React.useMemo(() => {
3332
return currentUser && currentUser.admin ? (
3433
<>
@@ -54,7 +53,7 @@ export const ApplicationTabView: React.FC = () => {
5453
) : null
5554
}, [currentUser, runtimeStore, organizationStore])
5655

57-
return <Tab defaultValue={defaultValue} orientation={"vertical"}>
56+
return <Tab defaultValue={defaultValue} key={defaultValue} orientation={"vertical"}>
5857
<TabList>
5958
<TabTrigger value={"overview"} asChild={true}>
6059
<Button variant={"none"} color={"primary"} paddingSize={"xs"} onClick={() => router.push("/")}>
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
"use client"
2+
3+
import React from "react";
4+
import {Layout} from "@code0-tech/pictor/dist/components/layout/Layout";
5+
import {useParams} from "next/navigation";
6+
import {
7+
AuroraBackground,
8+
Avatar,
9+
Badge,
10+
Button,
11+
Col,
12+
Flex,
13+
ScrollArea,
14+
ScrollAreaViewport,
15+
Spacing,
16+
Text,
17+
useService,
18+
useStore
19+
} from "@code0-tech/pictor";
20+
import {UserService} from "@edition/user/services/User.service";
21+
import {useUserSession} from "@edition/user/hooks/User.session.hook";
22+
import {User} from "@code0-tech/sagittarius-graphql-types";
23+
import {IconMail, IconSparkles, IconUser} from "@tabler/icons-react";
24+
25+
export const UserPage: React.FC = () => {
26+
27+
28+
const params = useParams()
29+
const userService = useService(UserService)
30+
const userStore = useStore(UserService)
31+
32+
const userIndex = params.userId as any as number
33+
const userId: User['id'] = `gid://sagittarius/User/${userIndex}`
34+
35+
const currentSession = useUserSession()
36+
const currentUser = React.useMemo(
37+
() => userService.getById(currentSession?.user?.id),
38+
[userStore, currentSession]
39+
)
40+
41+
const user = React.useMemo(
42+
() => userService.getById(userId),
43+
[userStore, userId, userService]
44+
)
45+
46+
47+
const leftContent = <ScrollArea h={"100%"} type={"scroll"}>
48+
<ScrollAreaViewport>
49+
<Flex pr={0.7} miw={"17vw"} style={{flexDirection: "column"}}>
50+
<div style={{position: "relative"}}>
51+
<Avatar type={"character"} size={150} identifier={user?.username!}/>
52+
<Badge pos={"absolute"} right={"20%"} bottom={"20%"}>
53+
<Text size={"md"}>👋</Text>
54+
</Badge>
55+
</div>
56+
<Spacing spacing={"xs"}/>
57+
<Text size={"xl"} hierarchy={"primary"}>{user?.firstname} {user?.lastname}</Text>
58+
<Spacing spacing={"xs"}/>
59+
<Flex style={{flexDirection: "column", gap: "0.7rem"}}>
60+
<Text display={"flex"} align={"center"} size={"sm"} style={{gap: "0.7rem"}}>
61+
<IconUser size={16}/>
62+
@{user?.username}
63+
</Text>
64+
<Text display={"flex"} align={"center"} size={"sm"} style={{gap: "0.7rem"}}>
65+
<IconMail size={16}/>
66+
{user?.email}
67+
</Text>
68+
<Text display={"flex"} align={"center"} size={"sm"} style={{gap: "0.7rem"}}>
69+
<IconSparkles size={16}/>
70+
<Badge color={"primary"}>BASIC</Badge>
71+
</Text>
72+
</Flex>
73+
<Spacing spacing={"xs"}/>
74+
{currentUser?.id === userId && (
75+
<>
76+
<Spacing spacing={"xs"}/>
77+
<Button w={"100%"} color={"tertiary"}>Edit Profile</Button>
78+
<Spacing spacing={"xs"}/>
79+
<Button color={"primary"} w={"100%"}>
80+
Upgrade to Pro
81+
<AuroraBackground/>
82+
</Button>
83+
</>
84+
)}
85+
</Flex>
86+
</ScrollAreaViewport>
87+
</ScrollArea>
88+
89+
return <Layout showLayoutSplitter={false} layoutGap={"0"} leftContent={leftContent}>
90+
<div style={{
91+
background: "#070514",
92+
height: "100%",
93+
padding: "1rem",
94+
borderTopLeftRadius: "1rem",
95+
borderTopRightRadius: "1rem"
96+
}}>
97+
<Flex h={"100%"} w={"100%"} align={"center"} justify={"center"}>
98+
<Col xs={4} style={{textAlign: "center"}}>
99+
<Text size={"xl"} hierarchy={"primary"}>
100+
@{user?.username}'s readme
101+
</Text>
102+
<Spacing spacing={"xs"}/>
103+
<Text>
104+
The user currently does not have a publicly available profile description.
105+
</Text>
106+
</Col>
107+
</Flex>
108+
</div>
109+
</Layout>
110+
}
111+

src/packages/core/src/util/graphql-client.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ export class GraphqlClient {
108108
});
109109
if (!next) break;
110110

111-
// Variablen für die nächste Page
111+
// Variablen für die nächste Default
112112
const nextVars: Record<string, any> = { ...(options.variables as any) };
113113
if (next.afterVar) {
114114
nextVars[next.afterVar] = getAt(aggregated, next.path)?.pageInfo?.endCursor;
@@ -117,7 +117,7 @@ export class GraphqlClient {
117117
nextVars[next.firstVar] = (options.variables as any)[next.firstVar];
118118
}
119119

120-
// Page-Request (netzwerkbasiert, um sicher zu gehen)
120+
// Default-Request (netzwerkbasiert, um sicher zu gehen)
121121
const page = await this._client.query<TData, TVariables>({
122122
...options,
123123
variables: nextVars as TVariables,

0 commit comments

Comments
 (0)