Penerapan UI Home

# style:
- Tampilan home dan loading
## No issue
This commit is contained in:
2024-06-25 15:47:49 +08:00
parent 1a157846c1
commit 96fb9a8512
11 changed files with 407 additions and 161 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

View File

@@ -2,7 +2,7 @@ import { Event_SplashScreen } from "@/app_modules/event";
export default async function Page() {
// await new Promise((a, b) => {
// setTimeout(a, 1000);
// setTimeout(a, 3000);
// });
return <Event_SplashScreen />;
}

View File

@@ -3,7 +3,7 @@ import ComponentGlobal_V2_LoadingPage from "@/app_modules/component_global/loadi
export default async function Page() {
return (
<>
<ComponentGlobal_V2_LoadingPage />
{/* <ComponentGlobal_V2_LoadingPage /> */}
</>
);
}

View File

@@ -1,17 +1,15 @@
import { HomeView } from "@/app_modules/home";
import { cookies } from "next/headers";
import { unsealData } from "iron-session";
import _ from "lodash";
import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token";
import { user_getOneByUserId } from "@/app_modules/home/fun/get/get_one_user_by_id";
import { redirect } from "next/navigation";
import { RouterAdminDashboard } from "@/app/lib/router_hipmi/router_admin";
import { RouterHome } from "@/app/lib/router_hipmi/router_home";
import ComponentGlobal_V2_LoadingPage from "@/app_modules/component_global/loading_page_v2";
import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token";
import { HomeView } from "@/app_modules/home";
import { user_getOneByUserId } from "@/app_modules/home/fun/get/get_one_user_by_id";
import { job_getTwoForHomeView } from "@/app_modules/job/fun/get/get_two_for_home_view";
import { redirect } from "next/navigation";
export default async function Page() {
const userId = await user_getOneUserId();
const dataUser = await user_getOneByUserId(userId);
const dataJob = await job_getTwoForHomeView();
if (dataUser?.active === false) {
return redirect(RouterHome.home_user_non_active);
@@ -23,12 +21,12 @@ export default async function Page() {
// if (dataUser?.Profile === null) return <ComponentGlobal_V2_LoadingPage />;
// await new Promise((a, b) => {
// setTimeout(a, 4000);
// setTimeout(a, 3000);
// });
return (
<>
<HomeView dataUser={dataUser as any} />
<HomeView dataUser={dataUser as any} dataJob={[]} />
</>
);
}

View File

@@ -1,9 +1,16 @@
import Coba_TestLoading from "@/app_modules/zCoba";
export default async function Page() {
await new Promise((a, b) => {
setTimeout(a, 3000);
});
return (
<>
<Coba_TestLoading />
</>
);
}

View File

@@ -2,10 +2,20 @@
import { Center } from "@mantine/core";
export default function ComponentGlobal_IsEmptyData({ text }: { text: string }) {
export default function ComponentGlobal_IsEmptyData({
text,
height,
}: {
text: string;
height?: number}) {
return (
<>
<Center h={"50vh"} fz={"sm"} fw={"bold"} c={"gray"}>
<Center
h={height ? `${height}vh` : "50vh"}
fz={"sm"}
fw={"bold"}
c={"gray"}
>
{text}
</Center>
</>

View File

@@ -1,43 +1,56 @@
"use client";
import { Box, Center, Group, LoadingOverlay, Skeleton, Text } from "@mantine/core";
import {
Box,
Center,
Group,
LoadingOverlay,
Skeleton,
Text,
} from "@mantine/core";
import { MainColor } from "./color/color_pallet";
export default function ComponentGlobal_V2_LoadingPage() {
const listhHuruf = [
{
huruf: "H",
},
{
huruf: "I",
},
{
huruf: "P",
},
{
huruf: "M",
},
{
huruf: "I",
},
];
const customLOader = (
<Center h={"100vh"}>
<Group>
{listhHuruf.map((e, i) => (
<Center key={i} h={"100%"}>
<Skeleton height={50} circle radius={"100%"} />
<Text sx={{ position: "absolute" }} c={"gray.4"} fw={"bold"}>
{e.huruf}
</Text>
</Center>
))}
</Group>
</Center>
);
const listhHuruf = [
{
huruf: "H",
},
{
huruf: "I",
},
{
huruf: "P",
},
{
huruf: "M",
},
{
huruf: "I",
},
];
const customLOader = (
<Center h={"100vh"}>
<Group>
{listhHuruf.map((e, i) => (
<Center key={i} h={"100%"}>
<Skeleton height={50} circle radius={"100%"} />
<Text sx={{ position: "absolute" }} c={"gray.4"} fw={"bold"}>
{e.huruf}
</Text>
</Center>
))}
</Group>
</Center>
);
return (
<>
<LoadingOverlay visible overlayBlur={1} loader={customLOader} />
</>
);
return (
<>
<LoadingOverlay
visible
overlayColor={MainColor.darkblue}
overlayOpacity={0.3}
loader={customLOader}
/>
</>
);
}

View File

@@ -3,6 +3,7 @@ import {
ActionIcon,
AppShell,
Avatar,
BackgroundImage,
Box,
Center,
Flex,
@@ -12,6 +13,8 @@ import {
Header,
Indicator,
Loader,
Paper,
ScrollArea,
SimpleGrid,
Stack,
Text,
@@ -25,6 +28,9 @@ import {
IconQrcode,
IconUserCircle,
IconBell,
IconMessages,
IconShoppingBag,
IconMap2,
} from "@tabler/icons-react";
import { Logout } from "../auth";
import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog";
@@ -38,6 +44,8 @@ import { RouterNotifikasi } from "@/app/lib/router_hipmi/router_notifikasi";
import { useShallowEffect } from "@mantine/hooks";
import notifikasi_countUserNotifikasi from "../notifikasi/fun/count/fun_count_by_id";
import mqtt_client from "@/util/mqtt_client";
import { AccentColor, MainColor } from "../component_global/color/color_pallet";
import { RouterForum } from "@/app/lib/router_hipmi/router_forum";
export default function HomeLayout({
dataUser,
@@ -50,13 +58,38 @@ export default function HomeLayout({
}) {
const router = useRouter();
// const [user, setUser] = useState(dataUser);
const [loadingProfil, setLoadingProfile] = useState(false);
const [loadingUS, setLoadingUS] = useState(false);
const [idLoadingProfil, setIsLoadingProfile] = useState(false);
const [isLoadingUS, setIsLoadingUS] = useState(false);
const [isLoadingBell, setIsLoadingBell] = useState(false);
const [isLoadingPage, setIsLoadingPage] = useState(false);
const [pageId, setPageId] = useState(0);
const [countNotif, setCountNotif] = useState(countNotifikasi);
const listHalamanFooter = [
{
id: 1,
name: "Forums",
icon: <IconMessages />,
link: RouterForum.splash,
},
{
id: 2,
name: "MarketPlace",
icon: <IconShoppingBag />,
link: "",
},
{
id: 3,
name: "Business Maps",
icon: <IconMap2 />,
link: "",
},
];
useShallowEffect(() => {
mqtt_client.subscribe("USER");
// mqtt_client.subscribe("Notifikasi_forum_create_komentar");
mqtt_client.on("message", (topic: any, message: any) => {
console.log(topic);
@@ -81,99 +114,166 @@ export default function HomeLayout({
return (
<>
<Box>
<BackgroundImage
src={"/aset/global/main_background.png"}
h={"100vh"}
pos={"static"}
>
{/* Header */}
<Box
style={{
zIndex: 99,
zIndex: 98,
}}
w={"100%"}
bg={"black"}
bg={MainColor.darkblue}
pos={"sticky"}
top={0}
h={50}
h={"8vh"}
>
<Group position="apart" h={"100%"} px={"md"}>
<ActionIcon variant="transparent" disabled></ActionIcon>
<ActionIcon
radius={"xl"}
variant={"transparent"}
onClick={() => {
if (dataUser?.Profile === null) {
ComponentGlobal_NotifikasiPeringatan("Lengkapi Profile");
} else {
setIsLoadingUS(true);
router.push(RouterUserSearch.main);
}
}}
>
{isLoadingUS ? (
<Loader size={20} />
) : (
<IconUserSearch color="white" />
)}
</ActionIcon>
<Center>
<Title order={4} c={"white"}>
<Title order={4} c={MainColor.yellow}>
HIPMI
</Title>
</Center>
<ActionIcon
variant="transparent"
onClick={() => {
router.push(RouterNotifikasi.main);
if (dataUser?.Profile === null) {
ComponentGlobal_NotifikasiPeringatan("Lengkapi Profile");
} else {
router.push(RouterNotifikasi.main);
setIsLoadingBell(true);
}
}}
>
<Indicator processing label={<Text fz={10}>{countNotif}</Text>}>
<IconBell />
</Indicator>
{isLoadingBell ? (
<Loader size={20} />
) : (
<Indicator
processing
color={MainColor.yellow}
label={<Text fz={10}>{countNotif}</Text>}
>
<IconBell color="white" />
</Indicator>
)}
</ActionIcon>
</Group>
</Box>
{/* Children */}
<Box p={"sm"} pos={"static"}>
<Stack>
<Box h={"82vh"} pos={"static"}>
<ScrollArea h={"100%"}>
{/* {Array(10)
.fill(0)
.map((e, i) => (
<Paper key={i} withBorder p={"lg"} h={100}>
{i + 1}
</Paper>
))} */}
{children}
<Box
style={{
height: "10vh",
}}
></Box>
</Stack>
</ScrollArea>
<Box
style={{
height: "10vh",
}}
/>
</Box>
{/* <Box h={"100%"} pos={"static"}>
<ScrollArea h={"100%"}>{children}</ScrollArea>
<Box
style={{
height: "10vh",
}}
/>
</Box> */}
{/* Footer */}
<Box
style={{
zIndex: 99,
borderRadius: "20px 20px 0px 0px",
}}
bg={MainColor.darkblue}
w={"100%"}
bg={"black"}
color="blue"
pos={"fixed"}
bottom={0}
h={"10vh"}
>
<SimpleGrid cols={2}>
<Center h={"10vh"}>
{loadingUS ? (
<Center>
<Loader />
</Center>
) : (
<Center>
<Stack
align="center"
spacing={0}
onClick={() => {
if (dataUser?.Profile === null) {
ComponentGlobal_NotifikasiPeringatan(
"Lengkapi Profile"
);
} else {
setLoadingUS(true);
// router.push(RouterProfile.katalog + `${user.Profile.id}`);
router.push(RouterUserSearch.main);
}
}}
>
<ActionIcon variant={"transparent"}>
<IconUserSearch color="white" />
<SimpleGrid
bg={AccentColor.darkblue}
cols={4}
style={{
borderRadius: "20px 20px 0px 0px",
border: `1px solid ${AccentColor.blue}`,
}}
>
{listHalamanFooter.map((e, i) => (
<Center h={"10vh"} key={e.id}>
{isLoadingPage && e.id === pageId ? (
<Center>
<Loader size={"sm"} />
</Center>
) : (
<Stack align="center" spacing={0}>
<ActionIcon
radius={"xl"}
// loading={isLoadingPage && e.id === pageId ? true : false}
c={e.link === "" ? "gray" : "white"}
variant="transparent"
onClick={() => {
if (dataUser?.Profile === null) {
ComponentGlobal_NotifikasiPeringatan(
"Lengkapi Profile"
);
} else {
e.link === ""
? ComponentGlobal_NotifikasiPeringatan(
"Cooming Soon"
)
: (router.push(e.link),
setIsLoadingPage(true),
setPageId(e?.id));
}
}}
>
{e.icon}
</ActionIcon>
<Text fz={"xs"} c={"white"}>
Temukan pengguna
<Text c={e.link === "" ? "gray" : "white"} fz={"xs"}>
{e.name}
</Text>
</Stack>
</Center>
)}
</Center>
)}
</Center>
))}
<Center h={"10vh"}>
{loadingProfil ? (
{idLoadingProfil ? (
<Center>
<Loader />
<Loader size={"sm"} />
</Center>
) : (
<Center>
@@ -181,7 +281,7 @@ export default function HomeLayout({
align="center"
spacing={2}
onClick={() => {
setLoadingProfile(true);
setIsLoadingProfile(true);
if (dataUser?.Profile === null) {
router.push(RouterProfile.create);
} else {
@@ -219,7 +319,7 @@ export default function HomeLayout({
</Center>
</SimpleGrid>
</Box>
</Box>
</BackgroundImage>
</>
);
}

View File

@@ -2,14 +2,19 @@
import {
ActionIcon,
BackgroundImage,
Box,
Center,
Flex,
Group,
Image,
Loader,
LoadingOverlay,
Paper,
ScrollArea,
SimpleGrid,
Skeleton,
Stack,
Text,
ThemeIcon,
Title,
@@ -25,6 +30,7 @@ import {
IconPresentation,
IconShoppingBag,
IconUserCircle,
IconUserSearch,
} from "@tabler/icons-react";
import toast from "react-simple-toasts";
@@ -41,27 +47,35 @@ import { useDisclosure } from "@mantine/hooks";
import { RouterForum } from "@/app/lib/router_hipmi/router_forum";
import ComponentGlobal_V2_LoadingPage from "../component_global/loading_page_v2";
import { RouterColab } from "@/app/lib/router_hipmi/router_colab";
import { AccentColor, MainColor } from "../component_global/color/color_pallet";
import { MODEL_JOB } from "../job/model/interface";
import _ from "lodash";
import ComponentGlobal_IsEmptyData from "../component_global/is_empty_data";
export default function HomeView({ dataUser }: { dataUser: MODEL_USER }) {
export default function HomeView({
dataUser,
dataJob,
}: {
dataUser: MODEL_USER;
dataJob: MODEL_JOB[];
}) {
const router = useRouter();
// const [stateUser, setStateUser] = useState(user);
const [loading, setLoading] = useState(false);
const [visible, { toggle }] = useDisclosure(false);
const listHalaman = [
const listPageOnBox = [
{
id: 1,
name: "Forums",
icon: <IconMessages size={50} />,
link: RouterForum.splash,
},
{
id: 2,
name: "Event",
icon: <IconPresentation size={50} />,
link: RouterEvent.splash,
},
{
id: 2,
name: "Project Collaboration",
icon: <IconAffiliate size={50} />,
link: RouterColab.splash,
},
{
id: 3,
@@ -69,51 +83,38 @@ export default function HomeView({ dataUser }: { dataUser: MODEL_USER }) {
icon: <IconPackageImport size={50} />,
link: RouterVote.splash,
},
{
id: 4,
name: "Project Collaboration",
icon: <IconAffiliate size={50} />,
link: RouterColab.splash,
},
{
id: 5,
name: "Crowd Funding",
icon: <IconHeartHandshake size={50} />,
link: `/dev/crowd/splash`,
},
{
id: 6,
name: "Job Vacancy",
icon: <IconBriefcase size={50} />,
link: RouterJob.spalsh,
},
{
id: 7,
name: "Business Maps",
icon: <IconMap2 size={50} />,
link: "",
},
{
id: 8,
name: "Marketplace",
icon: <IconShoppingBag size={50} />,
link: "",
},
];
const routePageJob = {
name: "Job Vacancy",
icon: <IconBriefcase size={50} />,
link: RouterJob.spalsh,
};
return (
<>
{visible ? <ComponentGlobal_V2_LoadingPage /> : ""}
<Box>
<Paper bg={"dark"} radius={5} mb={"xs"}>
<Image alt="logo" src={"/aset/home/home-hipmi.png"} />
<Box p={"md"}>
<Paper
radius={"xl"}
mb={"xs"}
style={{
borderRadius: "10px 10px 10px 10px",
border: `2px solid ${AccentColor.blue}`,
}}
>
<Image radius={"lg"} alt="logo" src={"/aset/home/home-hipmi.png"} />
</Paper>
{/* <pre>{JSON.stringify(stateUser, null, 2)}</pre> */}
<Box my={"sm"}>
<Stack my={"sm"}>
<SimpleGrid
cols={2}
spacing="md"
@@ -123,11 +124,15 @@ export default function HomeView({ dataUser }: { dataUser: MODEL_USER }) {
// { maxWidth: 'xs', cols: 1, spacing: 'xs' },
// ]}
>
{listHalaman.map((e, i) => (
{listPageOnBox.map((e, i) => (
<Paper
key={e.id}
h={100}
withBorder
h={150}
bg={MainColor.darkblue}
style={{
borderRadius: "10px 10px 10px 10px",
border: `2px solid ${AccentColor.blue}`,
}}
onClick={() => {
if (dataUser.Profile === null) {
return ComponentGlobal_NotifikasiPeringatan(
@@ -145,27 +150,89 @@ export default function HomeView({ dataUser }: { dataUser: MODEL_USER }) {
}
}}
>
<Flex
justify={"center"}
align={"center"}
direction={"column"}
h={100}
>
<Stack align="center" justify="center" h={"100%"}>
<ActionIcon
size={50}
variant="transparent"
color={e.link === "" ? "gray.3" : "teal"}
c={e.link === "" ? "gray.3" : "white"}
>
{e.icon}
</ActionIcon>
<Text c={e.link === "" ? "gray.3" : "teal"} fz={"sm"}>
<Text c={e.link === "" ? "gray.3" : "white"} fz={"sm"}>
{e.name}
</Text>
</Flex>
</Stack>
</Paper>
))}
</SimpleGrid>
</Box>
{/* Job View */}
<Paper
p={"md"}
w={"100%"}
bg={MainColor.darkblue}
style={{
borderRadius: "10px 10px 10px 10px",
border: `2px solid ${AccentColor.blue}`,
}}
>
<Stack
onClick={() => {
if (dataUser.Profile === null) {
return ComponentGlobal_NotifikasiPeringatan(
"Lengkapi Data Profile"
);
} else {
if (routePageJob.link === "") {
return ComponentGlobal_NotifikasiPeringatan(
"Cooming Soon !!"
);
} else {
toggle();
return router.push(routePageJob.link);
}
}
}}
>
<Group>
<ActionIcon
size={40}
c={routePageJob.link === "" ? "gray.3" : "white"}
>
{routePageJob.icon}
</ActionIcon>
<Text c={routePageJob.link === "" ? "gray.3" : "white"}>
{routePageJob.name}
</Text>
</Group>
{_.isEmpty(dataJob) ? (
<ComponentGlobal_IsEmptyData text="-" height={10} />
) : (
<SimpleGrid cols={2} spacing="md">
{dataJob.map((e, i) => (
<Stack key={e.id}>
<Group spacing={"xs"}>
<Stack h={"100%"} align="center" justify="flex-start">
<IconUserSearch size={20} color="white" />
</Stack>
<Stack spacing={0} w={"80%"}>
<Text c={MainColor.yellow} fw={"bold"}>
{e?.Author.username}
</Text>
<Text c={"white"} lineClamp={2} fz={"sm"}>
{e?.title}
</Text>
</Stack>
</Group>
</Stack>
))}
</SimpleGrid>
)}
</Stack>
</Paper>
</Stack>
</Box>
</>
);

View File

@@ -0,0 +1,28 @@
"use server";
import prisma from "@/app/lib/prisma";
export async function job_getTwoForHomeView() {
const get = await prisma.job.findMany({
take: 2,
orderBy: {
createdAt: "desc",
},
where: {
isActive: true,
},
select: {
id: true,
Author: {
select: {
id: true,
username: true,
},
},
title: true,
deskripsi: true
},
});
return get;
}

View File

@@ -1,6 +1,7 @@
"use client";
import {
BackgroundImage,
Box,
Button,
Center,
@@ -21,6 +22,7 @@ import { v4 as uuidv4 } from "uuid";
import { useShallowEffect } from "@mantine/hooks";
import { ScrollOnly } from "next-scroll-loader";
import _ from "lodash";
import ComponentGlobal_V2_LoadingPage from "../component_global/loading_page_v2";
const newData = Array(20)
.fill(0)
@@ -70,6 +72,27 @@ export default function Coba_TestLoading() {
const [data, setData] = useState(data2);
return (
<>
<BackgroundImage src={"/aset/global/main_background.png"}>
<Box h={"100vh"}>Apa</Box>
</BackgroundImage>
</>
);
return (
<>
<Box h={"100%"} bg={"blue"}>
{Array(50)
.fill(0)
.map((e, i) => (
<Text key={i}>{i + 1}</Text>
))}
<ComponentGlobal_V2_LoadingPage />
</Box>
</>
);
return (
<>
<Box mt={"lg"}>