Add basic services; Base layout
This commit is contained in:
parent
be6467cd2c
commit
ef526cd2db
30 changed files with 291 additions and 34 deletions
|
|
@ -1,13 +1,15 @@
|
|||
import { Route, Router } from "@solidjs/router";
|
||||
import type { Component } from "solid-js";
|
||||
import MainView from "./views/MainView/MainView";
|
||||
import SettingsView from "./views/SettingsView/SettingsView";
|
||||
import { MainView } from "./views/MainView";
|
||||
import { SettingsView } from "./views/SettingsView";
|
||||
import { LoginView } from "./views/LoginView";
|
||||
|
||||
const App: Component = () => {
|
||||
return (
|
||||
<Router>
|
||||
<Route path="/" component={MainView} />
|
||||
<Route path="/settings" component={SettingsView} />
|
||||
<Route path="/login" component={LoginView} />
|
||||
</Router>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
18
src/api/auth/auth.ts
Normal file
18
src/api/auth/auth.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import { callApi, HTTP } from "../tools";
|
||||
import {
|
||||
IFetchLoginRequest,
|
||||
IFetchLoginResponse,
|
||||
IFetchRefreshResponse,
|
||||
} from "./types";
|
||||
|
||||
const fetchLoginApi = async (
|
||||
request: IFetchLoginRequest,
|
||||
): Promise<IFetchLoginResponse> => {
|
||||
return await callApi(HTTP.POST, `auth/login`, request);
|
||||
};
|
||||
|
||||
const fetchRefreshApi = async (): Promise<IFetchRefreshResponse> => {
|
||||
return await callApi(HTTP.GET_REFRESH, `auth/refresh`);
|
||||
};
|
||||
|
||||
export { fetchLoginApi, fetchRefreshApi };
|
||||
2
src/api/auth/index.ts
Normal file
2
src/api/auth/index.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
export * from "./auth";
|
||||
export * from "./types";
|
||||
21
src/api/auth/types.ts
Normal file
21
src/api/auth/types.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
interface IFetchLoginRequest {
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
interface IFetchLoginResponse {
|
||||
id: string;
|
||||
ownerId: string;
|
||||
}
|
||||
|
||||
interface IFetchRefreshResponse {
|
||||
id: string;
|
||||
ownerId: string;
|
||||
token: string;
|
||||
}
|
||||
|
||||
export {
|
||||
type IFetchLoginRequest,
|
||||
type IFetchLoginResponse,
|
||||
type IFetchRefreshResponse,
|
||||
};
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"schema": "http",
|
||||
"url": "localhost",
|
||||
"port": 3012
|
||||
"port": 3012,
|
||||
"path": "api/v1"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,31 +1,75 @@
|
|||
import { state } from "../store/state";
|
||||
import config from "./config.json";
|
||||
|
||||
enum HTTP {
|
||||
GET_REFRESH,
|
||||
GET,
|
||||
POST,
|
||||
PATCH,
|
||||
DELETE,
|
||||
}
|
||||
|
||||
async function callApi(type: HTTP, path: string, body?: any) {
|
||||
async function callApi(type: HTTP, path: string, body?: object) {
|
||||
let response: Response;
|
||||
switch (type) {
|
||||
case HTTP.GET:
|
||||
case HTTP.GET_REFRESH:
|
||||
response = await fetch(
|
||||
`${config.schema}://${config.url}:${config.port}/${path}`,
|
||||
`${config.schema}://${config.url}:${config.port}/${config.path}/${path}`,
|
||||
{
|
||||
method: "GET",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
break;
|
||||
case HTTP.GET:
|
||||
response = await fetch(
|
||||
`${config.schema}://${config.url}:${config.port}/${config.path}/${path}`,
|
||||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${state.auth.session?.token}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
break;
|
||||
case HTTP.POST:
|
||||
response = await fetch(
|
||||
`${config.schema}://${config.url}:${config.port}/${path}`,
|
||||
`${config.schema}://${config.url}:${config.port}/${config.path}/${path}`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${state.auth.session?.token}`,
|
||||
},
|
||||
body: JSON.stringify(body ?? {}),
|
||||
},
|
||||
);
|
||||
break;
|
||||
case HTTP.PATCH:
|
||||
response = await fetch(
|
||||
`${config.schema}://${config.url}:${config.port}/${config.path}/${path}`,
|
||||
{
|
||||
method: "PATCH",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${state.auth.session?.token}`,
|
||||
},
|
||||
body: JSON.stringify(body ?? {}),
|
||||
},
|
||||
);
|
||||
break;
|
||||
case HTTP.DELETE:
|
||||
response = await fetch(
|
||||
`${config.schema}://${config.url}:${config.port}/${config.path}/${path}`,
|
||||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${state.auth.session?.token}`,
|
||||
},
|
||||
body: JSON.stringify(body ?? {}),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ const Channel: Component = () => {
|
|||
return <div></div>;
|
||||
};
|
||||
|
||||
export default Channel;
|
||||
export { Channel };
|
||||
|
|
|
|||
|
|
@ -8,4 +8,4 @@ const ChannelBar: Component = () => {
|
|||
);
|
||||
};
|
||||
|
||||
export default ChannelBar;
|
||||
export { ChannelBar };
|
||||
|
|
|
|||
|
|
@ -14,4 +14,4 @@ const Community: Component<ICommunityProps> = (props: ICommunityProps) => {
|
|||
);
|
||||
};
|
||||
|
||||
export default Community;
|
||||
export { Community };
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ const Member: Component = () => {
|
|||
return <div></div>;
|
||||
};
|
||||
|
||||
export default Member;
|
||||
export { Member };
|
||||
|
|
|
|||
|
|
@ -20,4 +20,4 @@ const Message: Component<IMessageProps> = (props: IMessageProps) => {
|
|||
);
|
||||
};
|
||||
|
||||
export default Message;
|
||||
export { Message };
|
||||
|
|
|
|||
|
|
@ -1,13 +1,36 @@
|
|||
import type { Component } from "solid-js";
|
||||
import { dispatch } from "../../store/state";
|
||||
import { UserActionTypes } from "../../store/user";
|
||||
import { AuthActionTypes } from "../../store/auth";
|
||||
|
||||
const MessageBar: Component = () => {
|
||||
const onRefresh = () => {
|
||||
dispatch({
|
||||
type: AuthActionTypes.FETCH_REFRESH_START,
|
||||
});
|
||||
};
|
||||
const onSend = () => {
|
||||
dispatch({
|
||||
type: UserActionTypes.FETCH_LOGGED_USER_ID_START,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div class="absolute w-full bottom-0 p-4 z-10">
|
||||
<div class="bg-stone-800/25 backdrop-blur-lg h-16 shadow-bar p-2 flex flex-row gap-2 rounded-full">
|
||||
<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..." />
|
||||
</label>
|
||||
<button class="bg-black/50 backdrop-blur-lg btn btn-neutral h-full rounded-full">
|
||||
<button
|
||||
class="bg-black/50 backdrop-blur-lg btn btn-neutral h-full rounded-full"
|
||||
onClick={onRefresh}
|
||||
>
|
||||
Refresh test
|
||||
</button>
|
||||
<button
|
||||
class="bg-black/50 backdrop-blur-lg btn btn-neutral h-full rounded-full"
|
||||
onClick={onSend}
|
||||
>
|
||||
Send
|
||||
</button>
|
||||
</div>
|
||||
|
|
@ -15,4 +38,4 @@ const MessageBar: Component = () => {
|
|||
);
|
||||
};
|
||||
|
||||
export default MessageBar;
|
||||
export { MessageBar };
|
||||
|
|
|
|||
26
src/services/auth/auth.ts
Normal file
26
src/services/auth/auth.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { fetchLoginApi, fetchRefreshApi } from "../../api/auth";
|
||||
import { AuthActionTypes } from "../../store/auth";
|
||||
import { dispatch } from "../../store/state";
|
||||
|
||||
const fetchLogin = async (username: string, password: string) => {
|
||||
const data = await fetchLoginApi({
|
||||
username: username,
|
||||
password: password,
|
||||
});
|
||||
|
||||
dispatch({
|
||||
type: AuthActionTypes.FETCH_LOGIN_FINISH,
|
||||
payload: data,
|
||||
});
|
||||
};
|
||||
|
||||
const fetchRefresh = async () => {
|
||||
const data = await fetchRefreshApi();
|
||||
|
||||
dispatch({
|
||||
type: AuthActionTypes.FETCH_REFRESH_FINISH,
|
||||
payload: data,
|
||||
});
|
||||
};
|
||||
|
||||
export { fetchLogin, fetchRefresh };
|
||||
1
src/services/auth/index.ts
Normal file
1
src/services/auth/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export * from "./auth";
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
import { AuthActionTypes, AuthAction } from "./auth";
|
||||
import { UserActionTypes, UserAction } from "./user";
|
||||
import { CommunityActionTypes, CommunityAction } from "./community";
|
||||
|
||||
type ActionTypes = UserActionTypes | CommunityActionTypes;
|
||||
type ActionTypes = AuthActionTypes | UserActionTypes | CommunityActionTypes;
|
||||
|
||||
type Action = UserAction | CommunityAction;
|
||||
type Action = AuthAction | UserAction | CommunityAction;
|
||||
|
||||
export { type Action, type ActionTypes };
|
||||
|
|
|
|||
26
src/store/auth/actions.ts
Normal file
26
src/store/auth/actions.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import {
|
||||
IFetchLoginRequest,
|
||||
IFetchLoginResponse,
|
||||
IFetchRefreshResponse,
|
||||
} from "../../api/auth";
|
||||
|
||||
enum AuthActionTypes {
|
||||
FETCH_LOGIN_START = "FETCH_LOGIN_START",
|
||||
FETCH_LOGIN_FINISH = "FETCH_LOGIN_FINISH",
|
||||
FETCH_REFRESH_START = "FETCH_REFRESH_START",
|
||||
FETCH_REFRESH_FINISH = "FETCH_REFRESH_FINISH",
|
||||
}
|
||||
|
||||
type AuthAction =
|
||||
| { type: AuthActionTypes.FETCH_LOGIN_START; payload: IFetchLoginRequest }
|
||||
| {
|
||||
type: AuthActionTypes.FETCH_LOGIN_FINISH;
|
||||
payload: IFetchLoginResponse;
|
||||
}
|
||||
| { type: AuthActionTypes.FETCH_REFRESH_START }
|
||||
| {
|
||||
type: AuthActionTypes.FETCH_REFRESH_FINISH;
|
||||
payload: IFetchRefreshResponse;
|
||||
};
|
||||
|
||||
export { AuthActionTypes, type AuthAction };
|
||||
28
src/store/auth/auth.ts
Normal file
28
src/store/auth/auth.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import { fetchLogin, fetchRefresh } from "../../services/auth";
|
||||
import { AuthActionTypes, AuthAction } from "./actions";
|
||||
import { IAuthState } from "./types";
|
||||
|
||||
function authReducer(state: IAuthState, action: AuthAction): IAuthState {
|
||||
switch (action.type) {
|
||||
case AuthActionTypes.FETCH_LOGIN_START:
|
||||
fetchLogin(action.payload.username, action.payload.password);
|
||||
return state;
|
||||
case AuthActionTypes.FETCH_LOGIN_FINISH:
|
||||
return {
|
||||
...state,
|
||||
session: action.payload,
|
||||
};
|
||||
case AuthActionTypes.FETCH_REFRESH_START:
|
||||
fetchRefresh();
|
||||
return state;
|
||||
case AuthActionTypes.FETCH_REFRESH_FINISH:
|
||||
return {
|
||||
...state,
|
||||
session: action.payload,
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
export { authReducer };
|
||||
3
src/store/auth/index.ts
Normal file
3
src/store/auth/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export * from "./auth";
|
||||
export * from "./actions";
|
||||
export * from "./types";
|
||||
11
src/store/auth/types.ts
Normal file
11
src/store/auth/types.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
interface IAuthState {
|
||||
session?: ISession;
|
||||
}
|
||||
|
||||
interface ISession {
|
||||
id?: string;
|
||||
ownerId?: string;
|
||||
token?: string;
|
||||
}
|
||||
|
||||
export { type IAuthState, type ISession };
|
||||
|
|
@ -1,10 +1,12 @@
|
|||
import { IState } from "./types";
|
||||
import { Action } from "./actions";
|
||||
import { AuthAction, authReducer } from "./auth";
|
||||
import { UserAction, userReducer } from "./user";
|
||||
import { CommunityAction, communityReducer } from "./community";
|
||||
|
||||
function reducer(state: IState, action: Action): IState {
|
||||
return {
|
||||
auth: authReducer(state.auth, action as AuthAction),
|
||||
user: userReducer(state.user, action as UserAction),
|
||||
community: communityReducer(state.community, action as CommunityAction),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ import { Action } from "./actions";
|
|||
import { reducer } from "./reducers";
|
||||
|
||||
const [state, setState] = createStore<IState>({
|
||||
auth: {
|
||||
session: undefined,
|
||||
},
|
||||
user: {
|
||||
loggedUserId: undefined,
|
||||
users: {},
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import { IAuthState } from "./auth";
|
||||
import { IUserState } from "./user";
|
||||
import { ICommunityState } from "./community";
|
||||
|
||||
interface IState {
|
||||
auth: IAuthState;
|
||||
user: IUserState;
|
||||
community: ICommunityState;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { Component } from "solid-js";
|
||||
import CommunityView from "../CommunityView/CommunityView";
|
||||
import { CommunityView } from "../CommunityView";
|
||||
|
||||
const ChannelView: Component = () => {
|
||||
return (
|
||||
|
|
@ -10,4 +10,4 @@ const ChannelView: Component = () => {
|
|||
);
|
||||
};
|
||||
|
||||
export default ChannelView;
|
||||
export { ChannelView };
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { onMount, type Component } from "solid-js";
|
||||
import ChannelBar from "../../components/ChannelBar/ChannelBar";
|
||||
import MessageBar from "../../components/MessageBar/MessageBar";
|
||||
import Message from "../../components/Message/Message";
|
||||
import { ChannelBar } from "../../components/ChannelBar";
|
||||
import { MessageBar } from "../../components/MessageBar";
|
||||
import { Message } from "../../components/Message";
|
||||
|
||||
const ChatView: Component = () => {
|
||||
const testMessages = [
|
||||
|
|
@ -211,4 +211,4 @@ const ChatView: Component = () => {
|
|||
);
|
||||
};
|
||||
|
||||
export default ChatView;
|
||||
export { ChatView };
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { Component } from "solid-js";
|
||||
import Community from "../../components/Community/Community";
|
||||
import { Community } from "../../components/Community";
|
||||
|
||||
const CommunityView: Component = () => {
|
||||
const communitiesTest = [
|
||||
|
|
@ -35,4 +35,4 @@ const CommunityView: Component = () => {
|
|||
);
|
||||
};
|
||||
|
||||
export default CommunityView;
|
||||
export { CommunityView };
|
||||
|
|
|
|||
|
|
@ -1,7 +1,50 @@
|
|||
import type { Component } from "solid-js";
|
||||
import { createSignal, type Component } from "solid-js";
|
||||
import { dispatch } from "../../store/state";
|
||||
import { AuthActionTypes } from "../../store/auth";
|
||||
|
||||
const LoginView: Component = () => {
|
||||
return <div></div>;
|
||||
const [getUsername, setUsername] = createSignal("");
|
||||
const [getPassword, setPassword] = createSignal("");
|
||||
|
||||
const onLogin = () => {
|
||||
dispatch({
|
||||
type: AuthActionTypes.FETCH_LOGIN_START,
|
||||
payload: {
|
||||
username: getUsername(),
|
||||
password: getPassword(),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export default LoginView;
|
||||
return (
|
||||
<div>
|
||||
<fieldset class="fieldset bg-base-200 border-base-300 rounded-box w-xs border p-4 mx-auto mt-32 lg:mt-64">
|
||||
<legend class="fieldset-legend">Login</legend>
|
||||
|
||||
<label class="label">Username</label>
|
||||
<input
|
||||
type="email"
|
||||
class="input"
|
||||
placeholder="Username"
|
||||
value={getUsername()}
|
||||
onInput={(e) => setUsername(e.target.value)}
|
||||
/>
|
||||
|
||||
<label class="label">Password</label>
|
||||
<input
|
||||
type="password"
|
||||
class="input"
|
||||
placeholder="Password"
|
||||
value={getPassword()}
|
||||
onInput={(e) => setPassword(e.target.value)}
|
||||
/>
|
||||
|
||||
<button class="btn btn-neutral mt-4" onClick={onLogin}>
|
||||
Login
|
||||
</button>
|
||||
</fieldset>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export { LoginView };
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { Component } from "solid-js";
|
||||
import ChannelView from "../ChannelView/ChannelView";
|
||||
import ChatView from "../ChatView/ChatView";
|
||||
import MemberView from "../MemberView/MemberView";
|
||||
import { ChannelView } from "../ChannelView";
|
||||
import { ChatView } from "../ChatView";
|
||||
import { MemberView } from "../MemberView";
|
||||
|
||||
const MainView: Component = () => {
|
||||
return (
|
||||
|
|
@ -13,4 +13,4 @@ const MainView: Component = () => {
|
|||
);
|
||||
};
|
||||
|
||||
export default MainView;
|
||||
export { MainView };
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ const MemberView: Component = () => {
|
|||
return <div class="bg-stone-900 w-64 shadow-panel z-20"></div>;
|
||||
};
|
||||
|
||||
export default MemberView;
|
||||
export { MemberView };
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ const RegisterView: Component = () => {
|
|||
return <div></div>;
|
||||
};
|
||||
|
||||
export default RegisterView;
|
||||
export { RegisterView };
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ const SettingsView: Component = () => {
|
|||
return <div></div>;
|
||||
};
|
||||
|
||||
export default SettingsView;
|
||||
export { SettingsView };
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue