diff --git a/src/lib/data/heatmap.ts b/src/lib/data/heatmap.ts
index 78796165..94c46815 100644
--- a/src/lib/data/heatmap.ts
+++ b/src/lib/data/heatmap.ts
@@ -1,383 +1,182 @@
-const WEEK_DAYS = ["MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"];
+const WEEK_DAYS = ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'];
-const HOURE_DAYS = [
- "12",
- "1",
- "2",
- "3",
- "4",
- "5",
- "6",
- "7",
- "8",
- "9",
- "10",
- "11",
- "1",
- "2",
- "3",
- "4",
- "5",
- "6",
- "7",
- "8",
- "9",
- "10",
- "11",
-];
+const HOURE_DAYS = Array.from({ length: 24 }, (_, i) => i).map(String);
-const chartData = [
- [0, 1, 10],
- [0, 2, 20],
- [0, 3, 40],
- [0, 4, 50],
- [0, 5, 30],
- [0, 6, 0],
- [0, 7, 70],
- [0, 8, 0],
- [0, 9, 90],
- [0, 10, 0],
- [0, 11, 2],
- [0, 12, 4],
- [0, 13, 1],
- [0, 14, 1],
- [0, 15, 3],
- [0, 16, 4],
- [0, 17, 6],
- [0, 18, 4],
- [0, 19, 4],
- [0, 20, 3],
- [0, 21, 3],
- [0, 22, 2],
- [0, 23, 5],
- [0, 24, 5],
- [1, 1, 10],
- [1, 2, 20],
- [1, 3, 25],
- [1, 4, 50],
- [1, 5, 30],
- [1, 6, 0],
- [1, 7, 30],
- [1, 8, 0],
- [1, 9, 90],
- [1, 10, 0],
- [1, 11, 2],
- [1, 12, 4],
- [1, 13, 1],
- [1, 14, 1],
- [1, 15, 3],
- [1, 16, 4],
- [1, 17, 6],
- [1, 18, 4],
- [1, 19, 4],
- [1, 20, 3],
- [1, 21, 3],
- [1, 22, 2],
- [1, 23, 5],
- [1, 24, 5],
- [2, 1, 10],
- [2, 2, 20],
- [2, 3, 40],
- [2, 4, 50],
- [2, 5, 30],
- [2, 6, 0],
- [2, 7, 70],
- [2, 8, 0],
- [2, 9, 90],
- [2, 10, 0],
- [2, 11, 2],
- [2, 12, 4],
- [2, 13, 1],
- [2, 14, 1],
- [2, 15, 3],
- [2, 16, 4],
- [2, 17, 6],
- [2, 18, 4],
- [2, 19, 4],
- [2, 20, 3],
- [2, 21, 3],
- [2, 22, 2],
- [2, 23, 5],
- [2, 24, 5],
- [3, 1, 10],
- [3, 2, 20],
- [3, 3, 25],
- [3, 4, 50],
- [3, 5, 30],
- [3, 6, 0],
- [3, 7, 30],
- [3, 8, 0],
- [3, 9, 90],
- [3, 10, 0],
- [3, 11, 2],
- [3, 12, 4],
- [3, 13, 1],
- [3, 14, 1],
- [3, 15, 3],
- [3, 16, 4],
- [3, 17, 6],
- [3, 18, 4],
- [3, 19, 4],
- [3, 20, 3],
- [3, 21, 3],
- [3, 22, 2],
- [3, 23, 5],
- [3, 24, 5],
- [4, 1, 10],
- [4, 2, 20],
- [4, 3, 40],
- [4, 4, 50],
- [4, 5, 30],
- [4, 6, 0],
- [4, 7, 70],
- [4, 8, 0],
- [4, 9, 90],
- [4, 10, 100],
- [4, 11, 2],
- [4, 12, 4],
- [4, 13, 1],
- [4, 14, 1],
- [4, 15, 3],
- [4, 16, 4],
- [4, 17, 6],
- [4, 18, 4],
- [4, 19, 4],
- [4, 20, 3],
- [4, 21, 3],
- [4, 22, 2],
- [4, 23, 5],
- [4, 24, 5],
- [5, 1, 10],
- [5, 2, 20],
- [5, 3, 25],
- [5, 4, 50],
- [5, 5, 30],
- [5, 6, 0],
- [5, 7, 30],
- [5, 8, 0],
- [5, 9, 90],
- [5, 10, 0],
- [5, 11, 2],
- [5, 12, 4],
- [5, 13, 1],
- [5, 14, 1],
- [5, 15, 3],
- [5, 16, 4],
- [5, 17, 6],
- [5, 18, 4],
- [5, 19, 4],
- [5, 20, 3],
- [5, 21, 3],
- [5, 22, 2],
- [5, 23, 5],
- [5, 24, 5],
- [6, 1, 10],
- [6, 2, 20],
- [6, 3, 40],
- [6, 4, 50],
- [6, 5, 30],
- [6, 6, 0],
- [6, 7, 70],
- [6, 8, 0],
- [6, 9, 90],
- [6, 10, 0],
- [6, 11, 2],
- [6, 12, 4],
- [6, 13, 1],
- [6, 14, 1],
- [6, 15, 3],
- [6, 16, 4],
- [6, 17, 6],
- [6, 18, 4],
- [6, 19, 4],
- [6, 20, 3],
- [6, 21, 3],
- [6, 22, 2],
- [6, 23, 5],
- [6, 24, 5],
-
-].map((item) => [item[1], item[0], item[2] || 0]);
-
-const options = {
- chart: {
- type: "heatmap",
- plotBorderWidth: 0,
+const defaultHeatmapChartOptions = {
+ chart: {
+ type: 'heatmap',
+ plotBorderWidth: 0,
+ },
+ title: {
+ text: null,
+ },
+ legend: {
+ enabled: false,
+ },
+ xAxis: {
+ categories: HOURE_DAYS,
+ tickInterval: 1,
+ labels: {
+ step: 1,
+ style: {
+ fontSize: '14px',
+ fontFamily: 'Inter',
+ },
},
+ opposite: true,
+ gridLineWidth: 0,
+ lineWidth: 0,
+ lineColor: 'rgba(0,0,0,0.75)',
+ tickWidth: 0,
+ tickLength: 0,
+ tickColor: 'rgba(0,0,0,0.75)',
title: {
- text: null
+ text: 'Hour',
+ style: {
+ fontSize: '14px',
+ fontFamily: 'Inter',
+ },
+ align: 'low',
},
- legend: {
- title: {
- text: 'Number of interactions',
- style: {
- fontStyle: "bold",
- },
- },
- align: "right",
- layout: "horizental",
- margin: 0,
- verticalAlign: "top",
- y: 0,
- x: 25,
- symbolHeight: 25,
+ },
+ yAxis: {
+ categories: WEEK_DAYS,
+ lineWidth: 0,
+ gridLineWidth: 0,
+ title: 'Weekdays',
+ reversed: true,
+ labels: {
+ style: {
+ fontSize: '14px',
+ fontFamily: 'Inter',
+ },
},
- xAxis: {
- categories: HOURE_DAYS,
- tickInterval: 1,
- labels: {
- step: 1,
- style: {
- fontSize: "14px",
- fontFamily: "Inter",
- },
+ },
+ tooltip: {
+ enabled: false,
+ },
+ colorAxis: {
+ min: 0,
+ minColor: '#F3F3F3',
+ maxColor: '#45367B',
+ max: 100,
+ stops: [
+ [0, '#F3F3F3'],
+ [10 / 100, '#F3F3F3'],
+ [10 / 100, '#E3E9FF'],
+ [20 / 100, '#E3E9FF'],
+ [20 / 100, '#C5D2FF'],
+ [30 / 100, '#C5D2FF'],
+ [30 / 100, '#9971E7'],
+ [50 / 100, '#9971E7'],
+ [50 / 100, '#673FB5'],
+ [70 / 100, '#673FB5'],
+ [70 / 100, '#35205E'],
+ [1, '#35205E'],
+ ].map(([position, color]) => [position, color] as [number, string]),
+ },
+ series: [
+ {
+ name: 'Revenue',
+ borderWidth: 0.5,
+ borderColor: 'white',
+ states: {
+ hover: {
+ enabled: false,
},
- opposite: true,
- gridLineWidth: 0,
- lineWidth: 0,
- lineColor: "rgba(0,0,0,0.75)",
- tickWidth: 0,
- tickLength: 0,
- tickColor: "rgba(0,0,0,0.75)",
- title: {
- text: "Hour",
- style: {
- fontSize: "14px",
- fontFamily: "Inter",
- },
- align: 'low',
+ },
+ dataLabels: {
+ enabled: true,
+ style: {
+ fontSize: '14px',
+ fontFamily: 'Inter',
+ textOutline: 'none',
+ fontWeight: 'normal',
},
+ },
+ pointPadding: 1.5,
+ data: Array.from({ length: 24 * 7 }, (_, i) => [
+ i % 24,
+ Math.floor(i / 24),
+ 0,
+ ]),
+ colsize: 0.9,
+ rowsize: 0.8,
},
- yAxis: {
- categories: WEEK_DAYS,
- lineWidth: 0,
- gridLineWidth: 0,
- title: "Weekdays",
- reversed: true,
- labels: {
- style: {
- fontSize: "14px",
- fontFamily: "Inter",
- },
+ ],
+ responsive: {
+ rules: [
+ {
+ condition: {
+ maxWidth: 600,
},
- },
- tooltip: {
- enabled: false,
- },
- colorAxis: {
- min: 0,
- minColor: '#F3F3F3',
- maxColor: '#45367B',
- max: 100,
- stops: [
- [0, "#F1F3F3"],
- [0.1, "#EBF2F5"],
- [0.15, "#E0F1F7"],
- [0.2, "#C4D8F8"],
- [0.25, "#AEDFF0"],
- [0.3, "#DAD0FF"],
- [0.5, "#AE9DF0"],
- [0.7, "#8474C0"],
- [1, "#45367B"],
- ],
- },
- series: [
- {
- name: "Revenue",
- borderWidth: 0.5,
- borderColor: "white",
- states: {
- hover: {
- enabled: false
- }
+ chartOptions: {
+ chart: {
+ scrollablePlotArea: {
+ minWidth: 1080,
+ },
+ },
+ legend: {
+ title: {
+ text: 'Number of interactions',
+ style: {
+ fontStyle: 'bold',
+ fontSize: '10px',
+ fontFamily: 'Inter',
+ },
+ },
+ align: 'left',
+ layout: 'horizental',
+ margin: 0,
+ verticalAlign: 'bottom',
+ y: 0,
+ x: 25,
+ symbolHeight: 20,
+ },
+ xAxis: {
+ width: 1000,
+ labels: {
+ step: 1,
+ style: {
+ fontSize: '10px',
+ fontFamily: 'Inter',
+ },
},
- dataLabels: {
+ },
+ yAxis: {
+ labels: {
+ style: {
+ fontSize: '10px',
+ fontFamily: 'Inter',
+ },
+ },
+ },
+ series: [
+ {
+ name: 'Revenue',
+ borderWidth: 0.5,
+ borderColor: 'white',
+ dataLabels: {
enabled: true,
style: {
- fontSize: "14px",
- fontFamily: "Inter",
- textOutline: 'none',
- fontWeight: "normal",
+ fontSize: '10px',
+ fontFamily: 'Inter',
},
+ },
+ pointPadding: 0.8,
+ data: Array.from({ length: 24 * 7 }, (_, i) => [
+ i % 24,
+ Math.floor(i / 24),
+ 0,
+ ]),
+ colsize: 0.9,
+ rowsize: 0.9,
},
- pointPadding: 1.5,
- data: chartData,
- colsize: 0.9,
- rowsize: 0.8,
+ ],
},
+ },
],
- responsive: {
- rules: [{
- condition: {
- maxWidth: 600
- },
- // Make the labels less space demanding on mobile
- chartOptions: {
- chart: {
- scrollablePlotArea: {
- minWidth: 1080,
- },
- },
- legend: {
- title: {
- text: 'Number of interactions',
- style: {
- fontStyle: "bold",
- fontSize: "10px",
- fontFamily: "Inter",
- },
- },
- align: "left",
- layout: "horizental",
- margin: 0,
- verticalAlign: "bottom",
- y: 0,
- x: 25,
- symbolHeight: 20,
- },
- xAxis: {
- width: 1000,
- labels: {
- step: 1,
- style: {
- fontSize: "10px",
- fontFamily: "Inter",
- },
- },
- },
- yAxis: {
- labels: {
- style: {
- fontSize: "10px",
- fontFamily: "Inter",
- },
- },
- },
- series: [
- {
- name: "Revenue",
- borderWidth: 0.5,
- borderColor: "white",
- dataLabels: {
- enabled: true,
- style: {
- fontSize: "10px",
- fontFamily: "Inter",
- },
- },
- pointPadding: .8,
- data: chartData,
- colsize: .9,
- rowsize: .9,
- },
- ],
- }
- }]
- }
+ },
};
-export {
- WEEK_DAYS,
- HOURE_DAYS,
- chartData,
- options
-};
\ No newline at end of file
+export { WEEK_DAYS, HOURE_DAYS, defaultHeatmapChartOptions };
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index cd49631d..39959383 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -3,13 +3,12 @@ import type { AppProps } from 'next/app';
import React, { useEffect } from 'react';
import { hotjar } from 'react-hotjar';
-import '@fortawesome/fontawesome-svg-core/styles.css'; // import Font Awesome CSS
+import '@fortawesome/fontawesome-svg-core/styles.css';
import { config } from '@fortawesome/fontawesome-svg-core';
-config.autoAddCss = false; // Tell Font Awesome to skip adding the CSS automatically since it's being imported above
-
+config.autoAddCss = false;
type ComponentWithPageLayout = AppProps & {
Component: AppProps['Component'] & {
- pageLayout?: React.ComponentType | any; // should fix type
+ pageLayout?: React.ComponentType | any;
};
};
@@ -24,6 +23,7 @@ import AmplitudeAnalytics from '../components/global/AmplitudeAnalytics';
import Script from 'next/script';
import { usePageViewTracking } from '../helpers/amplitudeHelper';
import SafaryClubScript from '../components/global/SafaryClubScript';
+import { TokenProvider } from '../context/TokenContext';
export default function App({ Component, pageProps }: ComponentWithPageLayout) {
usePageViewTracking();
@@ -57,15 +57,17 @@ export default function App({ Component, pageProps }: ComponentWithPageLayout) {
`}
- {Component.pageLayout ? (
-
-
-
-
-
- ) : (
-
- )}
+
+ {Component.pageLayout ? (
+
+
+
+
+
+ ) : (
+
+ )}
+
>
diff --git a/src/pages/_error.tsx b/src/pages/_error.tsx
index 8e687a91..e4536e89 100644
--- a/src/pages/_error.tsx
+++ b/src/pages/_error.tsx
@@ -61,7 +61,7 @@ const ErrorPage: NextComponentType<
label={'Community Insights'}
/>
router.push('/tryNow')}
+ onClick={() => router.push('/centric')}
classes={'text-black'}
variant="outlined"
label={'Connect your community'}
diff --git a/src/pages/callback.tsx b/src/pages/callback.tsx
index 9290b9ed..7ae311f7 100644
--- a/src/pages/callback.tsx
+++ b/src/pages/callback.tsx
@@ -1,208 +1,174 @@
+import React, { useEffect, useState } from 'react';
import { useRouter } from 'next/router';
-import { useEffect, useState } from 'react';
-import { IUser, callbackUrlParams } from '../utils/types';
+import { extractUrlParams } from '../helpers/helper';
+import { StatusCode } from '../utils/enums';
import SimpleBackdrop from '../components/global/LoadingBackdrop';
import { StorageService } from '../services/StorageService';
-import { toast } from 'react-toastify';
-import { BiError } from 'react-icons/bi';
-
-export default function callback() {
+import { IRetrieveCommunitiesProps } from '../store/types/ICentric';
+import useAppStore from '../store/useStore';
+import { ICommunity, metaData } from '../utils/interfaces';
+
+export type CommunityWithoutAvatar = Omit;
+interface Params {
+ name: string;
+ platform: string;
+ id: string;
+ username?: string;
+ profileImageUrl?: string;
+ icon?: string;
+}
+/**
+ * Callback Component.
+ *
+ * This component is designed to handle the callback after a user tries to authorize
+ * with Discord. Based on the status code received in the URL parameters, it will display
+ * appropriate messages to the user.
+ */
+function Callback() {
+ // State to store the displayed message
+ const [message, setMessage] = useState(null);
+
+ // Next.js router instance
const router = useRouter();
- const [loading, toggleLoading] = useState(true);
- if (typeof window !== 'undefined') {
- useEffect(() => {
- if (
- router?.query &&
- Object.keys(router?.query) &&
- Object.keys(router?.query).length > 0
- ) {
- const routerParams: callbackUrlParams = Object.assign(router.query);
- statusDecoder(routerParams);
+ // Method to retrieve communities from the store.
+ const { retrieveCommunities, createNewPlatform } = useAppStore();
+
+ /**
+ * Asynchronously fetches communities.
+ * Depending on the presence of communities, it will redirect to either the terms and conditions
+ * page or the community selection page.
+ */
+ const fetchCommunities = async () => {
+ const params: IRetrieveCommunitiesProps = { page: 1, limit: 10 };
+ try {
+ const communities = await retrieveCommunities(params);
+ if (communities.results.length === 0) {
+ router.push('/centric/tac');
} else {
- router.push('/tryNow');
+ router.push('/centric/select-community');
}
- }, [router]);
- }
-
- const notify = () => {
- toast('Discord authentication faild.please try again.', {
- position: 'bottom-left',
- autoClose: 3000,
- hideProgressBar: true,
- closeOnClick: false,
- pauseOnHover: true,
- draggable: false,
- progress: undefined,
- closeButton: false,
- theme: 'light',
- icon: ,
- });
+ } catch (error) {
+ console.error('Failed to retrieve communities:', error);
+ }
};
- const statusDecoder = (params: callbackUrlParams) => {
- const { statusCode } = params;
- let user = StorageService.readLocalStorage('user');
- switch (statusCode) {
- case '490':
- notify();
- router.push('/tryNow');
- break;
+ const handleCreateNewPlatform = async (params: Params) => {
+ const community =
+ StorageService.readLocalStorage('community');
- case '491':
- notify();
- router.push('/settings');
- break;
+ if (!community) {
+ console.error('Community not found in local storage.');
+ return;
+ }
- case '501':
- router.push({
- pathname: '/tryNow',
- query: {
- statusCode: params.statusCode,
- accessToken: params.accessToken,
- accessExp: params.accessExp,
- refreshExp: params.refreshExp,
- refreshToken: params.refreshToken,
- guildId: params.guildId,
- guildName: params.guildName,
- },
- });
- break;
+ let metadata: metaData = {
+ id: params.id,
+ };
- case '502':
- router.push({
- pathname: '/tryNow',
- query: {
- statusCode: params.statusCode,
- accessToken: params.accessToken,
- accessExp: params.accessExp,
- refreshExp: params.refreshExp,
- refreshToken: params.refreshToken,
- guildId: params.guildId,
- guildName: params.guildName,
- },
- });
- break;
+ if (params.platform === 'twitter') {
+ metadata.username = params.username;
+ metadata.profileImageUrl = params.profileImageUrl;
+ } else if (params.platform === 'discord') {
+ metadata.icon = params.icon;
+ metadata.name = params.name;
+ }
- case '503':
- StorageService.writeLocalStorage('user', {
- guild: {
- guildId: params.guildId,
- guildName: params.guildName,
- },
- token: {
- accessToken: params.accessToken,
- accessExp: params.accessExp,
- refreshToken: params.refreshToken,
- refreshExp: params.refreshExp,
- },
- });
- router.push({
- pathname: '/',
- });
- break;
+ const payload = {
+ name: params.platform,
+ community: community.id,
+ metadata: metadata,
+ };
- case '504':
- StorageService.writeLocalStorage('user', {
- guild: {
- guildId: params.guildId,
- guildName: params.guildName,
- },
- token: {
- accessToken: params.accessToken,
- accessExp: params.accessExp,
- refreshToken: params.refreshToken,
- refreshExp: params.refreshExp,
- },
- });
- router.push({
- pathname: '/',
- });
- break;
+ try {
+ const data = await createNewPlatform(payload);
+ if (!data) {
+ router.push('community-settings');
+ }
+ router.push(`/community-settings/platform/${data.id}`);
+ } catch (error) {
+ console.error('Failed to create new platform:', error);
+ }
+ };
+
+ /**
+ * Handles the display message based on the received status code.
+ *
+ * @param {StatusCode} code - The status code received from the URL parameters.
+ */
+ const handleStatusCode = (code: StatusCode, params: any) => {
+ switch (code) {
+ case StatusCode.DISCORD_AUTHORIZATION_SUCCESSFUL_FIRST_TIME:
+ setMessage('Welcome! Authorization for sign-in was successful.');
+ StorageService.writeLocalStorage('user', params);
+ fetchCommunities();
- case '601':
- StorageService.writeLocalStorage('user', {
- guild: {
- guildId: params.guildId,
- guildName: params.guildName,
- },
- token: {
- accessToken: params.accessToken,
- accessExp: params.accessExp,
- refreshToken: params.refreshToken,
- refreshExp: params.refreshExp,
- },
- });
- router.push('/');
break;
- case '602':
- StorageService.removeLocalStorage('user');
- router.push('/tryNow');
+ case StatusCode.REPEATED_DISCORD_AUTHORIZATION_ATTEMPT:
+ setMessage(
+ 'You have authorized before and are trying to authorize again.'
+ );
+ StorageService.writeLocalStorage('user', params);
+ fetchCommunities();
+
break;
- case '603':
- StorageService.writeLocalStorage('user', {
- guild: {
- guildId: params.guildId,
- guildName: params.guildName,
- },
- token: {
- accessToken: params.accessToken,
- accessExp: params.accessExp,
- refreshToken: params.refreshToken,
- refreshExp: params.refreshExp,
- },
- });
- router.push('/');
+ case StatusCode.DISCORD_AUTHORIZATION_FAILURE:
+ setMessage('Authorization failed. Please try again.');
+ handleCreateNewPlatform(params);
break;
- case '701':
- if (user) {
- StorageService.writeLocalStorage('user', {
- guild: {
- guildId: params.guildId,
- guildName: params.guildName,
- },
- token: user.token,
- });
- router.push({
- pathname: '/settings',
- query: {
- guildId: params.guildId,
- guildName: params.guildName,
- isSuccessful: true,
- },
- });
- }
+ case StatusCode.DISCORD_AUTHORIZATION_FROM_SETTINGS:
+ setMessage('Authorizion complete from settings page.');
+ handleCreateNewPlatform(params);
break;
- case '702':
- if (user) {
- StorageService.writeLocalStorage('user', {
- guild: {
- guildId: params.guildId,
- guildName: params.guildName,
- },
- token: user.token,
- });
- router.push({
- pathname: '/settings',
- query: {
- guildId: params.guildId,
- guildName: params.guildName,
- isSuccessful: true,
- },
- });
- }
+ case StatusCode.TWITTER_AUTHORIZATION_SUCCESSFUL:
+ setMessage('Authorizion complete from settings page.');
+ handleCreateNewPlatform(params);
break;
+ case StatusCode.TWITTER_AUTHORIZATION_FAILURE:
+ setMessage('Twitter Authorization failed.');
+ router.push('/community-settings');
+
+ case StatusCode.DISCORD_AUTHORIZATION_FAILURE_FROM_SETTINGS:
+ setMessage('Discord Authorization during setup on setting faield.');
+ router.push('/community-settings');
+
default:
+ console.error('Unexpected status code received:', code);
+ setMessage('An unexpected error occurred. Please try again later.');
break;
}
};
- if (loading) {
- return ;
- }
+ /**
+ * useEffect hook to handle status codes.
+ *
+ * It waits until the router instance is ready, extracts the parameters from the URL,
+ * and then handles the status code accordingly.
+ */
+ useEffect(() => {
+ if (router.isReady) {
+ const params = extractUrlParams(router.asPath);
+
+ if (
+ params.statusCode &&
+ Object.values(StatusCode).includes(params.statusCode as StatusCode)
+ ) {
+ handleStatusCode(params.statusCode as StatusCode, params);
+ } else {
+ console.error('Invalid or no status code found in the URL.');
+ setMessage(
+ 'An error occurred while processing your request. Please try again.'
+ );
+ }
+ }
+ }, [router.isReady]);
+
+ return ;
}
+
+export default Callback;
diff --git a/src/pages/centric/create-new-community.tsx b/src/pages/centric/create-new-community.tsx
new file mode 100644
index 00000000..d32928c8
--- /dev/null
+++ b/src/pages/centric/create-new-community.tsx
@@ -0,0 +1,114 @@
+import React, { useState } from 'react';
+import centricLayout from '../../layouts/centricLayout';
+import TcText from '../../components/shared/TcText';
+import TcBoxContainer from '../../components/shared/TcBox/TcBoxContainer';
+import TcInput from '../../components/shared/TcInput';
+import TcCheckbox from '../../components/shared/TcCheckbox';
+import { FormControlLabel } from '@mui/material';
+import TcLink from '../../components/shared/TcLink';
+import TcButton from '../../components/shared/TcButton';
+import router from 'next/router';
+import useAppStore from '../../store/useStore';
+import SimpleBackdrop from '../../components/global/LoadingBackdrop';
+import { useToken } from '../../context/TokenContext';
+
+function CreateNewCommunity() {
+ const { createNewCommunitie } = useAppStore();
+ const { updateCommunity } = useToken();
+
+ const [loading, setLoading] = useState(false);
+ const [communityName, setCommunityName] = useState('');
+ const [readTermsAndCondition, setReadTermsAndCondition] =
+ useState(false);
+
+ const handleCreateNewCommunitie = async () => {
+ setLoading(true);
+ const community = await createNewCommunitie({
+ name: communityName,
+ tcaAt: new Date().toISOString(),
+ });
+
+ updateCommunity(community);
+
+ router.push('/');
+ };
+ if (loading) {
+ return (
+ <>
+
+ >
+ );
+ }
+ return (
+
+
+
+
+ setCommunityName(e.target.value)}
+ />
+
+
+ {'I understand and agree to the '}
+
+ Privacy Policy
+
+ {' and '}
+
+ Terms of Service.
+
+ >
+ }
+ variant={'subtitle2'}
+ />
+ }
+ control={
+ setReadTermsAndCondition(e.target.checked)}
+ />
+ }
+ />
+
+ handleCreateNewCommunitie()}
+ />
+
+
+ }
+ />
+ );
+}
+
+CreateNewCommunity.pageLayout = centricLayout;
+
+export default CreateNewCommunity;
diff --git a/src/pages/centric/index.tsx b/src/pages/centric/index.tsx
new file mode 100644
index 00000000..e6b655f5
--- /dev/null
+++ b/src/pages/centric/index.tsx
@@ -0,0 +1,44 @@
+import React from 'react';
+import centricLayout from '../../layouts/centricLayout';
+import TcBoxContainer from '../../components/shared/TcBox/TcBoxContainer';
+import TcText from '../../components/shared/TcText';
+import TcButton from '../../components/shared/TcButton';
+import useAppStore from '../../store/useStore';
+
+function Index() {
+ const { discordAuthorization } = useAppStore();
+ return (
+