Skip to content

Commit

Permalink
Merge pull request #45 from piny940/client-update
Browse files Browse the repository at this point in the history
Clientをupdateできるようにする
  • Loading branch information
piny940 authored Oct 29, 2024
2 parents 963ad53 + 93b7a7e commit a2169e3
Show file tree
Hide file tree
Showing 14 changed files with 659 additions and 47 deletions.
2 changes: 1 addition & 1 deletion Taskfile.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ tasks:
cmds:
- task migrate:create
- cd spec && pnpm compile
- go generate ./...
- cd frontend && pnpm codegen
- go generate ./...
- task lint

migrate:create:
Expand Down
9 changes: 9 additions & 0 deletions frontend/src/app/member/clients/edit/[clientId]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { ClientEditPage } from '@/components/ClientEditPage'

type Props = {
clientId: string
}
export default async function Page(req: { params: Promise<Props> }) {
const params = await req.params
return <ClientEditPage clientId={params.clientId} />
}
29 changes: 22 additions & 7 deletions frontend/src/app/member/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import { blueGrey } from '@mui/material/colors'
import { useCallback, useEffect, useState } from 'react'
import Error from 'next/error'
import Link from 'next/link'
import EditIcon from '@mui/icons-material/Edit'
import { useRouter } from 'next/navigation'

export default function Page() {
const [clients, setClients] = useState<Client[]>([])
Expand All @@ -39,6 +41,8 @@ export default function Page() {
},
[fetchClients]
)
const router = useRouter()

useEffect(() => {
fetchClients()
}, [fetchClients])
Expand Down Expand Up @@ -71,18 +75,29 @@ export default function Page() {
{clients.map((client) => (
<ListItem
secondaryAction={
<IconButton
onClick={() => deleteClient(client.id)}
edge="end"
aria-label="delete"
>
<DeleteIcon />
</IconButton>
<Box sx={{ '> *': { marginX: 1 } }}>
<IconButton
onClick={() =>
router.push(`/member/clients/edit/${client.id}`)
}
edge="end"
>
<EditIcon />
</IconButton>
<IconButton
onClick={() => deleteClient(client.id)}
edge="end"
aria-label="delete"
>
<DeleteIcon />
</IconButton>
</Box>
}
key={client.id}
sx={{
bgcolor: 'white',
paddingX: 4,
paddingY: 2,
}}
>
<Typography variant="h6">{client.name}</Typography>
Expand Down
59 changes: 59 additions & 0 deletions frontend/src/components/ClientEdit.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
'use client'

import { useForm } from 'react-hook-form'
import { ClientForm, ClientInput } from './ClientForm'
import { RedirectURIsFields } from './RedirectURIsEdit'
import { Box, Typography } from '@mui/material'
import { Client } from '@/utils/types'
import { useCallback } from 'react'
import { client as apiClient } from '@/utils/client'
import { useRouter } from 'next/navigation'

export type ClientEditProps = {
client: Client
}

export const ClientEdit = ({ client }: ClientEditProps) => {
const { handleSubmit, getValues, control } = useForm<ClientInput>({
defaultValues: {
name: client.name,
redirectUris: client.redirect_urls,
},
})
const { control: redirectURIsControl, getValues: getRedirectURIsValues } =
useForm<RedirectURIsFields>({
defaultValues: {
redirectURIs: client.redirect_urls.map((url) => ({ url })),
},
})
const router = useRouter()
const submit = useCallback(async () => {
const newClient = getValues()
const urls = getRedirectURIsValues().redirectURIs.map((uri) => uri.url)
const { error } = await apiClient.POST('/account/clients/{id}', {
params: { path: { id: client.id } },
body: {
client: {
name: newClient.name,
redirect_urls: urls,
},
},
})
if (error) {
console.error(error)
throw new Error('Failed to update client: ' + error)
}
router.push('/member')
}, [getValues, getRedirectURIsValues, client.id, router])

return (
<Box>
<Typography variant="h4">Edit Client</Typography>
<ClientForm
control={control}
redirectURIsControl={redirectURIsControl}
submit={handleSubmit(submit)}
/>
</Box>
)
}
31 changes: 31 additions & 0 deletions frontend/src/components/ClientEditPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use client'
import { client } from '@/utils/client'
import { Client } from '@/utils/types'
import { useEffect, useState } from 'react'
import { ClientEdit } from './ClientEdit'

type ClientEditProps = {
clientId: string
}
export const ClientEditPage = ({ clientId }: ClientEditProps) => {
const [current, setCurrent] = useState<Client | null>(null)
const fetchClient = async (clientId: string) => {
const { data, error } = await client.GET('/account/clients/{id}', {
params: { path: { id: clientId } },
})
if (error) {
console.error(error)
throw new Error('Failed to fetch client: ' + error)
}
setCurrent(data.client)
}

useEffect(() => {
fetchClient(clientId)
}, [clientId])

if (!current) {
return <div>Loading...</div>
}
return <ClientEdit client={current} />
}
82 changes: 80 additions & 2 deletions frontend/src/utils/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@ export interface paths {
path?: never
cookie?: never
}
get?: never
/** Get a client */
get: operations['AccountClients_getClient']
put?: never
post?: never
/** Update a client */
post: operations['AccountClients_updateClient']
/** Delete a client */
delete: operations['AccountClients_deleteClient']
options?: never
Expand Down Expand Up @@ -175,6 +177,10 @@ export interface components {
secret: string
redirect_urls: string[]
}
'AccountClients.UpdateClientReq': {
name: string
redirect_urls: string[]
}
/** @enum {string} */
'Approvals.ApproveErr': 'invalid_client' | 'invalid_scope'
'Approvals.ApproveReq': {
Expand Down Expand Up @@ -364,6 +370,78 @@ export interface operations {
}
}
}
AccountClients_getClient: {
parameters: {
query?: never
header?: never
path: {
id: string
}
cookie?: never
}
requestBody?: never
responses: {
/** @description The request has succeeded. */
200: {
headers: {
[name: string]: unknown
}
content: {
'application/json': {
client: components['schemas']['Client']
}
}
}
/** @description The server cannot find the requested resource. */
404: {
headers: {
[name: string]: unknown
}
content: {
'application/json': {
error: string
}
}
}
}
}
AccountClients_updateClient: {
parameters: {
query?: never
header?: never
path: {
id: string
}
cookie?: never
}
requestBody: {
content: {
'application/json': {
client: components['schemas']['AccountClients.UpdateClientReq']
}
}
}
responses: {
/** @description There is no content to send for this request, but the headers may be useful. */
204: {
headers: {
[name: string]: unknown
}
content?: never
}
/** @description The server could not understand the request due to invalid syntax. */
400: {
headers: {
[name: string]: unknown
}
content: {
'application/json': {
error: string
}
}
}
}
}
AccountClients_deleteClient: {
parameters: {
query?: never
Expand Down
35 changes: 35 additions & 0 deletions internal/api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,38 @@ func (s *Server) AccountClientsListClients(ctx context.Context, request AccountC
Clients: mClients,
}, nil
}

func (s *Server) AccountClientsGetClient(ctx context.Context, request AccountClientsGetClientRequestObject) (AccountClientsGetClientResponseObject, error) {
user, err := CurrentUser(ctx)
if err != nil {
s.logger.Errorf("failed to get current user: %v", err)
return nil, err
}
client, err := s.ClientUsecase.FindWithUserID(oauth.ClientID(request.Id), user.ID)
if err != nil {
s.logger.Errorf("failed to get client: %v", err)
return AccountClientsGetClient404JSONResponse{
Error: "client_not_found",
}, nil
}
return AccountClientsGetClient200JSONResponse{
Client: Client{
Id: string(client.ID),
Name: client.Name,
RedirectUrls: client.RedirectURIs,
},
}, nil
}

func (s *Server) AccountClientsUpdateClient(ctx context.Context, request AccountClientsUpdateClientRequestObject) (AccountClientsUpdateClientResponseObject, error) {
user, err := CurrentUser(ctx)
if err != nil {
s.logger.Errorf("failed to get current user: %v", err)
return nil, err
}
if err := s.ClientUsecase.Update(oauth.ClientID(request.Id), user.ID, request.Body.Client.Name, request.Body.Client.RedirectUrls); err != nil {
s.logger.Errorf("failed to update client: %v", err)
return nil, err
}
return AccountClientsUpdateClient204Response{}, nil
}
Loading

0 comments on commit a2169e3

Please sign in to comment.