Invite and Session API/Services; Home view; Sidebar Items; Modals
This commit is contained in:
parent
280158470a
commit
e36587b99d
80 changed files with 1343 additions and 71 deletions
|
|
@ -31,7 +31,7 @@ const updateChannelApi = async (
|
||||||
const removeChannelApi = async (
|
const removeChannelApi = async (
|
||||||
request: IRemoveChannelRequest,
|
request: IRemoveChannelRequest,
|
||||||
): Promise<IRemoveChannelResponse> => {
|
): Promise<IRemoveChannelResponse> => {
|
||||||
return await callApi(HTTP.DELETE, `channel/${request.id}`, request);
|
return await callApi(HTTP.DELETE, `channel/${request.id}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ interface ICreateChannelResponse extends IFetchChannel {}
|
||||||
interface IUpdateChannelRequest {
|
interface IUpdateChannelRequest {
|
||||||
id: string;
|
id: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
|
description?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IUpdateChannelResponse extends IFetchChannel {}
|
interface IUpdateChannelResponse extends IFetchChannel {}
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,20 @@ import { callApi, HTTP } from "../tools";
|
||||||
import {
|
import {
|
||||||
IFetchCommunityRequest,
|
IFetchCommunityRequest,
|
||||||
IFetchCommunityResponse,
|
IFetchCommunityResponse,
|
||||||
|
ICreateCommunityRequest,
|
||||||
|
ICreateCommunityResponse,
|
||||||
|
IUpdateCommunityRequest,
|
||||||
|
IUpdateCommunityResponse,
|
||||||
|
IRemoveCommunityRequest,
|
||||||
|
IRemoveCommunityResponse,
|
||||||
IFetchCommunityChannelsRequest,
|
IFetchCommunityChannelsRequest,
|
||||||
IFetchCommunityChannelsResponse,
|
IFetchCommunityChannelsResponse,
|
||||||
IFetchCommunityRolesRequest,
|
IFetchCommunityRolesRequest,
|
||||||
IFetchCommunityRolesResponse,
|
IFetchCommunityRolesResponse,
|
||||||
IFetchCommunityMembersRequest,
|
IFetchCommunityMembersRequest,
|
||||||
IFetchCommunityMembersResponse,
|
IFetchCommunityMembersResponse,
|
||||||
|
IFetchCommunityInvitesRequest,
|
||||||
|
IFetchCommunityInvitesResponse,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
const fetchCommunityApi = async (
|
const fetchCommunityApi = async (
|
||||||
|
|
@ -16,6 +24,24 @@ const fetchCommunityApi = async (
|
||||||
return await callApi(HTTP.GET, `community/${request.id}`);
|
return await callApi(HTTP.GET, `community/${request.id}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const createCommunityApi = async (
|
||||||
|
request: ICreateCommunityRequest,
|
||||||
|
): Promise<ICreateCommunityResponse> => {
|
||||||
|
return await callApi(HTTP.POST, `community`, request);
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateCommunityApi = async (
|
||||||
|
request: IUpdateCommunityRequest,
|
||||||
|
): Promise<IUpdateCommunityResponse> => {
|
||||||
|
return await callApi(HTTP.PATCH, `community/${request.id}`, request);
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeCommunityApi = async (
|
||||||
|
request: IRemoveCommunityRequest,
|
||||||
|
): Promise<IRemoveCommunityResponse> => {
|
||||||
|
return await callApi(HTTP.DELETE, `community/${request.id}`);
|
||||||
|
};
|
||||||
|
|
||||||
const fetchCommunityChannelsApi = async (
|
const fetchCommunityChannelsApi = async (
|
||||||
request: IFetchCommunityChannelsRequest,
|
request: IFetchCommunityChannelsRequest,
|
||||||
): Promise<IFetchCommunityChannelsResponse> => {
|
): Promise<IFetchCommunityChannelsResponse> => {
|
||||||
|
|
@ -34,9 +60,19 @@ const fetchCommunityMembersApi = async (
|
||||||
return await callApi(HTTP.GET, `community/${request.id}/members`);
|
return await callApi(HTTP.GET, `community/${request.id}/members`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fetchCommunityInvitesApi = async (
|
||||||
|
request: IFetchCommunityInvitesRequest,
|
||||||
|
): Promise<IFetchCommunityInvitesResponse> => {
|
||||||
|
return await callApi(HTTP.GET, `community/${request.id}/invites`);
|
||||||
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
fetchCommunityApi,
|
fetchCommunityApi,
|
||||||
|
createCommunityApi,
|
||||||
|
updateCommunityApi,
|
||||||
|
removeCommunityApi,
|
||||||
fetchCommunityChannelsApi,
|
fetchCommunityChannelsApi,
|
||||||
fetchCommunityRolesApi,
|
fetchCommunityRolesApi,
|
||||||
fetchCommunityMembersApi,
|
fetchCommunityMembersApi,
|
||||||
|
fetchCommunityInvitesApi,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,28 @@ interface IFetchCommunityRequest {
|
||||||
|
|
||||||
interface IFetchCommunityResponse extends IFetchCommunity {}
|
interface IFetchCommunityResponse extends IFetchCommunity {}
|
||||||
|
|
||||||
|
interface ICreateCommunityRequest {
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ICreateCommunityResponse extends IFetchCommunity {}
|
||||||
|
|
||||||
|
interface IUpdateCommunityRequest {
|
||||||
|
id: string;
|
||||||
|
name?: string;
|
||||||
|
description?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IUpdateCommunityResponse extends IFetchCommunity {}
|
||||||
|
|
||||||
|
interface IRemoveCommunityRequest {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IRemoveCommunityResponse {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
interface IFetchCommunityChannelsRequest {
|
interface IFetchCommunityChannelsRequest {
|
||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
@ -54,10 +76,29 @@ interface IFetchCommunityMember {
|
||||||
username: string;
|
username: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface IFetchCommunityInvitesRequest {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IFetchCommunityInvitesResponse {
|
||||||
|
id: string;
|
||||||
|
invites: IFetchCommunityInvite[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IFetchCommunityInvite {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
type IFetchCommunity,
|
type IFetchCommunity,
|
||||||
type IFetchCommunityRequest,
|
type IFetchCommunityRequest,
|
||||||
type IFetchCommunityResponse,
|
type IFetchCommunityResponse,
|
||||||
|
type ICreateCommunityRequest,
|
||||||
|
type ICreateCommunityResponse,
|
||||||
|
type IUpdateCommunityRequest,
|
||||||
|
type IUpdateCommunityResponse,
|
||||||
|
type IRemoveCommunityRequest,
|
||||||
|
type IRemoveCommunityResponse,
|
||||||
type IFetchCommunityChannelsRequest,
|
type IFetchCommunityChannelsRequest,
|
||||||
type IFetchCommunityChannelsResponse,
|
type IFetchCommunityChannelsResponse,
|
||||||
type IFetchCommunityChannel,
|
type IFetchCommunityChannel,
|
||||||
|
|
@ -67,4 +108,7 @@ export {
|
||||||
type IFetchCommunityMembersRequest,
|
type IFetchCommunityMembersRequest,
|
||||||
type IFetchCommunityMembersResponse,
|
type IFetchCommunityMembersResponse,
|
||||||
type IFetchCommunityMember,
|
type IFetchCommunityMember,
|
||||||
|
type IFetchCommunityInvitesRequest,
|
||||||
|
type IFetchCommunityInvitesResponse,
|
||||||
|
type IFetchCommunityInvite,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
2
src/api/invite/index.ts
Normal file
2
src/api/invite/index.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
export * from "./invite";
|
||||||
|
export * from "./types";
|
||||||
29
src/api/invite/invite.ts
Normal file
29
src/api/invite/invite.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
import { callApi, HTTP } from "../tools";
|
||||||
|
import {
|
||||||
|
IFetchInviteRequest,
|
||||||
|
IFetchInviteResponse,
|
||||||
|
IRemoveInviteRequest,
|
||||||
|
IRemoveInviteResponse,
|
||||||
|
IAcceptInviteRequest,
|
||||||
|
IAcceptInviteResponse,
|
||||||
|
} from "./types";
|
||||||
|
|
||||||
|
const fetchInviteApi = async (
|
||||||
|
request: IFetchInviteRequest,
|
||||||
|
): Promise<IFetchInviteResponse> => {
|
||||||
|
return await callApi(HTTP.GET, `invite/${request.id}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeInviteApi = async (
|
||||||
|
request: IRemoveInviteRequest,
|
||||||
|
): Promise<IRemoveInviteResponse> => {
|
||||||
|
return await callApi(HTTP.DELETE, `invite/${request.id}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
const acceptInviteApi = async (
|
||||||
|
request: IAcceptInviteRequest,
|
||||||
|
): Promise<IAcceptInviteResponse> => {
|
||||||
|
return await callApi(HTTP.GET, `invite/${request.id}/accept`);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { fetchInviteApi, removeInviteApi, acceptInviteApi };
|
||||||
48
src/api/invite/types.ts
Normal file
48
src/api/invite/types.ts
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
interface IFetchInvite {
|
||||||
|
id: string;
|
||||||
|
communityId: string;
|
||||||
|
valid: boolean;
|
||||||
|
unlimitedInvites: boolean;
|
||||||
|
hasExpiration: boolean;
|
||||||
|
totalInvites: number;
|
||||||
|
remainingInvites: number;
|
||||||
|
creationDate: number;
|
||||||
|
expirationDate: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IFetchInviteRequest {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IFetchInviteResponse extends IFetchInvite {}
|
||||||
|
|
||||||
|
interface IRemoveInviteRequest {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IRemoveInviteResponse {
|
||||||
|
id: string;
|
||||||
|
userId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IAcceptInviteRequest {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IAcceptInviteResponse {
|
||||||
|
id: string;
|
||||||
|
userId: string;
|
||||||
|
userName: string;
|
||||||
|
communityId: string;
|
||||||
|
communityName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
type IFetchInvite,
|
||||||
|
type IFetchInviteRequest,
|
||||||
|
type IFetchInviteResponse,
|
||||||
|
type IRemoveInviteRequest,
|
||||||
|
type IRemoveInviteResponse,
|
||||||
|
type IAcceptInviteRequest,
|
||||||
|
type IAcceptInviteResponse,
|
||||||
|
};
|
||||||
|
|
@ -31,7 +31,7 @@ const updateRoleApi = async (
|
||||||
const removeRoleApi = async (
|
const removeRoleApi = async (
|
||||||
request: IRemoveRoleRequest,
|
request: IRemoveRoleRequest,
|
||||||
): Promise<IRemoveRoleResponse> => {
|
): Promise<IRemoveRoleResponse> => {
|
||||||
return await callApi(HTTP.DELETE, `role/${request.id}`, request);
|
return await callApi(HTTP.DELETE, `role/${request.id}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
export { fetchRoleApi, createRoleApi, updateRoleApi, removeRoleApi };
|
export { fetchRoleApi, createRoleApi, updateRoleApi, removeRoleApi };
|
||||||
|
|
|
||||||
2
src/api/session/index.ts
Normal file
2
src/api/session/index.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
export * from "./session";
|
||||||
|
export * from "./types";
|
||||||
21
src/api/session/session.ts
Normal file
21
src/api/session/session.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { callApi, HTTP } from "../tools";
|
||||||
|
import {
|
||||||
|
IFetchSessionRequest,
|
||||||
|
IFetchSessionResponse,
|
||||||
|
IRemoveSessionRequest,
|
||||||
|
IRemoveSessionResponse,
|
||||||
|
} from "./types";
|
||||||
|
|
||||||
|
const fetchSessionApi = async (
|
||||||
|
request: IFetchSessionRequest,
|
||||||
|
): Promise<IFetchSessionResponse> => {
|
||||||
|
return await callApi(HTTP.GET, `session/${request.id}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeSessionApi = async (
|
||||||
|
request: IRemoveSessionRequest,
|
||||||
|
): Promise<IRemoveSessionResponse> => {
|
||||||
|
return await callApi(HTTP.DELETE, `session/${request.id}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { fetchSessionApi, removeSessionApi };
|
||||||
28
src/api/session/types.ts
Normal file
28
src/api/session/types.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
interface IFetchSession {
|
||||||
|
id: string;
|
||||||
|
userId: string;
|
||||||
|
creationDate: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IFetchSessionRequest {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IFetchSessionResponse extends IFetchSession {}
|
||||||
|
|
||||||
|
interface IRemoveSessionRequest {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IRemoveSessionResponse {
|
||||||
|
id: string;
|
||||||
|
userId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
type IFetchSession,
|
||||||
|
type IFetchSessionRequest,
|
||||||
|
type IFetchSessionResponse,
|
||||||
|
type IRemoveSessionRequest,
|
||||||
|
type IRemoveSessionResponse,
|
||||||
|
};
|
||||||
|
|
@ -18,6 +18,20 @@ interface IFetchUserRequest {
|
||||||
|
|
||||||
interface IFetchUserResponse extends IFetchUser {}
|
interface IFetchUserResponse extends IFetchUser {}
|
||||||
|
|
||||||
|
interface IFetchUserSessionsRequest {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IFetchUserSessionsResponse {
|
||||||
|
id: string;
|
||||||
|
sessions: IFetchUserSession[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IFetchUserSession {
|
||||||
|
id: string;
|
||||||
|
userId: string;
|
||||||
|
}
|
||||||
|
|
||||||
interface IFetchUserCommunitiesRequest {
|
interface IFetchUserCommunitiesRequest {
|
||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
@ -30,7 +44,6 @@ interface IFetchUserCommunitiesResponse {
|
||||||
interface IFetchUserCommunity {
|
interface IFetchUserCommunity {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|
@ -38,6 +51,9 @@ export {
|
||||||
type IFetchLoggedUserResponse,
|
type IFetchLoggedUserResponse,
|
||||||
type IFetchUserRequest,
|
type IFetchUserRequest,
|
||||||
type IFetchUserResponse,
|
type IFetchUserResponse,
|
||||||
|
type IFetchUserSessionsRequest,
|
||||||
|
type IFetchUserSessionsResponse,
|
||||||
|
type IFetchUserSession,
|
||||||
type IFetchUserCommunitiesRequest,
|
type IFetchUserCommunitiesRequest,
|
||||||
type IFetchUserCommunitiesResponse,
|
type IFetchUserCommunitiesResponse,
|
||||||
type IFetchUserCommunity,
|
type IFetchUserCommunity,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ import {
|
||||||
IFetchLoggedUserResponse,
|
IFetchLoggedUserResponse,
|
||||||
IFetchUserRequest,
|
IFetchUserRequest,
|
||||||
IFetchUserResponse,
|
IFetchUserResponse,
|
||||||
|
IFetchUserSessionsRequest,
|
||||||
|
IFetchUserSessionsResponse,
|
||||||
IFetchUserCommunitiesRequest,
|
IFetchUserCommunitiesRequest,
|
||||||
IFetchUserCommunitiesResponse,
|
IFetchUserCommunitiesResponse,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
@ -17,10 +19,21 @@ const fetchUserApi = async (
|
||||||
return await callApi(HTTP.GET, `user/${request.id}`);
|
return await callApi(HTTP.GET, `user/${request.id}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fetchUserSessionsApi = async (
|
||||||
|
request: IFetchUserSessionsRequest,
|
||||||
|
): Promise<IFetchUserSessionsResponse> => {
|
||||||
|
return await callApi(HTTP.GET, `user/${request.id}/sessions`);
|
||||||
|
};
|
||||||
|
|
||||||
const fetchUserCommunitiesApi = async (
|
const fetchUserCommunitiesApi = async (
|
||||||
request: IFetchUserCommunitiesRequest,
|
request: IFetchUserCommunitiesRequest,
|
||||||
): Promise<IFetchUserCommunitiesResponse> => {
|
): Promise<IFetchUserCommunitiesResponse> => {
|
||||||
return await callApi(HTTP.GET, `user/${request.id}/communities`);
|
return await callApi(HTTP.GET, `user/${request.id}/communities`);
|
||||||
};
|
};
|
||||||
|
|
||||||
export { fetchLoggedUserApi, fetchUserApi, fetchUserCommunitiesApi };
|
export {
|
||||||
|
fetchLoggedUserApi,
|
||||||
|
fetchUserApi,
|
||||||
|
fetchUserSessionsApi,
|
||||||
|
fetchUserCommunitiesApi,
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ const Channel: Component<IChannelProps> = (props: IChannelProps) => {
|
||||||
return (
|
return (
|
||||||
<li
|
<li
|
||||||
class={`flex flex-row gap-2 items-center p-1 cursor-pointer rounded-lg ${props.active ? "bg-stone-700 hover:bg-stone-700" : "hover:bg-stone-800"}`}
|
class={`flex flex-row gap-2 items-center p-1 cursor-pointer rounded-lg ${props.active ? "bg-stone-700 hover:bg-stone-700" : "hover:bg-stone-800"}`}
|
||||||
onClick={() => props.onChannelClick(props.id)}
|
onClick={() => props.onChannelClick?.(props.id)}
|
||||||
>
|
>
|
||||||
<div class="font-bold text-xl"> #</div>
|
<div class="font-bold text-xl"> #</div>
|
||||||
<div class="font-bold">{props.name}</div>
|
<div class="font-bold">{props.name}</div>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ interface IChannelProps {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
active: boolean;
|
active: boolean;
|
||||||
onChannelClick: (id: string) => void;
|
onChannelClick?: (id: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { type IChannelProps };
|
export { type IChannelProps };
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,10 @@ const Community: Component<ICommunityProps> = (props: ICommunityProps) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
class="avatar cursor-pointer"
|
class="avatar cursor-pointer"
|
||||||
onClick={() => props.onCommunityClick(props.id)}
|
onClick={() => props.onCommunityClick?.(props.id)}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class={`w-full transition-[border-radius] duration-300 outline-stone-300 hover:outline-2 ${props.active ? "rounded-lg outline-2" : "rounded-4xl"}`}
|
class={`w-full transition-[border-radius] duration-300 outline-stone-300 ${props.active ? "rounded-lg outline-3 hover:outline-3" : "rounded-4xl hover:outline-2"}`}
|
||||||
>
|
>
|
||||||
<img src={props.avatar} />
|
<img src={props.avatar} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ interface ICommunityProps {
|
||||||
name: string;
|
name: string;
|
||||||
avatar: string;
|
avatar: string;
|
||||||
active: boolean;
|
active: boolean;
|
||||||
onCommunityClick: (id: string) => void;
|
onCommunityClick?: (id: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { type ICommunityProps };
|
export { type ICommunityProps };
|
||||||
|
|
|
||||||
101
src/components/CommunityModal/CommunityModal.tsx
Normal file
101
src/components/CommunityModal/CommunityModal.tsx
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
import { createSignal, type Component } from "solid-js";
|
||||||
|
import { ICommunityModalProps } from "./types";
|
||||||
|
import { dispatch } from "../../store/state";
|
||||||
|
import { CommunityActionTypes } from "../../store/community";
|
||||||
|
import { InviteActionTypes } from "../../store/invite";
|
||||||
|
|
||||||
|
const CommunityModal: Component<ICommunityModalProps> = (props) => {
|
||||||
|
const [getCommunityName, setCommunityName] = createSignal<string>("");
|
||||||
|
const [getInviteId, setInviteId] = createSignal<string>("");
|
||||||
|
|
||||||
|
const onCreateCommunity = () => {
|
||||||
|
dispatch({
|
||||||
|
type: CommunityActionTypes.CREATE_COMMUNITY_START,
|
||||||
|
payload: {
|
||||||
|
name: getCommunityName(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
setCommunityName("");
|
||||||
|
|
||||||
|
props.onClose?.();
|
||||||
|
};
|
||||||
|
|
||||||
|
const onJoinCommunity = () => {
|
||||||
|
dispatch({
|
||||||
|
type: InviteActionTypes.ACCEPT_INVITE_START,
|
||||||
|
payload: getInviteId(),
|
||||||
|
});
|
||||||
|
|
||||||
|
setInviteId("");
|
||||||
|
|
||||||
|
props.onClose?.();
|
||||||
|
};
|
||||||
|
|
||||||
|
const createCommunityHtml = () => (
|
||||||
|
<>
|
||||||
|
<h3 class="text-lg font-bold text-center mb-6">
|
||||||
|
Create a new Community
|
||||||
|
</h3>
|
||||||
|
<div class="bg-stone-800 h-16 p-2 flex flex-row gap-2 rounded-2xl">
|
||||||
|
<label class="bg-stone-800 input w-full h-full rounded-xl focus:border-none outline-none">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Enter name of the new community"
|
||||||
|
value={getCommunityName()}
|
||||||
|
onInput={(e) => setCommunityName(e.currentTarget.value)}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<button
|
||||||
|
class="bg-stone-950 btn btn-neutral h-full rounded-xl"
|
||||||
|
onClick={onCreateCommunity}
|
||||||
|
>
|
||||||
|
Create
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
const joinCommunityHtml = () => (
|
||||||
|
<>
|
||||||
|
<h3 class="text-lg font-bold text-center mb-6">
|
||||||
|
Join an existing Community
|
||||||
|
</h3>
|
||||||
|
<div class="bg-stone-800 h-16 p-2 flex flex-row gap-2 rounded-2xl">
|
||||||
|
<label class="bg-stone-800 input w-full h-full rounded-xl focus:border-none outline-none">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Enter invite ID"
|
||||||
|
value={getInviteId()}
|
||||||
|
onInput={(e) => setInviteId(e.currentTarget.value)}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<button
|
||||||
|
class="bg-stone-950 btn btn-neutral h-full rounded-xl"
|
||||||
|
onClick={onJoinCommunity}
|
||||||
|
>
|
||||||
|
Join
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<dialog ref={props.dialogRef} class="modal bg-[#00000050]">
|
||||||
|
<div class="modal-box bg-stone-950 rounded-3xl">
|
||||||
|
{createCommunityHtml()}
|
||||||
|
<div class="divider my-8"></div>
|
||||||
|
{joinCommunityHtml()}
|
||||||
|
</div>
|
||||||
|
<form
|
||||||
|
onClick={props.onClose}
|
||||||
|
method="dialog"
|
||||||
|
class="modal-backdrop"
|
||||||
|
></form>
|
||||||
|
</dialog>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CommunityModal;
|
||||||
2
src/components/CommunityModal/index.ts
Normal file
2
src/components/CommunityModal/index.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
export * from "./CommunityModal";
|
||||||
|
export * from "./types";
|
||||||
6
src/components/CommunityModal/types.ts
Normal file
6
src/components/CommunityModal/types.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
interface ICommunityModalProps {
|
||||||
|
dialogRef?: (element: HTMLDialogElement) => void;
|
||||||
|
onClose?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { type ICommunityModalProps };
|
||||||
22
src/components/HomeCard/HomeCard.tsx
Normal file
22
src/components/HomeCard/HomeCard.tsx
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
import type { Component } from "solid-js";
|
||||||
|
import { IHomeCardProps } from "./types";
|
||||||
|
import { Dynamic } from "solid-js/web";
|
||||||
|
|
||||||
|
const HomeCard: Component<IHomeCardProps> = (props: IHomeCardProps) => {
|
||||||
|
return (
|
||||||
|
<a class="w-60 cursor-pointer" onClick={props.onClick}>
|
||||||
|
<div class="card border-2 bg-stone-800 border-stone-500 hover:border-stone-100 w-60 h-60">
|
||||||
|
<div class="flex flex-col h-full gap-1 m-6">
|
||||||
|
<div class="w-20">
|
||||||
|
<Dynamic component={props.icon} />
|
||||||
|
</div>
|
||||||
|
<div class="grow"></div>
|
||||||
|
<h2 class="card-title">{props.title}</h2>
|
||||||
|
<p>{props.description}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { HomeCard };
|
||||||
2
src/components/HomeCard/index.ts
Normal file
2
src/components/HomeCard/index.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
export * from "./HomeCard";
|
||||||
|
export * from "./types";
|
||||||
11
src/components/HomeCard/types.ts
Normal file
11
src/components/HomeCard/types.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { JSXElement } from "solid-js";
|
||||||
|
import { IconParameters } from "../icons";
|
||||||
|
|
||||||
|
interface IHomeCardProps {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
onClick?: () => void;
|
||||||
|
icon: (props: IconParameters) => JSXElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { type IHomeCardProps };
|
||||||
|
|
@ -5,7 +5,7 @@ const Member: Component<IMemberProps> = (props: IMemberProps) => {
|
||||||
return (
|
return (
|
||||||
<li
|
<li
|
||||||
class={`flex flex-row gap-4 items-center p-1 cursor-pointer rounded-lg ${props.active ? "bg-stone-700 hover:bg-stone-700" : "hover:bg-stone-800"}`}
|
class={`flex flex-row gap-4 items-center p-1 cursor-pointer rounded-lg ${props.active ? "bg-stone-700 hover:bg-stone-700" : "hover:bg-stone-800"}`}
|
||||||
onClick={() => props.onMemberClick(props.id)}
|
onClick={() => props.onMemberClick?.(props.id)}
|
||||||
>
|
>
|
||||||
<div class="avatar">
|
<div class="avatar">
|
||||||
<div class="w-9 rounded-full">
|
<div class="w-9 rounded-full">
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ interface IMemberProps {
|
||||||
username: string;
|
username: string;
|
||||||
avatar: string;
|
avatar: string;
|
||||||
active: boolean;
|
active: boolean;
|
||||||
onMemberClick: (id: string) => void;
|
onMemberClick?: (id: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { type IMemberProps };
|
export { type IMemberProps };
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ const Message: Component<IMessageProps> = (props: IMessageProps) => {
|
||||||
<li class="list-row p-3 hover:bg-stone-700">
|
<li class="list-row p-3 hover:bg-stone-700">
|
||||||
<div
|
<div
|
||||||
class="avatar cursor-pointer"
|
class="avatar cursor-pointer"
|
||||||
onClick={() => props.onProfileClick(props.userId)}
|
onClick={() => props.onProfileClick?.(props.userId)}
|
||||||
>
|
>
|
||||||
<div class="w-10 rounded-full">
|
<div class="w-10 rounded-full">
|
||||||
<img src={props.avatar} />
|
<img src={props.avatar} />
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ interface IMessageProps {
|
||||||
userId: string;
|
userId: string;
|
||||||
username: string;
|
username: string;
|
||||||
avatar: string;
|
avatar: string;
|
||||||
onProfileClick: (userId: string) => void;
|
onProfileClick?: (userId: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { type IMessageProps };
|
export { type IMessageProps };
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import type { Component } from "solid-js";
|
import type { Component } from "solid-js";
|
||||||
import { state } from "../../store/state";
|
|
||||||
|
|
||||||
const MessageBar: Component = () => {
|
const MessageBar: Component = () => {
|
||||||
return (
|
return (
|
||||||
|
|
@ -8,7 +7,7 @@ const MessageBar: Component = () => {
|
||||||
<label class="bg-stone-800/50 backdrop-blur-lg input w-full h-full rounded-full focus:border-none outline-none">
|
<label class="bg-stone-800/50 backdrop-blur-lg input w-full h-full rounded-full focus:border-none outline-none">
|
||||||
<input type="text" placeholder="Send a message..." />
|
<input type="text" placeholder="Send a message..." />
|
||||||
</label>
|
</label>
|
||||||
<button class="bg-black/50 backdrop-blur-lg btn btn-neutral h-full rounded-full">
|
<button class="bg-stone-950/50 backdrop-blur-lg btn btn-neutral h-full rounded-full">
|
||||||
Send
|
Send
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
22
src/components/SettingsModal/SettingsModal.tsx
Normal file
22
src/components/SettingsModal/SettingsModal.tsx
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
import type { Component } from "solid-js";
|
||||||
|
import { ISettingsModalProps } from "./types";
|
||||||
|
|
||||||
|
const SettingsModal: Component<ISettingsModalProps> = (props) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<dialog ref={props.dialogRef} class="modal bg-[#00000050]">
|
||||||
|
<div class="modal-box bg-stone-950 rounded-3xl">
|
||||||
|
<h3 class="text-lg font-bold text-center">Settings</h3>
|
||||||
|
<p class="py-4 text-center">Not implemented yet</p>
|
||||||
|
</div>
|
||||||
|
<form
|
||||||
|
onClick={props.onClose}
|
||||||
|
method="dialog"
|
||||||
|
class="modal-backdrop"
|
||||||
|
></form>
|
||||||
|
</dialog>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SettingsModal;
|
||||||
2
src/components/SettingsModal/index.ts
Normal file
2
src/components/SettingsModal/index.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
export * from "./SettingsModal";
|
||||||
|
export * from "./types";
|
||||||
6
src/components/SettingsModal/types.ts
Normal file
6
src/components/SettingsModal/types.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
interface ISettingsModalProps {
|
||||||
|
dialogRef?: (element: HTMLDialogElement) => void;
|
||||||
|
onClose?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { type ISettingsModalProps };
|
||||||
18
src/components/SidebarItem/SidebarItem.tsx
Normal file
18
src/components/SidebarItem/SidebarItem.tsx
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
import type { Component } from "solid-js";
|
||||||
|
import { ISidebarItemProps } from "./types";
|
||||||
|
import { Dynamic } from "solid-js/web";
|
||||||
|
|
||||||
|
const SidebarItem: Component<ISidebarItemProps> = (
|
||||||
|
props: ISidebarItemProps,
|
||||||
|
) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
class={`bg-stone-800 w-full p-2 cursor-pointer transition-[border-radius] duration-300 outline-stone-300 ${props.active ? "rounded-lg outline-3 hover:outline-3" : "rounded-4xl hover:outline-2"}`}
|
||||||
|
onClick={() => props.onClick?.()}
|
||||||
|
>
|
||||||
|
<Dynamic component={props.icon} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { SidebarItem };
|
||||||
2
src/components/SidebarItem/index.ts
Normal file
2
src/components/SidebarItem/index.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
export * from "./SidebarItem";
|
||||||
|
export * from "./types";
|
||||||
10
src/components/SidebarItem/types.ts
Normal file
10
src/components/SidebarItem/types.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { JSXElement } from "solid-js";
|
||||||
|
import { IconParameters } from "../icons";
|
||||||
|
|
||||||
|
interface ISidebarItemProps {
|
||||||
|
icon: (props: IconParameters) => JSXElement;
|
||||||
|
active: boolean;
|
||||||
|
onClick?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { type ISidebarItemProps };
|
||||||
28
src/components/icons/HomeIcon.tsx
Normal file
28
src/components/icons/HomeIcon.tsx
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
import type { Component } from "solid-js";
|
||||||
|
|
||||||
|
import { IconParameters, defaultFillIconParameters as defaults } from "./types";
|
||||||
|
|
||||||
|
const HomeIcon: Component<IconParameters> = ({
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
fill = defaults.fill,
|
||||||
|
stroke = defaults.stroke,
|
||||||
|
strokeWidth = defaults.strokeWidth,
|
||||||
|
}: IconParameters) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width={width}
|
||||||
|
height={height}
|
||||||
|
fill={fill}
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width={strokeWidth}
|
||||||
|
stroke={stroke}
|
||||||
|
>
|
||||||
|
<path d="M11.47 3.841a.75.75 0 0 1 1.06 0l8.69 8.69a.75.75 0 1 0 1.06-1.061l-8.689-8.69a2.25 2.25 0 0 0-3.182 0l-8.69 8.69a.75.75 0 1 0 1.061 1.06l8.69-8.689Z" />
|
||||||
|
<path d="m12 5.432 8.159 8.159c.03.03.06.058.091.086v6.198c0 1.035-.84 1.875-1.875 1.875H15a.75.75 0 0 1-.75-.75v-4.5a.75.75 0 0 0-.75-.75h-3a.75.75 0 0 0-.75.75V21a.75.75 0 0 1-.75.75H5.625a1.875 1.875 0 0 1-1.875-1.875v-6.198a2.29 2.29 0 0 0 .091-.086L12 5.432Z" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default HomeIcon;
|
||||||
31
src/components/icons/PlusIcon.tsx
Normal file
31
src/components/icons/PlusIcon.tsx
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
import type { Component } from "solid-js";
|
||||||
|
|
||||||
|
import { IconParameters, defaultFillIconParameters as defaults } from "./types";
|
||||||
|
|
||||||
|
const PlusIcon: Component<IconParameters> = ({
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
fill = defaults.fill,
|
||||||
|
stroke = defaults.stroke,
|
||||||
|
strokeWidth = defaults.strokeWidth,
|
||||||
|
}: IconParameters) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width={width}
|
||||||
|
height={height}
|
||||||
|
fill={fill}
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width={strokeWidth}
|
||||||
|
stroke={stroke}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M12 3.75a.75.75 0 0 1 .75.75v6.75h6.75a.75.75 0 0 1 0 1.5h-6.75v6.75a.75.75 0 0 1-1.5 0v-6.75H4.5a.75.75 0 0 1 0-1.5h6.75V4.5a.75.75 0 0 1 .75-.75Z"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PlusIcon;
|
||||||
31
src/components/icons/SettingsIcon.tsx
Normal file
31
src/components/icons/SettingsIcon.tsx
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
import type { Component } from "solid-js";
|
||||||
|
|
||||||
|
import { IconParameters, defaultFillIconParameters as defaults } from "./types";
|
||||||
|
|
||||||
|
const SettingsIcon: Component<IconParameters> = ({
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
fill = defaults.fill,
|
||||||
|
stroke = defaults.stroke,
|
||||||
|
strokeWidth = defaults.strokeWidth,
|
||||||
|
}: IconParameters) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width={width}
|
||||||
|
height={height}
|
||||||
|
fill={fill}
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width={strokeWidth}
|
||||||
|
stroke={stroke}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M11.078 2.25c-.917 0-1.699.663-1.85 1.567L9.05 4.889c-.02.12-.115.26-.297.348a7.493 7.493 0 0 0-.986.57c-.166.115-.334.126-.45.083L6.3 5.508a1.875 1.875 0 0 0-2.282.819l-.922 1.597a1.875 1.875 0 0 0 .432 2.385l.84.692c.095.078.17.229.154.43a7.598 7.598 0 0 0 0 1.139c.015.2-.059.352-.153.43l-.841.692a1.875 1.875 0 0 0-.432 2.385l.922 1.597a1.875 1.875 0 0 0 2.282.818l1.019-.382c.115-.043.283-.031.45.082.312.214.641.405.985.57.182.088.277.228.297.35l.178 1.071c.151.904.933 1.567 1.85 1.567h1.844c.916 0 1.699-.663 1.85-1.567l.178-1.072c.02-.12.114-.26.297-.349.344-.165.673-.356.985-.57.167-.114.335-.125.45-.082l1.02.382a1.875 1.875 0 0 0 2.28-.819l.923-1.597a1.875 1.875 0 0 0-.432-2.385l-.84-.692c-.095-.078-.17-.229-.154-.43a7.614 7.614 0 0 0 0-1.139c-.016-.2.059-.352.153-.43l.84-.692c.708-.582.891-1.59.433-2.385l-.922-1.597a1.875 1.875 0 0 0-2.282-.818l-1.02.382c-.114.043-.282.031-.449-.083a7.49 7.49 0 0 0-.985-.57c-.183-.087-.277-.227-.297-.348l-.179-1.072a1.875 1.875 0 0 0-1.85-1.567h-1.843ZM12 15.75a3.75 3.75 0 1 0 0-7.5 3.75 3.75 0 0 0 0 7.5Z"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SettingsIcon;
|
||||||
7
src/components/icons/index.ts
Normal file
7
src/components/icons/index.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import HomeIcon from "./HomeIcon";
|
||||||
|
import SettingsIcon from "./SettingsIcon";
|
||||||
|
import PlusIcon from "./PlusIcon";
|
||||||
|
|
||||||
|
import type { IconParameters } from "./types";
|
||||||
|
|
||||||
|
export { IconParameters, HomeIcon, SettingsIcon, PlusIcon };
|
||||||
26
src/components/icons/types.ts
Normal file
26
src/components/icons/types.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
interface IconParameters {
|
||||||
|
width?: number
|
||||||
|
height?: number
|
||||||
|
fill?: string
|
||||||
|
stroke?: string
|
||||||
|
strokeWidth?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultFillIconParameters: IconParameters = {
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
fill: 'currentColor',
|
||||||
|
stroke: 'none',
|
||||||
|
strokeWidth: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultStrokeIconParameters: IconParameters = {
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
fill: 'none',
|
||||||
|
stroke: 'currentColor',
|
||||||
|
strokeWidth: 1.5,
|
||||||
|
}
|
||||||
|
|
||||||
|
export type { IconParameters }
|
||||||
|
export { defaultFillIconParameters, defaultStrokeIconParameters }
|
||||||
|
|
@ -30,10 +30,15 @@ const createChannel = async (name: string, communityId: string) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateChannel = async (id: string, name?: string) => {
|
const updateChannel = async (
|
||||||
|
id: string,
|
||||||
|
name?: string,
|
||||||
|
description?: string,
|
||||||
|
) => {
|
||||||
const data = await updateChannelApi({
|
const data = await updateChannelApi({
|
||||||
id: id,
|
id: id,
|
||||||
name: name,
|
name: name,
|
||||||
|
description: description,
|
||||||
});
|
});
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,19 @@
|
||||||
import {
|
import {
|
||||||
fetchCommunityApi,
|
fetchCommunityApi,
|
||||||
|
createCommunityApi,
|
||||||
|
updateCommunityApi,
|
||||||
|
removeCommunityApi,
|
||||||
fetchCommunityChannelsApi,
|
fetchCommunityChannelsApi,
|
||||||
fetchCommunityRolesApi,
|
fetchCommunityRolesApi,
|
||||||
fetchCommunityMembersApi,
|
fetchCommunityMembersApi,
|
||||||
|
fetchCommunityInvitesApi,
|
||||||
} from "../../api/community";
|
} from "../../api/community";
|
||||||
import { CommunityActionTypes } from "../../store/community";
|
import { CommunityActionTypes } from "../../store/community";
|
||||||
import { ChannelActionTypes } from "../../store/channel";
|
import { ChannelActionTypes } from "../../store/channel";
|
||||||
import { RoleActionTypes } from "../../store/role";
|
import { RoleActionTypes } from "../../store/role";
|
||||||
import { UserActionTypes } from "../../store/user";
|
import { UserActionTypes } from "../../store/user";
|
||||||
import { dispatch } from "../../store/state";
|
import { dispatch, state } from "../../store/state";
|
||||||
|
import { InviteActionTypes } from "../../store/invite";
|
||||||
|
|
||||||
const fetchCommunity = async (id: string) => {
|
const fetchCommunity = async (id: string) => {
|
||||||
const data = await fetchCommunityApi({
|
const data = await fetchCommunityApi({
|
||||||
|
|
@ -21,6 +26,66 @@ const fetchCommunity = async (id: string) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const createCommunity = async (name: string) => {
|
||||||
|
const data = await createCommunityApi({
|
||||||
|
name: name,
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: CommunityActionTypes.CREATE_COMMUNITY_FINISH,
|
||||||
|
payload: data,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (state.user.loggedUserId) {
|
||||||
|
dispatch({
|
||||||
|
type: UserActionTypes.FETCH_USER_COMMUNITIES_START,
|
||||||
|
payload: state.user.loggedUserId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateCommunity = async (
|
||||||
|
id: string,
|
||||||
|
name?: string,
|
||||||
|
description?: string,
|
||||||
|
) => {
|
||||||
|
const data = await updateCommunityApi({
|
||||||
|
id: id,
|
||||||
|
name: name,
|
||||||
|
description: description,
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: CommunityActionTypes.UPDATE_COMMUNITY_FINISH,
|
||||||
|
payload: data,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (state.user.loggedUserId) {
|
||||||
|
dispatch({
|
||||||
|
type: UserActionTypes.FETCH_USER_COMMUNITIES_START,
|
||||||
|
payload: state.user.loggedUserId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeCommunity = async (id: string) => {
|
||||||
|
const data = await removeCommunityApi({
|
||||||
|
id: id,
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: CommunityActionTypes.REMOVE_COMMUNITY_FINISH,
|
||||||
|
payload: data,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (state.user.loggedUserId) {
|
||||||
|
dispatch({
|
||||||
|
type: UserActionTypes.FETCH_USER_COMMUNITIES_START,
|
||||||
|
payload: state.user.loggedUserId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const fetchCommunityChannels = async (id: string) => {
|
const fetchCommunityChannels = async (id: string) => {
|
||||||
const data = await fetchCommunityChannelsApi({
|
const data = await fetchCommunityChannelsApi({
|
||||||
id: id,
|
id: id,
|
||||||
|
|
@ -75,9 +140,31 @@ const fetchCommunityMembers = async (id: string) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fetchCommunityInvites = async (id: string) => {
|
||||||
|
const data = await fetchCommunityInvitesApi({
|
||||||
|
id: id,
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: CommunityActionTypes.FETCH_COMMUNITY_INVITES_FINISH,
|
||||||
|
payload: data,
|
||||||
|
});
|
||||||
|
|
||||||
|
data.invites.forEach((invite) => {
|
||||||
|
dispatch({
|
||||||
|
type: InviteActionTypes.SET_INVITE,
|
||||||
|
payload: invite,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
fetchCommunity,
|
fetchCommunity,
|
||||||
|
createCommunity,
|
||||||
|
updateCommunity,
|
||||||
|
removeCommunity,
|
||||||
fetchCommunityChannels,
|
fetchCommunityChannels,
|
||||||
fetchCommunityRoles,
|
fetchCommunityRoles,
|
||||||
fetchCommunityMembers,
|
fetchCommunityMembers,
|
||||||
|
fetchCommunityInvites,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
1
src/services/invite/index.ts
Normal file
1
src/services/invite/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
export * from "./invite";
|
||||||
50
src/services/invite/invite.ts
Normal file
50
src/services/invite/invite.ts
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
import {
|
||||||
|
fetchInviteApi,
|
||||||
|
removeInviteApi,
|
||||||
|
acceptInviteApi,
|
||||||
|
} from "../../api/invite";
|
||||||
|
import { InviteActionTypes } from "../../store/invite";
|
||||||
|
import { dispatch, state } from "../../store/state";
|
||||||
|
import { UserActionTypes } from "../../store/user";
|
||||||
|
|
||||||
|
const fetchInvite = async (id: string) => {
|
||||||
|
const data = await fetchInviteApi({
|
||||||
|
id: id,
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: InviteActionTypes.FETCH_INVITE_FINISH,
|
||||||
|
payload: data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeInvite = async (id: string) => {
|
||||||
|
const data = await removeInviteApi({
|
||||||
|
id: id,
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: InviteActionTypes.REMOVE_INVITE_FINISH,
|
||||||
|
payload: data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const acceptInvite = async (id: string) => {
|
||||||
|
const data = await acceptInviteApi({
|
||||||
|
id: id,
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: InviteActionTypes.ACCEPT_INVITE_FINISH,
|
||||||
|
payload: data,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (state.user.loggedUserId) {
|
||||||
|
dispatch({
|
||||||
|
type: UserActionTypes.FETCH_USER_COMMUNITIES_START,
|
||||||
|
payload: state.user.loggedUserId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export { fetchInvite, removeInvite, acceptInvite };
|
||||||
1
src/services/session/index.ts
Normal file
1
src/services/session/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
export * from "./session";
|
||||||
27
src/services/session/session.ts
Normal file
27
src/services/session/session.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { fetchSessionApi, removeSessionApi } from "../../api/session";
|
||||||
|
import { SessionActionTypes } from "../../store/session";
|
||||||
|
import { dispatch } from "../../store/state";
|
||||||
|
|
||||||
|
const fetchSession = async (id: string) => {
|
||||||
|
const data = await fetchSessionApi({
|
||||||
|
id: id,
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: SessionActionTypes.FETCH_SESSION_FINISH,
|
||||||
|
payload: data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeSession = async (id: string) => {
|
||||||
|
const data = await removeSessionApi({
|
||||||
|
id: id,
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: SessionActionTypes.REMOVE_SESSION_FINISH,
|
||||||
|
payload: data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export { fetchSession, removeSession };
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
import {
|
import {
|
||||||
fetchLoggedUserApi,
|
fetchLoggedUserApi,
|
||||||
fetchUserApi,
|
fetchUserApi,
|
||||||
|
fetchUserSessionsApi,
|
||||||
fetchUserCommunitiesApi,
|
fetchUserCommunitiesApi,
|
||||||
} from "../../api/user";
|
} from "../../api/user";
|
||||||
import { UserActionTypes } from "../../store/user";
|
import { UserActionTypes } from "../../store/user";
|
||||||
import { CommunityActionTypes } from "../../store/community";
|
import { CommunityActionTypes } from "../../store/community";
|
||||||
import { dispatch } from "../../store/state";
|
import { dispatch } from "../../store/state";
|
||||||
|
import { SessionActionTypes } from "../../store/session";
|
||||||
|
|
||||||
const fetchLoggedUser = async () => {
|
const fetchLoggedUser = async () => {
|
||||||
const data = await fetchLoggedUserApi();
|
const data = await fetchLoggedUserApi();
|
||||||
|
|
@ -27,6 +29,24 @@ const fetchUser = async (id: string) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fetchUserSessions = async (id: string) => {
|
||||||
|
const data = await fetchUserSessionsApi({
|
||||||
|
id: id,
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: UserActionTypes.FETCH_USER_SESSIONS_FINISH,
|
||||||
|
payload: data,
|
||||||
|
});
|
||||||
|
|
||||||
|
data.sessions.forEach((session) => {
|
||||||
|
dispatch({
|
||||||
|
type: SessionActionTypes.SET_SESSION,
|
||||||
|
payload: session,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const fetchUserCommunities = async (id: string) => {
|
const fetchUserCommunities = async (id: string) => {
|
||||||
const data = await fetchUserCommunitiesApi({
|
const data = await fetchUserCommunitiesApi({
|
||||||
id: id,
|
id: id,
|
||||||
|
|
@ -45,4 +65,4 @@ const fetchUserCommunities = async (id: string) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export { fetchLoggedUser, fetchUser, fetchUserCommunities };
|
export { fetchLoggedUser, fetchUser, fetchUserSessions, fetchUserCommunities };
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,30 @@
|
||||||
|
import { AppActionTypes, AppAction } from "./app";
|
||||||
import { AuthActionTypes, AuthAction } from "./auth";
|
import { AuthActionTypes, AuthAction } from "./auth";
|
||||||
import { UserActionTypes, UserAction } from "./user";
|
import { UserActionTypes, UserAction } from "./user";
|
||||||
import { CommunityActionTypes, CommunityAction } from "./community";
|
import { CommunityActionTypes, CommunityAction } from "./community";
|
||||||
import { ChannelActionTypes, ChannelAction } from "./channel";
|
import { ChannelActionTypes, ChannelAction } from "./channel";
|
||||||
import { RoleActionTypes, RoleAction } from "./role";
|
import { RoleActionTypes, RoleAction } from "./role";
|
||||||
|
import { SessionActionTypes, SessionAction } from "./session";
|
||||||
|
import { InviteActionTypes, InviteAction } from "./invite";
|
||||||
|
|
||||||
type ActionTypes =
|
type ActionTypes =
|
||||||
|
| AppActionTypes
|
||||||
| AuthActionTypes
|
| AuthActionTypes
|
||||||
| UserActionTypes
|
| UserActionTypes
|
||||||
| CommunityActionTypes
|
| CommunityActionTypes
|
||||||
| ChannelActionTypes
|
| ChannelActionTypes
|
||||||
| RoleActionTypes;
|
| RoleActionTypes
|
||||||
|
| SessionActionTypes
|
||||||
|
| InviteActionTypes;
|
||||||
|
|
||||||
type Action =
|
type Action =
|
||||||
|
| AppAction
|
||||||
| AuthAction
|
| AuthAction
|
||||||
| UserAction
|
| UserAction
|
||||||
| CommunityAction
|
| CommunityAction
|
||||||
| ChannelAction
|
| ChannelAction
|
||||||
| RoleAction;
|
| RoleAction
|
||||||
|
| SessionAction
|
||||||
|
| InviteAction;
|
||||||
|
|
||||||
export { type Action, type ActionTypes };
|
export { type Action, type ActionTypes };
|
||||||
|
|
|
||||||
12
src/store/app/actions.ts
Normal file
12
src/store/app/actions.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
enum AppActionTypes {
|
||||||
|
SET_HOME_OPEN = "SET_HOME_OPEN",
|
||||||
|
SET_SETTINGS_OPEN = "SET_SETTINGS_OPEN",
|
||||||
|
SET_ADD_COMMUNITY_OPEN = "SET_ADD_COMMUNITY_OPEN",
|
||||||
|
}
|
||||||
|
|
||||||
|
type AppAction =
|
||||||
|
| { type: AppActionTypes.SET_HOME_OPEN; payload: boolean }
|
||||||
|
| { type: AppActionTypes.SET_SETTINGS_OPEN; payload: boolean }
|
||||||
|
| { type: AppActionTypes.SET_ADD_COMMUNITY_OPEN; payload: boolean };
|
||||||
|
|
||||||
|
export { AppActionTypes, type AppAction };
|
||||||
21
src/store/app/app.ts
Normal file
21
src/store/app/app.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { setState } from "../state";
|
||||||
|
import { AppActionTypes, AppAction } from "./actions";
|
||||||
|
import { IAppState } from "./types";
|
||||||
|
|
||||||
|
function appReducer(_state: IAppState, action: AppAction) {
|
||||||
|
switch (action.type) {
|
||||||
|
case AppActionTypes.SET_HOME_OPEN:
|
||||||
|
setState("app", "homeOpen", action.payload);
|
||||||
|
break;
|
||||||
|
case AppActionTypes.SET_SETTINGS_OPEN:
|
||||||
|
setState("app", "dialogsOpen", "settingsOpen", false);
|
||||||
|
setState("app", "dialogsOpen", "settingsOpen", action.payload);
|
||||||
|
break;
|
||||||
|
case AppActionTypes.SET_ADD_COMMUNITY_OPEN:
|
||||||
|
setState("app", "dialogsOpen", "addCommunityOpen", false);
|
||||||
|
setState("app", "dialogsOpen", "addCommunityOpen", action.payload);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { appReducer };
|
||||||
3
src/store/app/index.ts
Normal file
3
src/store/app/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
export * from "./app";
|
||||||
|
export * from "./actions";
|
||||||
|
export * from "./types";
|
||||||
11
src/store/app/types.ts
Normal file
11
src/store/app/types.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
interface IAppState {
|
||||||
|
homeOpen: boolean;
|
||||||
|
dialogsOpen: IDialogsOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IDialogsOpen {
|
||||||
|
settingsOpen: boolean;
|
||||||
|
addCommunityOpen: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { type IAppState, type IDialogsOpen };
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import {
|
import {
|
||||||
ICreateChannelRequest,
|
ICreateChannelRequest,
|
||||||
|
IUpdateChannelRequest,
|
||||||
IFetchChannelResponse,
|
IFetchChannelResponse,
|
||||||
ICreateChannelResponse,
|
ICreateChannelResponse,
|
||||||
IUpdateChannelResponse,
|
IUpdateChannelResponse,
|
||||||
|
|
@ -27,7 +28,7 @@ type ChannelAction =
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
type: ChannelActionTypes.SET_ACTIVE_CHANNEL;
|
type: ChannelActionTypes.SET_ACTIVE_CHANNEL;
|
||||||
payload: string;
|
payload: string | undefined;
|
||||||
}
|
}
|
||||||
| { type: ChannelActionTypes.FETCH_CHANNEL_START; payload: string }
|
| { type: ChannelActionTypes.FETCH_CHANNEL_START; payload: string }
|
||||||
| {
|
| {
|
||||||
|
|
@ -42,7 +43,10 @@ type ChannelAction =
|
||||||
type: ChannelActionTypes.CREATE_CHANNEL_FINISH;
|
type: ChannelActionTypes.CREATE_CHANNEL_FINISH;
|
||||||
payload: ICreateChannelResponse;
|
payload: ICreateChannelResponse;
|
||||||
}
|
}
|
||||||
| { type: ChannelActionTypes.UPDATE_CHANNEL_START; payload: string }
|
| {
|
||||||
|
type: ChannelActionTypes.UPDATE_CHANNEL_START;
|
||||||
|
payload: IUpdateChannelRequest;
|
||||||
|
}
|
||||||
| {
|
| {
|
||||||
type: ChannelActionTypes.UPDATE_CHANNEL_FINISH;
|
type: ChannelActionTypes.UPDATE_CHANNEL_FINISH;
|
||||||
payload: IUpdateChannelResponse;
|
payload: IUpdateChannelResponse;
|
||||||
|
|
|
||||||
|
|
@ -26,27 +26,26 @@ function channelReducer(state: IChannelState, action: ChannelAction) {
|
||||||
createChannel(action.payload.name, action.payload.communityId);
|
createChannel(action.payload.name, action.payload.communityId);
|
||||||
break;
|
break;
|
||||||
case ChannelActionTypes.CREATE_CHANNEL_FINISH:
|
case ChannelActionTypes.CREATE_CHANNEL_FINISH:
|
||||||
setState("channel", "channels", {
|
setState("channel", "channels", action.payload.id, action.payload);
|
||||||
...state.channels,
|
|
||||||
[action.payload.id]: action.payload,
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case ChannelActionTypes.UPDATE_CHANNEL_START:
|
case ChannelActionTypes.UPDATE_CHANNEL_START:
|
||||||
updateChannel(action.payload);
|
updateChannel(
|
||||||
|
action.payload.id,
|
||||||
|
action.payload.name,
|
||||||
|
action.payload.description,
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case ChannelActionTypes.UPDATE_CHANNEL_FINISH:
|
case ChannelActionTypes.UPDATE_CHANNEL_FINISH:
|
||||||
setState("channel", "channels", {
|
setState("channel", "channels", action.payload.id, action.payload);
|
||||||
...state.channels,
|
|
||||||
[action.payload.id]: action.payload,
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case ChannelActionTypes.REMOVE_CHANNEL_START:
|
case ChannelActionTypes.REMOVE_CHANNEL_START:
|
||||||
removeChannel(action.payload);
|
removeChannel(action.payload);
|
||||||
break;
|
break;
|
||||||
case ChannelActionTypes.REMOVE_CHANNEL_FINISH:
|
case ChannelActionTypes.REMOVE_CHANNEL_FINISH:
|
||||||
setState("channel", "channels", {
|
setState("channel", "channels", (channels) => {
|
||||||
...state.channels,
|
const copy = { ...channels };
|
||||||
[action.payload.id]: undefined,
|
delete copy[action.payload.id];
|
||||||
|
return copy;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
interface IChannelState {
|
interface IChannelState {
|
||||||
active: string;
|
active?: string;
|
||||||
channels: Record<string, IChannel>;
|
channels: Record<string, IChannel>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,14 @@
|
||||||
import {
|
import {
|
||||||
|
ICreateCommunityRequest,
|
||||||
|
IUpdateCommunityRequest,
|
||||||
IFetchCommunityResponse,
|
IFetchCommunityResponse,
|
||||||
|
ICreateCommunityResponse,
|
||||||
|
IUpdateCommunityResponse,
|
||||||
|
IRemoveCommunityResponse,
|
||||||
IFetchCommunityChannelsResponse,
|
IFetchCommunityChannelsResponse,
|
||||||
IFetchCommunityRolesResponse,
|
IFetchCommunityRolesResponse,
|
||||||
IFetchCommunityMembersResponse,
|
IFetchCommunityMembersResponse,
|
||||||
|
IFetchCommunityInvitesResponse,
|
||||||
} from "../../api/community";
|
} from "../../api/community";
|
||||||
import { IFetchUserCommunity } from "../../api/user";
|
import { IFetchUserCommunity } from "../../api/user";
|
||||||
|
|
||||||
|
|
@ -11,12 +17,20 @@ enum CommunityActionTypes {
|
||||||
SET_ACTIVE_COMMUNITY = "SET_ACTIVE_COMMUNITY",
|
SET_ACTIVE_COMMUNITY = "SET_ACTIVE_COMMUNITY",
|
||||||
FETCH_COMMUNITY_START = "FETCH_COMMUNITY_START",
|
FETCH_COMMUNITY_START = "FETCH_COMMUNITY_START",
|
||||||
FETCH_COMMUNITY_FINISH = "FETCH_COMMUNITY_FINISH",
|
FETCH_COMMUNITY_FINISH = "FETCH_COMMUNITY_FINISH",
|
||||||
|
CREATE_COMMUNITY_START = "CREATE_COMMUNITY_START",
|
||||||
|
CREATE_COMMUNITY_FINISH = "CREATE_COMMUNITY_FINISH",
|
||||||
|
UPDATE_COMMUNITY_START = "UPDATE_COMMUNITY_START",
|
||||||
|
UPDATE_COMMUNITY_FINISH = "UPDATE_COMMUNITY_FINISH",
|
||||||
|
REMOVE_COMMUNITY_START = "REMOVE_COMMUNITY_START",
|
||||||
|
REMOVE_COMMUNITY_FINISH = "REMOVE_COMMUNITY_FINISH",
|
||||||
FETCH_COMMUNITY_CHANNELS_START = "FETCH_COMMUNITY_CHANNELS_START",
|
FETCH_COMMUNITY_CHANNELS_START = "FETCH_COMMUNITY_CHANNELS_START",
|
||||||
FETCH_COMMUNITY_CHANNELS_FINISH = "FETCH_COMMUNITY_CHANNELS_FINISH",
|
FETCH_COMMUNITY_CHANNELS_FINISH = "FETCH_COMMUNITY_CHANNELS_FINISH",
|
||||||
FETCH_COMMUNITY_ROLES_START = "FETCH_COMMUNITY_ROLES_START",
|
FETCH_COMMUNITY_ROLES_START = "FETCH_COMMUNITY_ROLES_START",
|
||||||
FETCH_COMMUNITY_ROLES_FINISH = "FETCH_COMMUNITY_ROLES_FINISH",
|
FETCH_COMMUNITY_ROLES_FINISH = "FETCH_COMMUNITY_ROLES_FINISH",
|
||||||
FETCH_COMMUNITY_MEMBERS_START = "FETCH_COMMUNITY_MEMBERS_START",
|
FETCH_COMMUNITY_MEMBERS_START = "FETCH_COMMUNITY_MEMBERS_START",
|
||||||
FETCH_COMMUNITY_MEMBERS_FINISH = "FETCH_COMMUNITY_MEMBERS_FINISH",
|
FETCH_COMMUNITY_MEMBERS_FINISH = "FETCH_COMMUNITY_MEMBERS_FINISH",
|
||||||
|
FETCH_COMMUNITY_INVITES_START = "FETCH_COMMUNITY_INVITES_START",
|
||||||
|
FETCH_COMMUNITY_INVITES_FINISH = "FETCH_COMMUNITY_INVITES_FINISH",
|
||||||
}
|
}
|
||||||
|
|
||||||
type CommunityAction =
|
type CommunityAction =
|
||||||
|
|
@ -26,13 +40,34 @@ type CommunityAction =
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
type: CommunityActionTypes.SET_ACTIVE_COMMUNITY;
|
type: CommunityActionTypes.SET_ACTIVE_COMMUNITY;
|
||||||
payload: string;
|
payload: string | undefined;
|
||||||
}
|
}
|
||||||
| { type: CommunityActionTypes.FETCH_COMMUNITY_START; payload: string }
|
| { type: CommunityActionTypes.FETCH_COMMUNITY_START; payload: string }
|
||||||
| {
|
| {
|
||||||
type: CommunityActionTypes.FETCH_COMMUNITY_FINISH;
|
type: CommunityActionTypes.FETCH_COMMUNITY_FINISH;
|
||||||
payload: IFetchCommunityResponse;
|
payload: IFetchCommunityResponse;
|
||||||
}
|
}
|
||||||
|
| {
|
||||||
|
type: CommunityActionTypes.CREATE_COMMUNITY_START;
|
||||||
|
payload: ICreateCommunityRequest;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: CommunityActionTypes.CREATE_COMMUNITY_FINISH;
|
||||||
|
payload: ICreateCommunityResponse;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: CommunityActionTypes.UPDATE_COMMUNITY_START;
|
||||||
|
payload: IUpdateCommunityRequest;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: CommunityActionTypes.UPDATE_COMMUNITY_FINISH;
|
||||||
|
payload: IUpdateCommunityResponse;
|
||||||
|
}
|
||||||
|
| { type: CommunityActionTypes.REMOVE_COMMUNITY_START; payload: string }
|
||||||
|
| {
|
||||||
|
type: CommunityActionTypes.REMOVE_COMMUNITY_FINISH;
|
||||||
|
payload: IRemoveCommunityResponse;
|
||||||
|
}
|
||||||
| {
|
| {
|
||||||
type: CommunityActionTypes.FETCH_COMMUNITY_CHANNELS_START;
|
type: CommunityActionTypes.FETCH_COMMUNITY_CHANNELS_START;
|
||||||
payload: string;
|
payload: string;
|
||||||
|
|
@ -56,6 +91,14 @@ type CommunityAction =
|
||||||
| {
|
| {
|
||||||
type: CommunityActionTypes.FETCH_COMMUNITY_MEMBERS_FINISH;
|
type: CommunityActionTypes.FETCH_COMMUNITY_MEMBERS_FINISH;
|
||||||
payload: IFetchCommunityMembersResponse;
|
payload: IFetchCommunityMembersResponse;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: CommunityActionTypes.FETCH_COMMUNITY_INVITES_START;
|
||||||
|
payload: string;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: CommunityActionTypes.FETCH_COMMUNITY_INVITES_FINISH;
|
||||||
|
payload: IFetchCommunityInvitesResponse;
|
||||||
};
|
};
|
||||||
|
|
||||||
export { CommunityActionTypes, type CommunityAction };
|
export { CommunityActionTypes, type CommunityAction };
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,12 @@
|
||||||
import {
|
import {
|
||||||
fetchCommunity,
|
fetchCommunity,
|
||||||
|
createCommunity,
|
||||||
|
updateCommunity,
|
||||||
|
removeCommunity,
|
||||||
fetchCommunityChannels,
|
fetchCommunityChannels,
|
||||||
fetchCommunityRoles,
|
fetchCommunityRoles,
|
||||||
fetchCommunityMembers,
|
fetchCommunityMembers,
|
||||||
|
fetchCommunityInvites,
|
||||||
} from "../../services/community";
|
} from "../../services/community";
|
||||||
import { setState } from "../state";
|
import { setState } from "../state";
|
||||||
import { CommunityActionTypes, CommunityAction } from "./actions";
|
import { CommunityActionTypes, CommunityAction } from "./actions";
|
||||||
|
|
@ -32,6 +36,42 @@ function communityReducer(state: ICommunityState, action: CommunityAction) {
|
||||||
action.payload,
|
action.payload,
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
case CommunityActionTypes.CREATE_COMMUNITY_START:
|
||||||
|
createCommunity(action.payload.name);
|
||||||
|
break;
|
||||||
|
case CommunityActionTypes.CREATE_COMMUNITY_FINISH:
|
||||||
|
setState(
|
||||||
|
"community",
|
||||||
|
"communities",
|
||||||
|
action.payload.id,
|
||||||
|
action.payload,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case CommunityActionTypes.UPDATE_COMMUNITY_START:
|
||||||
|
updateCommunity(
|
||||||
|
action.payload.id,
|
||||||
|
action.payload.name,
|
||||||
|
action.payload.description,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case CommunityActionTypes.UPDATE_COMMUNITY_FINISH:
|
||||||
|
setState(
|
||||||
|
"community",
|
||||||
|
"communities",
|
||||||
|
action.payload.id,
|
||||||
|
action.payload,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case CommunityActionTypes.REMOVE_COMMUNITY_START:
|
||||||
|
removeCommunity(action.payload);
|
||||||
|
break;
|
||||||
|
case CommunityActionTypes.REMOVE_COMMUNITY_FINISH:
|
||||||
|
setState("community", "communities", (communities) => {
|
||||||
|
const copy = { ...communities };
|
||||||
|
delete copy[action.payload.id];
|
||||||
|
return copy;
|
||||||
|
});
|
||||||
|
break;
|
||||||
case CommunityActionTypes.FETCH_COMMUNITY_CHANNELS_START:
|
case CommunityActionTypes.FETCH_COMMUNITY_CHANNELS_START:
|
||||||
fetchCommunityChannels(action.payload);
|
fetchCommunityChannels(action.payload);
|
||||||
break;
|
break;
|
||||||
|
|
@ -56,6 +96,14 @@ function communityReducer(state: ICommunityState, action: CommunityAction) {
|
||||||
members: action.payload.members.map((member) => member.id),
|
members: action.payload.members.map((member) => member.id),
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case CommunityActionTypes.FETCH_COMMUNITY_INVITES_START:
|
||||||
|
fetchCommunityInvites(action.payload);
|
||||||
|
break;
|
||||||
|
case CommunityActionTypes.FETCH_COMMUNITY_INVITES_FINISH:
|
||||||
|
setState("community", "communities", action.payload.id, {
|
||||||
|
invites: action.payload.invites.map((invite) => invite.id),
|
||||||
|
});
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
interface ICommunityState {
|
interface ICommunityState {
|
||||||
active: string;
|
active?: string;
|
||||||
communities: Record<string, ICommunity>;
|
communities: Record<string, ICommunity>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -12,6 +12,7 @@ interface ICommunity {
|
||||||
channels?: string[];
|
channels?: string[];
|
||||||
roles?: string[];
|
roles?: string[];
|
||||||
members?: string[];
|
members?: string[];
|
||||||
|
invites?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export { type ICommunityState, type ICommunity };
|
export { type ICommunityState, type ICommunity };
|
||||||
|
|
|
||||||
39
src/store/invite/actions.ts
Normal file
39
src/store/invite/actions.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { IFetchCommunityInvite } from "../../api/community";
|
||||||
|
import {
|
||||||
|
IFetchInviteResponse,
|
||||||
|
IRemoveInviteResponse,
|
||||||
|
IAcceptInviteResponse,
|
||||||
|
} from "../../api/invite";
|
||||||
|
|
||||||
|
enum InviteActionTypes {
|
||||||
|
SET_INVITE = "SET_INVITE",
|
||||||
|
FETCH_INVITE_START = "FETCH_INVITE_START",
|
||||||
|
FETCH_INVITE_FINISH = "FETCH_INVITE_FINISH",
|
||||||
|
REMOVE_INVITE_START = "REMOVE_INVITE_START",
|
||||||
|
REMOVE_INVITE_FINISH = "REMOVE_INVITE_FINISH",
|
||||||
|
ACCEPT_INVITE_START = "ACCEPT_INVITE_START",
|
||||||
|
ACCEPT_INVITE_FINISH = "ACCEPT_INVITE_FINISH",
|
||||||
|
}
|
||||||
|
|
||||||
|
type InviteAction =
|
||||||
|
| {
|
||||||
|
type: InviteActionTypes.SET_INVITE;
|
||||||
|
payload: IFetchCommunityInvite;
|
||||||
|
}
|
||||||
|
| { type: InviteActionTypes.FETCH_INVITE_START; payload: string }
|
||||||
|
| {
|
||||||
|
type: InviteActionTypes.FETCH_INVITE_FINISH;
|
||||||
|
payload: IFetchInviteResponse;
|
||||||
|
}
|
||||||
|
| { type: InviteActionTypes.REMOVE_INVITE_START; payload: string }
|
||||||
|
| {
|
||||||
|
type: InviteActionTypes.REMOVE_INVITE_FINISH;
|
||||||
|
payload: IRemoveInviteResponse;
|
||||||
|
}
|
||||||
|
| { type: InviteActionTypes.ACCEPT_INVITE_START; payload: string }
|
||||||
|
| {
|
||||||
|
type: InviteActionTypes.ACCEPT_INVITE_FINISH;
|
||||||
|
payload: IAcceptInviteResponse;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { InviteActionTypes, type InviteAction };
|
||||||
3
src/store/invite/index.ts
Normal file
3
src/store/invite/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
export * from "./invite";
|
||||||
|
export * from "./actions";
|
||||||
|
export * from "./types";
|
||||||
35
src/store/invite/invite.ts
Normal file
35
src/store/invite/invite.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
import { fetchInvite, removeInvite, acceptInvite } from "../../services/invite";
|
||||||
|
import { setState } from "../state";
|
||||||
|
import { InviteActionTypes, InviteAction } from "./actions";
|
||||||
|
import { IInviteState } from "./types";
|
||||||
|
|
||||||
|
function inviteReducer(state: IInviteState, action: InviteAction) {
|
||||||
|
switch (action.type) {
|
||||||
|
case InviteActionTypes.SET_INVITE:
|
||||||
|
setState("invite", "invites", action.payload.id, action.payload);
|
||||||
|
break;
|
||||||
|
case InviteActionTypes.FETCH_INVITE_START:
|
||||||
|
fetchInvite(action.payload);
|
||||||
|
break;
|
||||||
|
case InviteActionTypes.FETCH_INVITE_FINISH:
|
||||||
|
setState("invite", "invites", action.payload.id, action.payload);
|
||||||
|
break;
|
||||||
|
case InviteActionTypes.REMOVE_INVITE_START:
|
||||||
|
removeInvite(action.payload);
|
||||||
|
break;
|
||||||
|
case InviteActionTypes.REMOVE_INVITE_FINISH:
|
||||||
|
setState("invite", "invites", (invites) => {
|
||||||
|
const copy = { ...invites };
|
||||||
|
delete copy[action.payload.id];
|
||||||
|
return copy;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case InviteActionTypes.ACCEPT_INVITE_START:
|
||||||
|
acceptInvite(action.payload);
|
||||||
|
break;
|
||||||
|
case InviteActionTypes.ACCEPT_INVITE_FINISH:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { inviteReducer };
|
||||||
17
src/store/invite/types.ts
Normal file
17
src/store/invite/types.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
interface IInviteState {
|
||||||
|
invites: Record<string, IInvite>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IInvite {
|
||||||
|
id: string;
|
||||||
|
communityId?: string;
|
||||||
|
valid?: boolean;
|
||||||
|
unlimitedInvites?: boolean;
|
||||||
|
hasExpiration?: boolean;
|
||||||
|
totalInvites?: number;
|
||||||
|
remainingInvites?: number;
|
||||||
|
creationDate?: number;
|
||||||
|
expirationDate?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { type IInviteState, type IInvite };
|
||||||
|
|
@ -1,17 +1,23 @@
|
||||||
import { IState } from "./types";
|
import { IState } from "./types";
|
||||||
import { Action } from "./actions";
|
import { Action } from "./actions";
|
||||||
|
import { AppAction, appReducer } from "./app";
|
||||||
import { AuthAction, authReducer } from "./auth";
|
import { AuthAction, authReducer } from "./auth";
|
||||||
import { UserAction, userReducer } from "./user";
|
import { UserAction, userReducer } from "./user";
|
||||||
import { CommunityAction, communityReducer } from "./community";
|
import { CommunityAction, communityReducer } from "./community";
|
||||||
import { ChannelAction, channelReducer } from "./channel";
|
import { ChannelAction, channelReducer } from "./channel";
|
||||||
import { RoleAction, roleReducer } from "./role";
|
import { RoleAction, roleReducer } from "./role";
|
||||||
|
import { SessionAction, sessionReducer } from "./session";
|
||||||
|
import { InviteAction, inviteReducer } from "./invite";
|
||||||
|
|
||||||
function reducer(state: IState, action: Action) {
|
function reducer(state: IState, action: Action) {
|
||||||
|
appReducer(state.app, action as AppAction);
|
||||||
authReducer(state.auth, action as AuthAction);
|
authReducer(state.auth, action as AuthAction);
|
||||||
userReducer(state.user, action as UserAction);
|
userReducer(state.user, action as UserAction);
|
||||||
communityReducer(state.community, action as CommunityAction);
|
communityReducer(state.community, action as CommunityAction);
|
||||||
channelReducer(state.channel, action as ChannelAction);
|
channelReducer(state.channel, action as ChannelAction);
|
||||||
roleReducer(state.role, action as RoleAction);
|
roleReducer(state.role, action as RoleAction);
|
||||||
|
sessionReducer(state.session, action as SessionAction);
|
||||||
|
inviteReducer(state.invite, action as InviteAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
export { reducer };
|
export { reducer };
|
||||||
|
|
|
||||||
|
|
@ -23,27 +23,22 @@ function roleReducer(state: IRoleState, action: RoleAction) {
|
||||||
createRole(action.payload.name, action.payload.communityId);
|
createRole(action.payload.name, action.payload.communityId);
|
||||||
break;
|
break;
|
||||||
case RoleActionTypes.CREATE_ROLE_FINISH:
|
case RoleActionTypes.CREATE_ROLE_FINISH:
|
||||||
setState("role", "roles", {
|
setState("role", "roles", action.payload.id, action.payload);
|
||||||
...state.roles,
|
|
||||||
[action.payload.id]: action.payload,
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case RoleActionTypes.UPDATE_ROLE_START:
|
case RoleActionTypes.UPDATE_ROLE_START:
|
||||||
updateRole(action.payload);
|
updateRole(action.payload);
|
||||||
break;
|
break;
|
||||||
case RoleActionTypes.UPDATE_ROLE_FINISH:
|
case RoleActionTypes.UPDATE_ROLE_FINISH:
|
||||||
setState("role", "roles", {
|
setState("role", "roles", action.payload.id, action.payload);
|
||||||
...state.roles,
|
|
||||||
[action.payload.id]: action.payload,
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case RoleActionTypes.REMOVE_ROLE_START:
|
case RoleActionTypes.REMOVE_ROLE_START:
|
||||||
removeRole(action.payload);
|
removeRole(action.payload);
|
||||||
break;
|
break;
|
||||||
case RoleActionTypes.REMOVE_ROLE_FINISH:
|
case RoleActionTypes.REMOVE_ROLE_FINISH:
|
||||||
setState("role", "roles", {
|
setState("role", "roles", (roles) => {
|
||||||
...state.roles,
|
const copy = { ...roles };
|
||||||
[action.payload.id]: undefined,
|
delete copy[action.payload.id];
|
||||||
|
return copy;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
31
src/store/session/actions.ts
Normal file
31
src/store/session/actions.ts
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { IFetchUserSession } from "../../api/user";
|
||||||
|
import {
|
||||||
|
IFetchSessionResponse,
|
||||||
|
IRemoveSessionResponse,
|
||||||
|
} from "../../api/session";
|
||||||
|
|
||||||
|
enum SessionActionTypes {
|
||||||
|
SET_SESSION = "SET_SESSION",
|
||||||
|
FETCH_SESSION_START = "FETCH_SESSION_START",
|
||||||
|
FETCH_SESSION_FINISH = "FETCH_SESSION_FINISH",
|
||||||
|
REMOVE_SESSION_START = "REMOVE_SESSION_START",
|
||||||
|
REMOVE_SESSION_FINISH = "REMOVE_SESSION_FINISH",
|
||||||
|
}
|
||||||
|
|
||||||
|
type SessionAction =
|
||||||
|
| {
|
||||||
|
type: SessionActionTypes.SET_SESSION;
|
||||||
|
payload: IFetchUserSession;
|
||||||
|
}
|
||||||
|
| { type: SessionActionTypes.FETCH_SESSION_START; payload: string }
|
||||||
|
| {
|
||||||
|
type: SessionActionTypes.FETCH_SESSION_FINISH;
|
||||||
|
payload: IFetchSessionResponse;
|
||||||
|
}
|
||||||
|
| { type: SessionActionTypes.REMOVE_SESSION_START; payload: string }
|
||||||
|
| {
|
||||||
|
type: SessionActionTypes.REMOVE_SESSION_FINISH;
|
||||||
|
payload: IRemoveSessionResponse;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { SessionActionTypes, type SessionAction };
|
||||||
3
src/store/session/index.ts
Normal file
3
src/store/session/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
export * from "./session";
|
||||||
|
export * from "./actions";
|
||||||
|
export * from "./types";
|
||||||
30
src/store/session/session.ts
Normal file
30
src/store/session/session.ts
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { fetchSession, removeSession } from "../../services/session";
|
||||||
|
import { setState } from "../state";
|
||||||
|
import { SessionActionTypes, SessionAction } from "./actions";
|
||||||
|
import { ISessionState } from "./types";
|
||||||
|
|
||||||
|
function sessionReducer(state: ISessionState, action: SessionAction) {
|
||||||
|
switch (action.type) {
|
||||||
|
case SessionActionTypes.SET_SESSION:
|
||||||
|
setState("session", "sessions", action.payload.id, action.payload);
|
||||||
|
break;
|
||||||
|
case SessionActionTypes.FETCH_SESSION_START:
|
||||||
|
fetchSession(action.payload);
|
||||||
|
break;
|
||||||
|
case SessionActionTypes.FETCH_SESSION_FINISH:
|
||||||
|
setState("session", "sessions", action.payload.id, action.payload);
|
||||||
|
break;
|
||||||
|
case SessionActionTypes.REMOVE_SESSION_START:
|
||||||
|
removeSession(action.payload);
|
||||||
|
break;
|
||||||
|
case SessionActionTypes.REMOVE_SESSION_FINISH:
|
||||||
|
setState("session", "sessions", (sessions) => {
|
||||||
|
const copy = { ...sessions };
|
||||||
|
delete copy[action.payload.id];
|
||||||
|
return copy;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { sessionReducer };
|
||||||
11
src/store/session/types.ts
Normal file
11
src/store/session/types.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
interface ISessionState {
|
||||||
|
sessions: Record<string, ISession>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ISession {
|
||||||
|
id: string;
|
||||||
|
userId?: string;
|
||||||
|
creationDate?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { type ISessionState, type ISession };
|
||||||
|
|
@ -4,6 +4,13 @@ import { Action } from "./actions";
|
||||||
import { reducer } from "./reducers";
|
import { reducer } from "./reducers";
|
||||||
|
|
||||||
const [state, setState] = createStore<IState>({
|
const [state, setState] = createStore<IState>({
|
||||||
|
app: {
|
||||||
|
homeOpen: true,
|
||||||
|
dialogsOpen: {
|
||||||
|
settingsOpen: false,
|
||||||
|
addCommunityOpen: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
auth: {
|
auth: {
|
||||||
session: undefined,
|
session: undefined,
|
||||||
},
|
},
|
||||||
|
|
@ -20,6 +27,12 @@ const [state, setState] = createStore<IState>({
|
||||||
role: {
|
role: {
|
||||||
roles: {},
|
roles: {},
|
||||||
},
|
},
|
||||||
|
session: {
|
||||||
|
sessions: {},
|
||||||
|
},
|
||||||
|
invite: {
|
||||||
|
invites: {},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
function dispatch(action: Action) {
|
function dispatch(action: Action) {
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,21 @@
|
||||||
|
import { IAppState } from "./app";
|
||||||
import { IAuthState } from "./auth";
|
import { IAuthState } from "./auth";
|
||||||
import { IUserState } from "./user";
|
import { IUserState } from "./user";
|
||||||
import { ICommunityState } from "./community";
|
import { ICommunityState } from "./community";
|
||||||
import { IChannelState } from "./channel";
|
import { IChannelState } from "./channel";
|
||||||
import { IRoleState } from "./role";
|
import { IRoleState } from "./role";
|
||||||
|
import { ISessionState } from "./session";
|
||||||
|
import { IInviteState } from "./invite";
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
|
app: IAppState;
|
||||||
auth: IAuthState;
|
auth: IAuthState;
|
||||||
user: IUserState;
|
user: IUserState;
|
||||||
community: ICommunityState;
|
community: ICommunityState;
|
||||||
channel: IChannelState;
|
channel: IChannelState;
|
||||||
role: IRoleState;
|
role: IRoleState;
|
||||||
|
session: ISessionState;
|
||||||
|
invite: IInviteState;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { type IState };
|
export { type IState };
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { IFetchCommunityMember } from "../../api/community";
|
||||||
import {
|
import {
|
||||||
IFetchLoggedUserResponse,
|
IFetchLoggedUserResponse,
|
||||||
IFetchUserResponse,
|
IFetchUserResponse,
|
||||||
|
IFetchUserSessionsResponse,
|
||||||
IFetchUserCommunitiesResponse,
|
IFetchUserCommunitiesResponse,
|
||||||
} from "../../api/user";
|
} from "../../api/user";
|
||||||
|
|
||||||
|
|
@ -11,6 +12,8 @@ enum UserActionTypes {
|
||||||
FETCH_LOGGED_USER_ID_FINISH = "FETCH_LOGGED_USER_ID_FINISH",
|
FETCH_LOGGED_USER_ID_FINISH = "FETCH_LOGGED_USER_ID_FINISH",
|
||||||
FETCH_USER_START = "FETCH_USER_START",
|
FETCH_USER_START = "FETCH_USER_START",
|
||||||
FETCH_USER_FINISH = "FETCH_USER_FINISH",
|
FETCH_USER_FINISH = "FETCH_USER_FINISH",
|
||||||
|
FETCH_USER_SESSIONS_START = "FETCH_USER_SESSIONS_START",
|
||||||
|
FETCH_USER_SESSIONS_FINISH = "FETCH_USER_SESSIONS_FINISH",
|
||||||
FETCH_USER_COMMUNITIES_START = "FETCH_USER_COMMUNITIES_START",
|
FETCH_USER_COMMUNITIES_START = "FETCH_USER_COMMUNITIES_START",
|
||||||
FETCH_USER_COMMUNITIES_FINISH = "FETCH_USER_COMMUNITIES_FINISH",
|
FETCH_USER_COMMUNITIES_FINISH = "FETCH_USER_COMMUNITIES_FINISH",
|
||||||
}
|
}
|
||||||
|
|
@ -27,6 +30,11 @@ type UserAction =
|
||||||
}
|
}
|
||||||
| { type: UserActionTypes.FETCH_USER_START; payload: string }
|
| { type: UserActionTypes.FETCH_USER_START; payload: string }
|
||||||
| { type: UserActionTypes.FETCH_USER_FINISH; payload: IFetchUserResponse }
|
| { type: UserActionTypes.FETCH_USER_FINISH; payload: IFetchUserResponse }
|
||||||
|
| { type: UserActionTypes.FETCH_USER_SESSIONS_START; payload: string }
|
||||||
|
| {
|
||||||
|
type: UserActionTypes.FETCH_USER_SESSIONS_FINISH;
|
||||||
|
payload: IFetchUserSessionsResponse;
|
||||||
|
}
|
||||||
| { type: UserActionTypes.FETCH_USER_COMMUNITIES_START; payload: string }
|
| { type: UserActionTypes.FETCH_USER_COMMUNITIES_START; payload: string }
|
||||||
| {
|
| {
|
||||||
type: UserActionTypes.FETCH_USER_COMMUNITIES_FINISH;
|
type: UserActionTypes.FETCH_USER_COMMUNITIES_FINISH;
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ interface IUser {
|
||||||
admin?: boolean;
|
admin?: boolean;
|
||||||
registerDate?: number;
|
registerDate?: number;
|
||||||
lastLogin?: number;
|
lastLogin?: number;
|
||||||
|
sessions?: string[];
|
||||||
communities?: string[];
|
communities?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import {
|
import {
|
||||||
fetchLoggedUser,
|
fetchLoggedUser,
|
||||||
fetchUser,
|
fetchUser,
|
||||||
|
fetchUserSessions,
|
||||||
fetchUserCommunities,
|
fetchUserCommunities,
|
||||||
} from "../../services/user";
|
} from "../../services/user";
|
||||||
import { setState } from "../state";
|
import { setState } from "../state";
|
||||||
|
|
@ -24,6 +25,14 @@ function userReducer(state: IUserState, action: UserAction) {
|
||||||
case UserActionTypes.FETCH_USER_FINISH:
|
case UserActionTypes.FETCH_USER_FINISH:
|
||||||
setState("user", "users", action.payload.id, action.payload);
|
setState("user", "users", action.payload.id, action.payload);
|
||||||
break;
|
break;
|
||||||
|
case UserActionTypes.FETCH_USER_SESSIONS_START:
|
||||||
|
fetchUserSessions(action.payload);
|
||||||
|
break;
|
||||||
|
case UserActionTypes.FETCH_USER_SESSIONS_FINISH:
|
||||||
|
setState("user", "users", action.payload.id, {
|
||||||
|
sessions: action.payload.sessions.map((session) => session.id),
|
||||||
|
});
|
||||||
|
break;
|
||||||
case UserActionTypes.FETCH_USER_COMMUNITIES_START:
|
case UserActionTypes.FETCH_USER_COMMUNITIES_START:
|
||||||
fetchUserCommunities(action.payload);
|
fetchUserCommunities(action.payload);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { createEffect, createMemo, type Component } from "solid-js";
|
import { createEffect, createMemo, type Component } from "solid-js";
|
||||||
import { CommunityView } from "../CommunityView";
|
|
||||||
import { dispatch, state } from "../../store/state";
|
import { dispatch, state } from "../../store/state";
|
||||||
import { CommunityActionTypes, ICommunity } from "../../store/community";
|
import { CommunityActionTypes, ICommunity } from "../../store/community";
|
||||||
import { ChannelActionTypes } from "../../store/channel";
|
import { ChannelActionTypes } from "../../store/channel";
|
||||||
|
|
@ -23,7 +22,7 @@ const ChannelView: Component = () => {
|
||||||
|
|
||||||
const communityInfo = createMemo<ICommunity | undefined>(() => {
|
const communityInfo = createMemo<ICommunity | undefined>(() => {
|
||||||
const activeCommunityId = state.community.active;
|
const activeCommunityId = state.community.active;
|
||||||
return state.community.communities[activeCommunityId];
|
return state.community.communities[activeCommunityId ?? 0];
|
||||||
});
|
});
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
|
|
@ -63,9 +62,7 @@ const ChannelView: Component = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="flex flex-row bg-stone-900 w-80 shadow-panel z-20">
|
<div class="bg-stone-900 w-80 shadow-panel z-20 h-full relative">
|
||||||
<CommunityView />
|
|
||||||
<div class="h-full w-full relative">
|
|
||||||
<CommunityBar
|
<CommunityBar
|
||||||
id={communityInfo()?.id}
|
id={communityInfo()?.id}
|
||||||
name={communityInfo()?.name}
|
name={communityInfo()?.name}
|
||||||
|
|
@ -78,7 +75,6 @@ const ChannelView: Component = () => {
|
||||||
{channelIds().map(mapChannel)}
|
{channelIds().map(mapChannel)}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,7 @@ const ChatView: Component = () => {
|
||||||
|
|
||||||
const channelInfo = createMemo<IChannel | undefined>(() => {
|
const channelInfo = createMemo<IChannel | undefined>(() => {
|
||||||
const activeChannelId = state.channel.active;
|
const activeChannelId = state.channel.active;
|
||||||
return state.channel.channels[activeChannelId];
|
return state.channel.channels[activeChannelId ?? 0];
|
||||||
});
|
});
|
||||||
|
|
||||||
let scrollRef: HTMLUListElement | undefined;
|
let scrollRef: HTMLUListElement | undefined;
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@ import { createMemo, type Component } from "solid-js";
|
||||||
import { Community } from "../../components/Community";
|
import { Community } from "../../components/Community";
|
||||||
import { dispatch, state } from "../../store/state";
|
import { dispatch, state } from "../../store/state";
|
||||||
import { CommunityActionTypes } from "../../store/community";
|
import { CommunityActionTypes } from "../../store/community";
|
||||||
|
import { SidebarItem } from "../../components/SidebarItem";
|
||||||
|
import { AppActionTypes } from "../../store/app";
|
||||||
|
import { HomeIcon, PlusIcon, SettingsIcon } from "../../components/icons";
|
||||||
|
|
||||||
const CommunityView: Component = () => {
|
const CommunityView: Component = () => {
|
||||||
const communityIds = createMemo(() => {
|
const communityIds = createMemo(() => {
|
||||||
|
|
@ -18,7 +21,25 @@ const CommunityView: Component = () => {
|
||||||
return loggedUser.communities ?? [];
|
return loggedUser.communities ?? [];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const onHomeClick = () => {
|
||||||
|
dispatch({
|
||||||
|
type: CommunityActionTypes.SET_ACTIVE_COMMUNITY,
|
||||||
|
payload: undefined,
|
||||||
|
});
|
||||||
|
dispatch({
|
||||||
|
type: AppActionTypes.SET_HOME_OPEN,
|
||||||
|
payload: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const onCommunityClick = (id: string) => {
|
const onCommunityClick = (id: string) => {
|
||||||
|
if (state.app.homeOpen) {
|
||||||
|
dispatch({
|
||||||
|
type: AppActionTypes.SET_HOME_OPEN,
|
||||||
|
payload: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: CommunityActionTypes.FETCH_COMMUNITY_START,
|
type: CommunityActionTypes.FETCH_COMMUNITY_START,
|
||||||
payload: id,
|
payload: id,
|
||||||
|
|
@ -29,6 +50,20 @@ const CommunityView: Component = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onNewClick = () => {
|
||||||
|
dispatch({
|
||||||
|
type: AppActionTypes.SET_ADD_COMMUNITY_OPEN,
|
||||||
|
payload: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSettingsClick = () => {
|
||||||
|
dispatch({
|
||||||
|
type: AppActionTypes.SET_SETTINGS_OPEN,
|
||||||
|
payload: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const mapCommunity = (communityId: string) => {
|
const mapCommunity = (communityId: string) => {
|
||||||
const community = state.community.communities[communityId];
|
const community = state.community.communities[communityId];
|
||||||
if (!community) {
|
if (!community) {
|
||||||
|
|
@ -49,8 +84,22 @@ const CommunityView: Component = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="bg-stone-950 w-18 h-full shadow-panel z-30 flex flex-col p-2 gap-2">
|
<div class="flex flex-col bg-stone-950 w-16 h-full shadow-panel z-30 p-2 gap-2">
|
||||||
|
<SidebarItem
|
||||||
|
icon={HomeIcon}
|
||||||
|
active={state.app.homeOpen}
|
||||||
|
onClick={onHomeClick}
|
||||||
|
/>
|
||||||
|
<div class="divider my-0"></div>
|
||||||
{communityIds().map(mapCommunity)}
|
{communityIds().map(mapCommunity)}
|
||||||
|
<div class="divider my-0"></div>
|
||||||
|
<SidebarItem icon={PlusIcon} active={false} onClick={onNewClick} />
|
||||||
|
<div class="flex-1"></div>
|
||||||
|
<SidebarItem
|
||||||
|
icon={SettingsIcon}
|
||||||
|
active={false}
|
||||||
|
onClick={onSettingsClick}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
42
src/views/HomeView/HomeView.tsx
Normal file
42
src/views/HomeView/HomeView.tsx
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
import { type Component } from "solid-js";
|
||||||
|
import { PlusIcon, SettingsIcon } from "../../components/icons";
|
||||||
|
import { HomeCard } from "../../components/HomeCard";
|
||||||
|
import { dispatch } from "../../store/state";
|
||||||
|
import { AppActionTypes } from "../../store/app";
|
||||||
|
|
||||||
|
const HomeView: Component = () => {
|
||||||
|
const onNewClick = () => {
|
||||||
|
dispatch({
|
||||||
|
type: AppActionTypes.SET_ADD_COMMUNITY_OPEN,
|
||||||
|
payload: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSettingsClick = () => {
|
||||||
|
dispatch({
|
||||||
|
type: AppActionTypes.SET_SETTINGS_OPEN,
|
||||||
|
payload: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class="flex-1 flex flex-row bg-stone-900 shadow-panel z-0">
|
||||||
|
<div class="flex-1 flex flex-row items-center justify-center gap-8">
|
||||||
|
<HomeCard
|
||||||
|
title="Find a Community"
|
||||||
|
description="Find or create a new Community to chat"
|
||||||
|
icon={PlusIcon}
|
||||||
|
onClick={onNewClick}
|
||||||
|
/>
|
||||||
|
<HomeCard
|
||||||
|
title="Open Settings"
|
||||||
|
description="Adjust your settings"
|
||||||
|
icon={SettingsIcon}
|
||||||
|
onClick={onSettingsClick}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { HomeView };
|
||||||
1
src/views/HomeView/index.ts
Normal file
1
src/views/HomeView/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
export * from "./HomeView";
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
import { createEffect, createMemo, onMount, type Component } from "solid-js";
|
import { createEffect, onMount, type Component } from "solid-js";
|
||||||
import { ChannelView } from "../ChannelView";
|
import { ChannelView } from "../ChannelView";
|
||||||
import { ChatView } from "../ChatView";
|
import { ChatView } from "../ChatView";
|
||||||
import { MemberView } from "../MemberView";
|
import { MemberView } from "../MemberView";
|
||||||
import { dispatch, state } from "../../store/state";
|
import { dispatch, state } from "../../store/state";
|
||||||
import { UserActionTypes } from "../../store/user";
|
import { UserActionTypes } from "../../store/user";
|
||||||
import { AuthActionTypes } from "../../store/auth";
|
import { AuthActionTypes } from "../../store/auth";
|
||||||
|
import { HomeView } from "../HomeView";
|
||||||
|
import { CommunityView } from "../CommunityView";
|
||||||
|
import { ModalView } from "../ModalView";
|
||||||
|
|
||||||
const MainView: Component = () => {
|
const MainView: Component = () => {
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
|
|
@ -30,9 +33,19 @@ const MainView: Component = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="flex flex-row h-screen">
|
<div class="flex flex-row h-screen">
|
||||||
|
<ModalView />
|
||||||
|
<CommunityView />
|
||||||
|
{state.app.homeOpen ? (
|
||||||
|
<>
|
||||||
|
<HomeView />
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
<ChannelView />
|
<ChannelView />
|
||||||
<ChatView />
|
<ChatView />
|
||||||
<MemberView />
|
<MemberView />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
55
src/views/ModalView/ModalView.tsx
Normal file
55
src/views/ModalView/ModalView.tsx
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
import { createEffect, type Component } from "solid-js";
|
||||||
|
import { dispatch, state } from "../../store/state";
|
||||||
|
import SettingsModal from "../../components/SettingsModal/SettingsModal";
|
||||||
|
import CommunityModal from "../../components/CommunityModal/CommunityModal";
|
||||||
|
import { AppActionTypes } from "../../store/app";
|
||||||
|
|
||||||
|
const ModalView: Component = () => {
|
||||||
|
let settingsModal: HTMLDialogElement;
|
||||||
|
let communityModal: HTMLDialogElement;
|
||||||
|
|
||||||
|
createEffect(() => {
|
||||||
|
if (state.app.dialogsOpen.settingsOpen) {
|
||||||
|
settingsModal.showModal();
|
||||||
|
} else {
|
||||||
|
settingsModal.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
createEffect(() => {
|
||||||
|
if (state.app.dialogsOpen.addCommunityOpen) {
|
||||||
|
communityModal.showModal();
|
||||||
|
} else {
|
||||||
|
communityModal.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const onCloseSettings = () => {
|
||||||
|
dispatch({
|
||||||
|
type: AppActionTypes.SET_SETTINGS_OPEN,
|
||||||
|
payload: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onCloseCommunity = () => {
|
||||||
|
dispatch({
|
||||||
|
type: AppActionTypes.SET_ADD_COMMUNITY_OPEN,
|
||||||
|
payload: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<SettingsModal
|
||||||
|
dialogRef={(element) => (settingsModal = element)}
|
||||||
|
onClose={onCloseSettings}
|
||||||
|
/>
|
||||||
|
<CommunityModal
|
||||||
|
dialogRef={(element) => (communityModal = element)}
|
||||||
|
onClose={onCloseCommunity}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { ModalView };
|
||||||
1
src/views/ModalView/index.ts
Normal file
1
src/views/ModalView/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
export * from "./ModalView";
|
||||||
Loading…
Add table
Add a link
Reference in a new issue