-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #27 from toririm/main-prepare-merge
[main] sync up to date
- Loading branch information
Showing
11 changed files
with
230 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
{} | ||
{ | ||
"plugins": ["prettier-plugin-tailwindcss"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export const hasId = <T>(obj: T): obj is Required<T> => { | ||
return (obj as any).id !== undefined; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { | ||
addDoc, | ||
collection, | ||
deleteDoc, | ||
doc, | ||
getDoc, | ||
getDocs, | ||
setDoc, | ||
} from "firebase/firestore"; | ||
import { converter } from "~/firebase/converter"; | ||
import { db } from "~/firebase/firestore"; | ||
import { hasId } from "~/lib/typeguard"; | ||
import { Order, orderSchema, OrderWithId } from "~/models/order"; | ||
import { OrderRepository } from "./type"; | ||
|
||
export const orderRepository: OrderRepository = { | ||
save: async (order) => { | ||
if (hasId(order)) { | ||
return await update(order); | ||
} else { | ||
return await create(order); | ||
} | ||
}, | ||
|
||
delete: async (id) => { | ||
await deleteDoc(doc(db, "orders", id)); | ||
}, | ||
|
||
findById: async (id) => { | ||
const docRef = doc(db, "orders", id).withConverter( | ||
converter(orderSchema.required()), | ||
); | ||
const docSnap = await getDoc(docRef); | ||
if (docSnap.exists()) { | ||
return docSnap.data(); | ||
} | ||
return null; | ||
}, | ||
|
||
findAll: async () => { | ||
const colRef = collection(db, "orders").withConverter( | ||
converter(orderSchema.required()), | ||
); | ||
const docSnaps = await getDocs(colRef); | ||
return docSnaps.docs.map((doc) => doc.data()); | ||
}, | ||
}; | ||
|
||
const update = async (order: OrderWithId): Promise<OrderWithId> => { | ||
const docRef = doc(db, "orders", order.id).withConverter( | ||
converter(orderSchema.required()), | ||
); | ||
await setDoc(docRef, order); | ||
return order; | ||
}; | ||
|
||
const create = async (order: Order): Promise<OrderWithId> => { | ||
const colRef = collection(db, "orders").withConverter(converter(orderSchema)); | ||
const docRef = await addDoc(colRef, order); | ||
const resultDoc = await getDoc( | ||
docRef.withConverter(converter(orderSchema.required())), | ||
); | ||
if (resultDoc.exists()) { | ||
return resultDoc.data(); | ||
} | ||
throw new Error("Failed to save order"); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,13 @@ | ||
export type Repository<T> = { | ||
findAll: () => Promise<T[]>; | ||
findById: (id: string) => Promise<T | null>; | ||
create: (data: T) => Promise<void>; | ||
update: (data: T) => Promise<void>; | ||
delete: (id: string) => Promise<void>; | ||
import { Item } from "~/models/item"; | ||
import { Order } from "~/models/order"; | ||
|
||
export type BaseRepository<T> = { | ||
save(data: T): Promise<Required<T>>; | ||
delete(id: string): Promise<void>; | ||
findById(id: string): Promise<Required<T> | null>; | ||
findAll(): Promise<Required<T>[]>; | ||
}; | ||
|
||
export type ItemRepository = BaseRepository<Item>; | ||
|
||
export type OrderRepository = BaseRepository<Order>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import type { ActionFunction, MetaFunction } from "@remix-run/node"; | ||
import { Form } from "@remix-run/react"; | ||
import { typedjson, useTypedLoaderData } from "remix-typedjson"; | ||
import { Button } from "~/components/ui/button"; | ||
import { Input } from "~/components/ui/input"; | ||
import { Order } from "~/models/order"; | ||
import { orderRepository } from "~/repositories/order"; | ||
|
||
export const meta: MetaFunction = () => { | ||
return [{ title: "オーダー" }]; | ||
}; | ||
|
||
const type2label = { | ||
hot: "ホット", | ||
ice: "アイス", | ||
ore: "オレ", | ||
milk: "ミルク", | ||
}; | ||
|
||
export const clientLoader = async () => { | ||
console.log("findAllのテスト"); | ||
const orders = await orderRepository.findAll(); | ||
return typedjson({ orders }); | ||
}; | ||
|
||
export default function Orders() { | ||
const { orders } = useTypedLoaderData<typeof clientLoader>(); | ||
|
||
return ( | ||
<div className="font-sans p-4"> | ||
<h1 className="text-3xl">アイテム</h1> | ||
<ul> | ||
{orders.map((order) => ( | ||
<li key={order.id}> | ||
<h2>{order.orderId}</h2> | ||
<p>{order.id}</p> | ||
<div> | ||
{order.items.map((item) => ( | ||
<div key={item.id}> | ||
<h3>{item.name}</h3> | ||
<p>{item.price}</p> | ||
<p>{type2label[item.type]}</p> | ||
</div> | ||
))} | ||
</div> | ||
<p>{order.createdAt.toISOString()}</p> | ||
<p>{`提供時間:${order.servedAt?.toISOString()}`}</p> | ||
<p>{order.total}</p> | ||
<p>{order.orderReady}</p> | ||
</li> | ||
))} | ||
</ul> | ||
<Form method="post"> | ||
<Input type="number" name="orderId" required placeholder="注文番号" /> | ||
<Button type="submit">登録</Button> | ||
</Form> | ||
<Form method="delete"> | ||
<Input type="text" name="id" required placeholder="id" /> | ||
<Button type="submit">削除</Button> | ||
</Form> | ||
<Form method="put"> | ||
<Input type="text" name="id" required placeholder="id" /> | ||
<Button type="submit">更新</Button> | ||
</Form> | ||
</div> | ||
); | ||
} | ||
|
||
const testOrder = (orderId: number): Order => ({ | ||
orderId, | ||
items: [ | ||
{ | ||
id: "1", | ||
name: "テスト", | ||
price: 100, | ||
type: "hot", | ||
}, | ||
], | ||
createdAt: new Date(), | ||
servedAt: null, | ||
assignee: null, | ||
total: 100, | ||
orderReady: false, | ||
}); | ||
|
||
export const clientAction: ActionFunction = async ({ request }) => { | ||
const formData = await request.formData(); | ||
|
||
switch (request.method) { | ||
case "POST": | ||
console.log("save(create)のテスト"); | ||
const orderId = Number(formData.get("orderId")); | ||
const newOrder = testOrder(orderId); | ||
const savedOrder = await orderRepository.save(newOrder); | ||
console.log("created", savedOrder); | ||
break; | ||
|
||
case "DELETE": | ||
console.log("deleteのテスト"); | ||
const id = formData.get("id"); | ||
await orderRepository.delete(id as string); | ||
break; | ||
|
||
case "PUT": | ||
console.log("save(update)のテスト"); | ||
const id2 = formData.get("id"); | ||
const order = await orderRepository.findById(id2 as string); | ||
if (order) { | ||
order.servedAt = new Date(); | ||
await orderRepository.save(order); | ||
} | ||
break; | ||
} | ||
|
||
return null; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters