MingruiZhang commited on
Commit
cb6fbf2
1 Parent(s): 96ac62a

feat: project card more info (#28)

Browse files

<img width="1904" alt="image"
src="https://github.com/landing-ai/vision-agent-ui/assets/5669963/8a2ed136-fab5-4a44-9fb9-0ffad32cbc15">

app/project/layout.tsx CHANGED
@@ -1,12 +1,20 @@
1
  import ProjectListSideBar from '@/components/project-sidebar/ProjectListSideBar';
2
  import { Suspense } from 'react';
3
  import Loading from '@/components/ui/Loading';
 
 
4
 
5
  interface ChatLayoutProps {
6
  children: React.ReactNode;
7
  }
8
 
9
  export default async function Layout({ children }: ChatLayoutProps) {
 
 
 
 
 
 
10
  return (
11
  <div className="relative flex h-[calc(100vh_-_theme(spacing.16))] overflow-hidden">
12
  <div
 
1
  import ProjectListSideBar from '@/components/project-sidebar/ProjectListSideBar';
2
  import { Suspense } from 'react';
3
  import Loading from '@/components/ui/Loading';
4
+ import { authEmail } from '@/auth';
5
+ import { redirect } from 'next/navigation';
6
 
7
  interface ChatLayoutProps {
8
  children: React.ReactNode;
9
  }
10
 
11
  export default async function Layout({ children }: ChatLayoutProps) {
12
+ const { isAdmin } = await authEmail();
13
+
14
+ if (!isAdmin) {
15
+ redirect('/');
16
+ }
17
+
18
  return (
19
  <div className="relative flex h-[calc(100vh_-_theme(spacing.16))] overflow-hidden">
20
  <div
components/project-sidebar/ProjectCard.tsx CHANGED
@@ -11,14 +11,25 @@ export interface ProjectCardProps {
11
  projectInfo: ProjectBaseInfo;
12
  }
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  const ProjectCard: React.FC<ProjectCardProps> = ({ projectInfo }) => {
15
- const {
16
- id,
17
- name,
18
- created_at,
19
- label_type,
20
- organization: { name: orgName },
21
- } = projectInfo;
22
 
23
  const { projectId: projectIdFromParam } = useParams();
24
 
@@ -31,10 +42,20 @@ const ProjectCard: React.FC<ProjectCardProps> = ({ projectInfo }) => {
31
  )}
32
  href={`/project/${id}`}
33
  >
34
- <div className="overflow-hidden">
35
- <p className="text-xs text-gray-500">{orgName}</p>
36
- <p className="text-sm font-medium text-gray mb-1">{name}</p>
37
- <p className="text-xs text-gray-500">{formattedDate}</p>
 
 
 
 
 
 
 
 
 
 
38
  </div>
39
  </Link>
40
  );
 
11
  projectInfo: ProjectBaseInfo;
12
  }
13
 
14
+ export enum LabelType {
15
+ BoundingBox = 'bounding_box',
16
+ Segmentation = 'segmentation',
17
+ Classification = 'classification',
18
+ AnomalyDetection = 'anomaly_detection',
19
+ SegmentationInstantLearning = 'segmentation_instant_learning',
20
+ }
21
+
22
+ const LabelTypeDisplayText: { [key: string]: string } = {
23
+ [LabelType.BoundingBox]: 'detection',
24
+ [LabelType.Segmentation]: 'segmentation',
25
+ [LabelType.Classification]: 'classification',
26
+ [LabelType.AnomalyDetection]: 'anomaly',
27
+ [LabelType.SegmentationInstantLearning]: 'vp',
28
+ };
29
+
30
  const ProjectCard: React.FC<ProjectCardProps> = ({ projectInfo }) => {
31
+ const { id, name, created_at, label_type, orgName, subscription } =
32
+ projectInfo;
 
 
 
 
 
33
 
34
  const { projectId: projectIdFromParam } = useParams();
35
 
 
42
  )}
43
  href={`/project/${id}`}
44
  >
45
+ <div className="overflow-hidden w-full">
46
+ <div className="flex items-center justify-between w-full">
47
+ <p className="text-xs text-gray-500 truncate mr-2 truncate">
48
+ {orgName}
49
+ </p>
50
+ <p className="text-xs text-gray-500 italic">{subscription}</p>
51
+ </div>
52
+ <div className="flex mb-1 items-center">
53
+ <p className="text-sm font-medium text-gray mr-2 truncate">{name}</p>
54
+ <Chip value={LabelTypeDisplayText[label_type]} />
55
+ </div>
56
+ <div className="flex items-center truncate">
57
+ <p className="text-xs text-gray-500">{formattedDate}</p>
58
+ </div>
59
  </div>
60
  </Link>
61
  );
components/ui/Chip.tsx CHANGED
@@ -3,20 +3,18 @@ import { cn } from '@/lib/utils';
3
  export interface ChipProps {
4
  label?: string;
5
  value: string;
6
- color?: 'gray' | 'blue';
7
  className?: string;
8
  }
9
 
10
- const Chip: React.FC<ChipProps> = ({
11
- label,
12
- value,
13
- color = 'gray',
14
- className,
15
- }) => {
16
  return (
17
  <div
18
  className={cn(
19
- `inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-${color}-100 text-${color}-800 mr-1`,
 
 
 
20
  className,
21
  )}
22
  >
 
3
  export interface ChipProps {
4
  label?: string;
5
  value: string;
6
+ color?: 'gray' | 'blue' | 'yellow' | 'purple';
7
  className?: string;
8
  }
9
 
10
+ const Chip: React.FC<ChipProps> = ({ label, value, className, color }) => {
 
 
 
 
 
11
  return (
12
  <div
13
  className={cn(
14
+ `inline-flex items-center px-1.5 rounded-full text-xs bg-gray-100 text-gray-500 mr-2`,
15
+ color === 'blue' && 'bg-blue-100 text-blue-500',
16
+ color === 'yellow' && 'bg-yellow-100 text-yellow-500',
17
+ color === 'purple' && 'bg-purple-100 text-purple-500',
18
  className,
19
  )}
20
  >
lib/fetch/index.ts CHANGED
@@ -83,10 +83,9 @@ export type ProjectBaseInfo = {
83
  name: string;
84
  created_at: Date;
85
  label_type: string;
86
- organization: {
87
- id: number;
88
- name: string;
89
- };
90
  };
91
  /**
92
  * Fetch recent projects from all organizations from past 30 days, excluding
 
83
  name: string;
84
  created_at: Date;
85
  label_type: string;
86
+ orgName: string;
87
+ orgId: number;
88
+ subscription: string;
 
89
  };
90
  /**
91
  * Fetch recent projects from all organizations from past 30 days, excluding
lib/hooks/useVisionAgent.tsx CHANGED
@@ -82,13 +82,22 @@ const useVisionAgent = (chat: ChatEntity) => {
82
  ...message,
83
  content: logs + CLEANED_SEPARATOR + newContent,
84
  };
85
- /**
86
- * A workaround to fix the issue of the message not being appended to the chat
87
- * https://github.com/vercel/ai/issues/550#issuecomment-1712693371
88
- */
89
  setMessages([
90
  ...messages,
91
- { id: nanoid(), role: 'user', content: input, createdAt: new Date() },
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  newMessage,
93
  ]);
94
  if (id) {
 
82
  ...message,
83
  content: logs + CLEANED_SEPARATOR + newContent,
84
  };
 
 
 
 
85
  setMessages([
86
  ...messages,
87
+ /**
88
+ * A workaround to fix the issue of the messages been stale state when appending a new message
89
+ * https://github.com/vercel/ai/issues/550#issuecomment-1712693371
90
+ */
91
+ ...(input
92
+ ? [
93
+ {
94
+ id: nanoid(),
95
+ role: 'user',
96
+ content: input,
97
+ createdAt: new Date(),
98
+ } satisfies Message,
99
+ ]
100
+ : []),
101
  newMessage,
102
  ]);
103
  if (id) {