Skip to content

Commit

Permalink
feat: updated app design for today page too
Browse files Browse the repository at this point in the history
  • Loading branch information
ImJustChew committed Aug 22, 2024
1 parent f0477bc commit 1a8f620
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 118 deletions.
119 changes: 119 additions & 0 deletions src/app/[lang]/(mods-pages)/apps/AppItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { apps } from "@/const/apps";
import { ExternalLink } from "lucide-react";
import React from "react";
import { useCallback } from "react";
import useDictionary from "@/dictionaries/useDictionary";
import { useHeadlessAIS } from "@/hooks/contexts/useHeadlessAIS";
import { useSettings } from "@/hooks/contexts/settings";
import { useRouter } from "next/navigation";
import { cn } from "@/lib/utils";
import { Dialog, DialogContent } from "@/components/ui/dialog";
import { toast } from "@/components/ui/use-toast";

const AppItem = ({
app,
mini = false,
}: {
app: (typeof apps)[number];
mini?: boolean;
}) => {
const { language } = useSettings();
const { ais, getACIXSTORE } = useHeadlessAIS();
const router = useRouter();
const dict = useDictionary();
const [aisLoading, setAisLoading] = React.useState(false);

const onItemClicked = useCallback(async () => {
if (app.ais) {
if (!ais.enabled) {
toast({ title: dict.ccxp.not_logged_in_error });
return;
}

setAisLoading(true);
const token = await getACIXSTORE();
if (!token) {
setAisLoading(false);
return;
}

// if starts with http, open in new tab
if (app.href.startsWith("https://www.ccxp.nthu.edu.tw")) {
// Redirect user
const redirect_url = app.href + `?ACIXSTORE=${token}`;
console.log(redirect_url);
const link = document.createElement("a");
link.href = redirect_url;
link.target = "_blank";
link.click();
} else {
router.push(app.href);
}
setAisLoading(false);
} else {
router.push(app.href);
}
}, [router, app, ais, getACIXSTORE, dict]);

return (
<div
className={cn(
!mini
? "flex flex-row items-center space-x-2 flex-1"
: "flex flex-col items-center space-y-1",
(app.ais && ais.enabled) || !app.ais
? "cursor-pointer"
: "cursor-not-allowed opacity-30",
)}
onClick={onItemClicked}
>
<div className="p-2 rounded-lg bg-nthu-100 text-nthu-800 grid place-items-center">
<app.Icon size={24} />
</div>
<div className="flex flex-col">
<h2
className={cn(!mini ? "font-medium" : "text-xs max-w-20 text-center")}
>
{language == "zh" ? app.title_zh : app.title_en}
</h2>
{!mini && app.href.startsWith("https://www.ccxp.nthu.edu.tw") && (
<h3 className="text-xs text-muted-foreground">
<ExternalLink size={12} className="inline" /> {dict.applist.to_ccxp}
</h3>
)}
</div>
<Dialog open={aisLoading} modal={true}>
<DialogContent>
<div className="flex flex-col items-center space-y-4">
<div className="flex flex-col space-y-4 items-center">
{/* <div className='animate-spin rounded-full h-16 w-16 border-2 border-gray-900'></div> */}
<svg
className="animate-spin h-14 w-14 text-gray-900 dark:text-gray-100"
viewBox="0 0 24 24"
>
<circle
className="opacity-0"
cx="12"
cy="12"
r="12"
stroke="currentColor"
strokeWidth="4"
></circle>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
></path>
</svg>
<p className="text-gray-700 dark:text-gray-500">
{dict.ccxp.logging_in_please_wait}
</p>
</div>
</div>
</DialogContent>
</Dialog>
</div>
);
};

export default AppItem;
104 changes: 2 additions & 102 deletions src/app/[lang]/(mods-pages)/apps/page.tsx
Original file line number Diff line number Diff line change
@@ -1,117 +1,17 @@
"use client";
import { apps, categories } from "@/const/apps";
import { ExternalLink, Settings, Star } from "lucide-react";
import React, { useCallback } from "react";
import { Settings, Star } from "lucide-react";
import useDictionary from "@/dictionaries/useDictionary";
import { useHeadlessAIS } from "@/hooks/contexts/useHeadlessAIS";
import { useSettings } from "@/hooks/contexts/settings";
import { useRouter } from "next/navigation";
import { cn } from "@/lib/utils";
import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog";
import { toast } from "@/components/ui/use-toast";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Button } from "@/components/ui/button";

const AppItem = ({ app }: { app: (typeof apps)[number] }) => {
const { language } = useSettings();
const { ais, getACIXSTORE } = useHeadlessAIS();
const router = useRouter();
const dict = useDictionary();
const [aisLoading, setAisLoading] = React.useState(false);

const onItemClicked = useCallback(async () => {
if (app.ais) {
if (!ais.enabled) {
toast({ title: dict.ccxp.not_logged_in_error });
return;
}

setAisLoading(true);
const token = await getACIXSTORE();
if (!token) {
setAisLoading(false);
return;
}

// if starts with http, open in new tab
if (app.href.startsWith("https://www.ccxp.nthu.edu.tw")) {
// Redirect user
const redirect_url = app.href + `?ACIXSTORE=${token}`;
console.log(redirect_url);
const link = document.createElement("a");
link.href = redirect_url;
link.target = "_blank";
link.click();
} else {
router.push(app.href);
}
setAisLoading(false);
} else {
router.push(app.href);
}
}, [router, app, ais, getACIXSTORE, dict]);

return (
<div
className={cn(
"flex flex-row items-center space-x-2 flex-1",
(app.ais && ais.enabled) || !app.ais
? "cursor-pointer"
: "cursor-not-allowed opacity-30",
)}
onClick={onItemClicked}
>
<div className="p-2 rounded-lg bg-nthu-100 text-nthu-800 grid place-items-center">
<app.Icon size={24} />
</div>
<div className="flex flex-col">
<h2 className=" font-medium">
{language == "zh" ? app.title_zh : app.title_en}
</h2>
{app.href.startsWith("https://www.ccxp.nthu.edu.tw") && (
<h3 className="text-xs text-muted-foreground">
<ExternalLink size={12} className="inline" /> {dict.applist.to_ccxp}
</h3>
)}
</div>
<Dialog open={aisLoading} modal={true}>
<DialogContent>
<div className="flex flex-col items-center space-y-4">
<div className="flex flex-col space-y-4 items-center">
{/* <div className='animate-spin rounded-full h-16 w-16 border-2 border-gray-900'></div> */}
<svg
className="animate-spin h-14 w-14 text-gray-900 dark:text-gray-100"
viewBox="0 0 24 24"
>
<circle
className="opacity-0"
cx="12"
cy="12"
r="12"
stroke="currentColor"
strokeWidth="4"
></circle>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
></path>
</svg>
<p className="text-gray-700 dark:text-gray-500">
{dict.ccxp.logging_in_please_wait}
</p>
</div>
</div>
</DialogContent>
</Dialog>
</div>
);
};
import AppItem from "./AppItem";

const AppList = () => {
const dict = useDictionary();
const { language, pinnedApps, toggleApp } = useSettings();
const { ais } = useHeadlessAIS();

return (
<div className="h-full w-full px-2">
Expand Down
19 changes: 3 additions & 16 deletions src/components/Today/TodaySchedule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import useTime from "@/hooks/useTime";
import { NoClassPickedReminder } from "./NoClassPickedReminder";
import { TimetableItemDrawer } from "@/components/Timetable/TimetableItemDrawer";
import AppItem from "@/app/[lang]/(mods-pages)/apps/AppItem";

const getRangeOfDays = (start: Date, end: Date) => {
const days = [];
Expand Down Expand Up @@ -132,23 +133,9 @@ const TodaySchedule: FC<{
if (applist.length == 0) return <></>;
return (
<div className="flex flex-col gap-1">
<h1 className="text-xs font-bold text-gray-500">
{dict.applist.title}
</h1>
<div className="flex flex-row flex-wrap gap-2 pb-2">
<div className="flex flex-row flex-wrap gap-2 pb-2 justify-evenly">
{applist.map((app, index) => (
<Link href={app.href} key={index}>
<div className="flex flex-col items-center justify-center p-2 gap-2 w-16">
<div className="p-3 rounded-full bg-nthu-200 text-nthu-800 grid place-items-center">
<app.Icon size={20} />
</div>
<div className="flex flex-col gap-1 flex-1">
<h2 className="text-xs font-medium text-gray-600 text-center line-clamp-2 break-all">
{language == "zh" ? app.title_zh : app.title_en}
</h2>
</div>
</div>
</Link>
<AppItem key={index} app={app} mini />
))}
</div>
</div>
Expand Down

0 comments on commit 1a8f620

Please sign in to comment.