Skip to content

Commit

Permalink
Merge branch 'main' into 4/auth
Browse files Browse the repository at this point in the history
  • Loading branch information
dino3616 committed Jan 18, 2024
2 parents e223eb5 + 2279bf3 commit 0059d05
Show file tree
Hide file tree
Showing 18 changed files with 305 additions and 4 deletions.
12 changes: 12 additions & 0 deletions apps/website/src/app/dashboard/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { NextPage } from 'next';
import { LostItemStatus } from '~website/src/module/dashboard/ui/page/lost-item-status-section';
import { PinnedTask } from '~website/src/module/dashboard/ui/page/pinned-task-section';

const DashboardPage: NextPage = () => (
<div className="flex flex-col items-center gap-32">
<PinnedTask />
<LostItemStatus />
</div>
);

export default DashboardPage;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { LostItemDetail } from './lost-item-detail-presenter';
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { CalendarIcon } from '@lockerai/core/icon/calendar-icon';
import Image from 'next/image';

interface Props {
isRetrieved: boolean;
}

export const LostItemDetail: React.FC<Props> = (Props) => {
if (Props.isRetrieved) {
return (
<div className="flex w-[384px] flex-col gap-3">
<Image
// public/tmpicon.pngを一時的に使用
src="/tmpphone.png"
width={384}
height={240}
alt="user-icon"
className="rounded-3xl"
></Image>
<p className="w-fit items-center rounded-full border border-solid border-cyan-7 bg-cyan-3 px-4 py-2 text-base text-cyan-11">retrieved</p>
<p className="truncate text-2xl font-bold text-sage-11">phone, iPhone 15, white, at station platform, around 5 o’clock</p>
<div className="flex items-center gap-2">
<CalendarIcon className="h-[24px] w-[24px]" />
<p className="text-xl text-sage-11">Oct. 13, 2023 15:32 reported</p>
</div>
</div>
);
}
return (
<div className="flex w-[384px] flex-col gap-3">
<Image
// public/tmpicon.pngを一時的に使用
src="/tmpphone.png"
width={384}
height={240}
alt="user-icon"
className="rounded-3xl"
></Image>
<p className="w-fit items-center rounded-full border border-solid border-purple-7 bg-purple-3 px-4 py-2 text-base text-purple-11">
Delivered
</p>
<p className="truncate text-2xl font-bold text-sage-11">phone, iPhone 15, white, at station platform, around 5 o’clock</p>
<div className="flex items-center gap-2">
<CalendarIcon className="h-[24px] w-[24px]" />
<p className="text-xl text-sage-11">Oct. 13, 2023 15:32 reported</p>
</div>
</div>
);

};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { LostItemStatus } from './lost-item-status-section.presenter';
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { LostItemDetail } from '#website/module/dashboard/ui/component/lost-item-detail';

export const LostItemStatus = () => (
<section className="flex w-[1272px] flex-col gap-8 rounded-3xl border border-solid border-sage-7 bg-sage-1 px-10 py-8">
<div className="flex w-fit gap-6 rounded-xl border border-solid border-sage-7 bg-sage-2 px-4 py-2.5">
<ul className=" flex flex-wrap gap-8 text-center text-sm text-sage-11">
<li className="rounded-lg px-5 py-1.5 text-xl font-bold text-sage-11 hover:bg-sage-5 hover:text-sage-12">
<p>All</p>
</li>

<li className="rounded-lg px-5 py-1.5 text-xl font-bold text-sage-11 hover:bg-sage-5 hover:text-sage-12">
<p>Retrieved</p>
</li>

<li className="rounded-lg px-5 py-1.5 text-xl font-bold text-sage-11 hover:bg-sage-5 hover:text-sage-12">
<p>Delivered</p>
</li>
</ul>
</div>

<div className="flex flex-row flex-wrap gap-16">
<LostItemDetail isRetrieved />
<LostItemDetail isRetrieved={false} />
<LostItemDetail isRetrieved />
</div>
</section>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
'use client';

import { Image } from '@lockerai/core/component/image';
import { ImageIcon } from '@lockerai/core/icon/image-icon';
import React, { useRef, useState } from 'react';

export const DropImage = () => {
const [images, setImages] = useState<string[]>([]);
const dropAreaRef = useRef<HTMLInputElement>(null);

const arrayBufferToBase64 = (buffer: ArrayBuffer): string => {
const bytes = new Uint8Array(buffer);
let binary = '';
bytes.forEach((byte) => {
binary += String.fromCharCode(byte);
});
return btoa(binary);
};

const handleImage = (file: File | null | undefined) => {
if (file instanceof File) {
const reader = new FileReader();

reader.onload = () => {
const {result} = reader;
if (result instanceof ArrayBuffer) {
const base64String = arrayBufferToBase64(result);
setImages((prevImages) => [...prevImages, base64String]);
}
};

reader.readAsArrayBuffer(file);
}
};

const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
e.preventDefault();
const file = e.dataTransfer.files[0];
handleImage(file);
};

const handleImageSelection = (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files && e.target.files[0];
handleImage(file);
};

const handleDropAreaClick = () => {
if (dropAreaRef.current) {
dropAreaRef.current.click();
}
};

return (
<div className="relative flex flex-col items-center justify-center">
<input type="file" ref={dropAreaRef} className="hidden" onChange={handleImageSelection} />
<div
className="z-0 h-{400px} flex w-full mx-auto cursor-pointer flex-col items-center justify-center gap-3 rounded-3xl border border-dashed border-green-7 p-8"
onClick={handleDropAreaClick}
onDrop={handleDrop}
onDragOver={(e) => e.preventDefault()}
>
<ImageIcon width={300} height={300} />
<p className="text-2xl text-sage-11">Drag and drop or select images of the lost item.</p>
</div>
{images.length === 0 ? null : (
<div className="absolute z-10">
<div className="flex flex-row flex-wrap gap-6">
{images.map((image, index) => (
<div key={index}>
<Image src={`data:image/jpeg;base64,${image}`} alt={`Uploaded ${index}`} className="max-h-40 rounded-3xl" width={240} height={160} />
</div>
))}
</div>
</div>
)}
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { DropImage } from './drop-image.presenter';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ReportItemsSection } from './report-items-section.presenter';
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Button } from '#core/component/button';
import { PlaneIcon } from '@lockerai/core/icon/plane-icon';
import { type ComponentPropsWithoutRef } from 'react';
import { DropImage } from 'src/module/report/ui/component/drop-image';

type ReportItemsSectionProps = Omit<ComponentPropsWithoutRef<'section'>, 'children' | 'className'>;
export const ReportItemsSection = ({ ...props }: ReportItemsSectionProps) => (
<section className="flex flex-col items-start gap-16 px-32 py-16" {...props}>
<div className="flex flex-col items-start gap-2">
<p className="text-7xl font-bold text-sage-12">Report</p>
<p className="text-2xl text-sage-11">Take photos of the lost item and report to it.</p>
</div>

<div className="flex w-full flex-col items-center gap-6">
<div className="ml-auto flex items-center rounded-xl border border-green-7 bg-green-3 px-8 py-3 text-lg font-bold text-green-11">
<Button>report</Button>
<PlaneIcon />
</div>
<DropImage />
</div>
</section>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { SearchItemsSection } from './search-items-section.presenter';
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { InsightIcon } from '@lockerai/core/icon/insight-icon';
import { type ComponentPropsWithoutRef } from 'react';

type SearchItemsSectionProps = Omit<ComponentPropsWithoutRef<'section'>, 'children' | 'className'>;
export const SearchItemsSection = ({ ...props }: SearchItemsSectionProps) => (
<section className="flex py-9" {...props}>
<div className="grid flex-col items-center gap-8">
<div className="flex w-[910px] gap-4 rounded-full border border-solid border-green-7 bg-green-3 px-8 py-4 text-2xl text-sage-11">
<InsightIcon className="h-[32px] w-[32px] stroke-sage-11" />
<input type="text" className="w-full bg-green-3" placeholder="Enter your lost item features…" />
</div>

<div className="grid w-[910px] flex-col items-center gap-5">
<div className="grid flex-col items-start gap-3 rounded-3xl border border-solid border-amber-7 bg-amber-2 px-8 py-6">
<p className="flex text-xl font-bold text-amber-11">Too few features</p>
<p className="grid flex-col items-start gap-1 pl-3 text-2xl text-sage-12">
Please enter more features. For example, it is more effective to enter not only features of the item, but also information about when
and where it was lost.
</p>
</div>

<div className="grid flex-col items-start gap-3 rounded-3xl border border-solid border-sage-7 bg-sage-2 px-8 py-6">
<p className="text-xl font-bold text-sage-11">Ex.</p>
<div className="grid flex-col items-start gap-1 pl-3">
<p className="text-2xl text-sage-12">phone, iPhone 15, white</p>
<p className="text-2xl text-sage-12">watch, white, G-Shock</p>
</div>
</div>
</div>
</div>
</section>
);
4 changes: 0 additions & 4 deletions docker/docker-compose.development.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
name: lockerai

version: "3.8"

services:
app:
container_name: lockerai-app
Expand Down
39 changes: 39 additions & 0 deletions packages/core/icon/image-icon/image-icon.presenter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { ComponentPropsWithoutRef, ReactNode } from 'react';

type ImageIconProps = Omit<ComponentPropsWithoutRef<'svg'>, 'children'>;

export const ImageIcon = ({ ...props }: ImageIconProps): ReactNode => (
<svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
<g clipPath="url(#clip0_200_7643)">
<path d="M125 66.667H125.083" stroke="#1B543A" strokeWidth="8" strokeLinecap="round" strokeLinejoin="round" />
<path
d="M104.167 175H50C43.3696 175 37.0107 172.366 32.3223 167.678C27.6339 162.989 25 156.63 25 150V50C25 43.3696 27.6339 37.0107 32.3223 32.3223C37.0107 27.6339 43.3696 25 50 25H150C156.63 25 162.989 27.6339 167.678 32.3223C172.366 37.0107 175 43.3696 175 50V104.167"
stroke="#1B543A"
strokeWidth="8"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M25 133.333L66.6667 91.6662C74.4 84.2245 83.9333 84.2245 91.6667 91.6662L125 125"
stroke="#1B543A"
strokeWidth="8"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M116.667 116.667L125 108.333C130.583 102.967 137.083 101.467 143.183 103.833"
stroke="#1B543A"
strokeWidth="8"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path d="M133.333 158.333H183.333" stroke="#1B543A" strokeWidth="8" strokeLinecap="round" strokeLinejoin="round" />
<path d="M158.333 133.333V183.333" stroke="#1B543A" strokeWidth="8" strokeLinecap="round" strokeLinejoin="round" />
</g>
<defs>
<clipPath id="clip0_200_7643">
<rect width="200" height="200" fill="white" />
</clipPath>
</defs>
</svg>
);
13 changes: 13 additions & 0 deletions packages/core/icon/image-icon/image-icon.story.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { Meta, StoryObj } from '@storybook/react';
import { ImageIcon } from './image-icon.presenter';

type Story = StoryObj<typeof ImageIcon>;

const meta = {
component: ImageIcon,
argTypes: {},
} satisfies Meta<typeof ImageIcon>;

export default meta;

export const Default: Story = {};
1 change: 1 addition & 0 deletions packages/core/icon/image-icon/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ImageIcon } from './image-icon.presenter';
1 change: 1 addition & 0 deletions packages/core/icon/plane-icon/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { PlaneIcon } from './plane-icon.presenter';
12 changes: 12 additions & 0 deletions packages/core/icon/plane-icon/plane-icon.presenter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { ComponentPropsWithoutRef, ReactNode } from 'react';

type PlaneIconProps = Omit<ComponentPropsWithoutRef<'svg'>, 'children'>;

export const PlaneIcon = ({ ...props }: PlaneIconProps): ReactNode => (
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
<path
d="M15.8539 0.64615C15.9232 0.715482 15.9705 0.803624 15.99 0.899627C16.0096 0.99563 16.0005 1.09526 15.9639 1.18615L10.1449 15.7331C10.0937 15.8613 10.008 15.9727 9.89746 16.0553C9.78691 16.1379 9.65571 16.1884 9.51832 16.2012C9.38092 16.214 9.24265 16.1887 9.11873 16.128C8.9948 16.0673 8.89003 15.9736 8.81593 15.8572L5.63793 10.8622L0.642932 7.68415C0.52625 7.61013 0.432283 7.50532 0.371402 7.38128C0.31052 7.25723 0.285089 7.11878 0.297917 6.9812C0.310744 6.84362 0.36133 6.71226 0.444093 6.60161C0.526855 6.49096 0.638578 6.40532 0.766932 6.35415L15.3139 0.53715C15.4048 0.500562 15.5045 0.491482 15.6005 0.511038C15.6965 0.530595 15.7846 0.577925 15.8539 0.64715V0.64615ZM6.63593 10.5701L9.39693 14.9081L14.1299 3.07615L6.63593 10.5701ZM13.4229 2.36915L1.59093 7.10215L5.92993 9.86215L13.4229 2.36915Z"
fill="#4CC38A"
/>
</svg>
);
13 changes: 13 additions & 0 deletions packages/core/icon/plane-icon/plane-icon.story.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { Meta, StoryObj } from '@storybook/react';
import { PlaneIcon } from './plane-icon.presenter';

type Story = StoryObj<typeof PlaneIcon>;

const meta = {
component: PlaneIcon,
argTypes: {},
} satisfies Meta<typeof PlaneIcon>;

export default meta;

export const Default: Story = {};

0 comments on commit 0059d05

Please sign in to comment.