mirror of
https://github.com/ershisan99/inctagram-live-2024-08-30.git
synced 2026-02-05 12:35:10 +00:00
lesson 3
This commit is contained in:
102
src/services/instagram.api.ts
Normal file
102
src/services/instagram.api.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
// Need to use the React-specific entry point to import createApi
|
||||
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
|
||||
import {
|
||||
GetAllPostsArgs,
|
||||
GetAllPostsResponse,
|
||||
LoginArgs,
|
||||
LoginResponse,
|
||||
MeResponse,
|
||||
UploadFileResponse,
|
||||
UserPosts,
|
||||
UserProfile,
|
||||
} from '@/services/instagram.types'
|
||||
|
||||
// Define a service using a base URL and expected endpoints
|
||||
export const instagramApi = createApi({
|
||||
tagTypes: ['Posts'],
|
||||
reducerPath: 'instagramApi',
|
||||
baseQuery: fetchBaseQuery({
|
||||
baseUrl: 'https://inctagram.work/api/',
|
||||
prepareHeaders: (headers) => {
|
||||
const token = localStorage.getItem('access_token')
|
||||
if (token) {
|
||||
headers.set('Authorization', `Bearer ${token}`)
|
||||
}
|
||||
return headers
|
||||
},
|
||||
}),
|
||||
endpoints: (builder) => ({
|
||||
getAllPublicPosts: builder.query<
|
||||
GetAllPostsResponse,
|
||||
GetAllPostsArgs | void
|
||||
>({
|
||||
query: (arg) => {
|
||||
const { endCursorPostId, ...params } = arg ?? {}
|
||||
return { url: `/v1/public-posts/all/${endCursorPostId}`, params }
|
||||
},
|
||||
}),
|
||||
login: builder.mutation<LoginResponse, LoginArgs>({
|
||||
query: (args) => ({ url: 'v1/auth/login', body: args, method: 'POST' }),
|
||||
}),
|
||||
me: builder.query<MeResponse, void>({
|
||||
query: () => ({
|
||||
url: '/v1/auth/me',
|
||||
}),
|
||||
}),
|
||||
getUserProfile: builder.query<UserProfile, { id: number }>({
|
||||
query: ({ id }) => ({
|
||||
url: `/v1/public-user/profile/${id}`,
|
||||
}),
|
||||
}),
|
||||
getUserPosts: builder.query<UserPosts, { id: number }>({
|
||||
providesTags: ['Posts'],
|
||||
query: ({ id }) => ({
|
||||
url: `/v1/public-posts/user/${id}`,
|
||||
}),
|
||||
}),
|
||||
uploadFileForPost: builder.mutation<UploadFileResponse, { file: File }>({
|
||||
query: ({ file }) => {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
return {
|
||||
url: '/v1/posts/image',
|
||||
body: formData,
|
||||
method: 'POST',
|
||||
}
|
||||
},
|
||||
}),
|
||||
createPost: builder.mutation<
|
||||
any,
|
||||
{ description: string; uploadIds: string[] }
|
||||
>({
|
||||
invalidatesTags: ['Posts'],
|
||||
query: ({ description, uploadIds }) => {
|
||||
return {
|
||||
url: '/v1/posts',
|
||||
body: {
|
||||
description,
|
||||
childrenMetadata: uploadIds.map((id) => {
|
||||
return {
|
||||
uploadId: id,
|
||||
}
|
||||
}),
|
||||
},
|
||||
|
||||
method: 'POST',
|
||||
}
|
||||
},
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
// Export hooks for usage in functional components, which are
|
||||
// auto-generated based on the defined endpoints
|
||||
export const {
|
||||
useGetAllPublicPostsQuery,
|
||||
useLoginMutation,
|
||||
useMeQuery,
|
||||
useGetUserProfileQuery,
|
||||
useGetUserPostsQuery,
|
||||
useUploadFileForPostMutation,
|
||||
useCreatePostMutation,
|
||||
} = instagramApi
|
||||
91
src/services/instagram.types.ts
Normal file
91
src/services/instagram.types.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
export interface UserProfile {
|
||||
id: number
|
||||
userName: string
|
||||
firstName: string
|
||||
lastName: string
|
||||
city: string
|
||||
country: string
|
||||
region: string
|
||||
dateOfBirth: string
|
||||
aboutMe: string
|
||||
avatars: Avatar[]
|
||||
createdAt: string
|
||||
}
|
||||
|
||||
export interface Avatar {
|
||||
url: string
|
||||
width: number
|
||||
height: number
|
||||
fileSize: number
|
||||
createdAt: string
|
||||
}
|
||||
|
||||
export interface MeResponse {
|
||||
userId: number
|
||||
userName: string
|
||||
email: string
|
||||
isBlocked: boolean
|
||||
}
|
||||
|
||||
export interface LoginArgs {
|
||||
email: string
|
||||
password: string
|
||||
}
|
||||
|
||||
export interface LoginResponse {
|
||||
accessToken: string
|
||||
}
|
||||
|
||||
export interface GetAllPostsArgs {
|
||||
pageSize?: number
|
||||
sortBy?: string
|
||||
sortDirection?: 'asc' | 'desc'
|
||||
endCursorPostId?: number
|
||||
}
|
||||
|
||||
export interface GetAllPostsResponse {
|
||||
totalCount: number
|
||||
pageSize: number
|
||||
items: Post[]
|
||||
totalUsers: number
|
||||
}
|
||||
|
||||
export interface Post {
|
||||
id: number
|
||||
userName: string
|
||||
description: string
|
||||
location?: string | null
|
||||
images: Image[]
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
avatarOwner?: string
|
||||
ownerId: number
|
||||
owner: Owner
|
||||
likesCount: number
|
||||
isLiked: boolean
|
||||
}
|
||||
|
||||
export interface Owner {
|
||||
firstName: string
|
||||
lastName: string
|
||||
}
|
||||
|
||||
export interface Image {
|
||||
url: string
|
||||
width: number
|
||||
height: number
|
||||
fileSize: number
|
||||
createdAt: string
|
||||
uploadId: string
|
||||
}
|
||||
|
||||
export interface UserPosts {
|
||||
totalCount: number
|
||||
pageSize: number
|
||||
items: Post[]
|
||||
totalUsers: number
|
||||
}
|
||||
|
||||
export interface UploadFileResponse {
|
||||
images: Image[]
|
||||
}
|
||||
33
src/services/store.ts
Normal file
33
src/services/store.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import {
|
||||
Action,
|
||||
combineSlices,
|
||||
configureStore,
|
||||
ThunkAction,
|
||||
} from '@reduxjs/toolkit'
|
||||
import { createWrapper } from 'next-redux-wrapper'
|
||||
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
|
||||
import { instagramApi } from '@/services/instagram.api'
|
||||
|
||||
const makeStore = () =>
|
||||
configureStore({
|
||||
reducer: combineSlices(instagramApi),
|
||||
middleware: (getDefaultMiddleware) =>
|
||||
getDefaultMiddleware().concat(instagramApi.middleware),
|
||||
devTools: true,
|
||||
})
|
||||
|
||||
export type AppStore = ReturnType<typeof makeStore>
|
||||
export type AppState = ReturnType<AppStore['getState']>
|
||||
export type AppDispatch = AppStore['dispatch']
|
||||
export type AppThunk<ReturnType = void> = ThunkAction<
|
||||
ReturnType,
|
||||
AppState,
|
||||
unknown,
|
||||
Action
|
||||
>
|
||||
|
||||
// Use throughout your app instead of plain `useDispatch` and `useSelector`
|
||||
export const useAppDispatch = () => useDispatch<AppDispatch>()
|
||||
export const useAppSelector: TypedUseSelectorHook<AppState> = useSelector
|
||||
|
||||
export const wrapper = createWrapper<AppStore>(makeStore)
|
||||
Reference in New Issue
Block a user