Compare commits

...

3 Commits

Author SHA1 Message Date
Flatlogic Bot
fbbc411823 Upgrade_3 2025-07-02 06:45:15 +00:00
Flatlogic Bot
72986fa192 upgrade_2 2025-07-02 06:28:27 +00:00
Flatlogic Bot
cb4671c3a0 stocksageAI_upgrade_1 2025-07-02 05:06:07 +00:00
29 changed files with 527 additions and 112 deletions

5
.gitignore vendored
View File

@ -1,3 +1,8 @@
node_modules/
*/node_modules/
*/build/
**/node_modules/
**/build/
.DS_Store
.env

View File

@ -129,7 +129,7 @@
<p class="tip">The application is currently launching. The page will automatically refresh once site is
available.</p>
<div class="project-info">
<h2>Build SaaS app that analysis stock in Nigeria</h2>
<h2>StocksageAI</h2>
<p>AI-powered SaaS for stock analysis and recommendations.</p>
</div>
<div class="loader-container">

View File

@ -1,6 +1,6 @@
# Build SaaS app that analysis stock in Nigeria
# StocksageAI
## This project was generated by [Flatlogic Platform](https://flatlogic.com).

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
#Build SaaS app that analysis stock in Nigeria - template backend,
#StocksageAI - template backend,
#### Run App on local machine:
@ -38,10 +38,10 @@
- Type this command to creating a new database.
- `postgres=> CREATE DATABASE db_build_saas_app_that_analysis_stock_in_nigeria;`
- `postgres=> CREATE DATABASE db_stocksageai;`
- Then give that new user privileges to the new database then quit the `psql`.
- `postgres=> GRANT ALL PRIVILEGES ON DATABASE db_build_saas_app_that_analysis_stock_in_nigeria TO admin;`
- `postgres=> GRANT ALL PRIVILEGES ON DATABASE db_stocksageai TO admin;`
- `postgres=> \q`
---

View File

@ -1,6 +1,6 @@
{
"name": "buildsaasappthatanalysisstockinnigeria",
"description": "Build SaaS app that analysis stock in Nigeria - template backend",
"name": "stocksageai",
"description": "StocksageAI - template backend",
"scripts": {
"start": "npm run db:migrate && npm run db:seed && npm run watch",
"db:migrate": "sequelize-cli db:migrate",
@ -19,6 +19,8 @@
"express": "4.18.2",
"formidable": "1.2.2",
"helmet": "4.1.1",
"yahoo-finance2": "^2.0.0",
"node-cron": "^3.10.0",
"json2csv": "^5.0.7",
"jsonwebtoken": "8.5.1",
"lodash": "4.17.21",

View File

@ -3,7 +3,7 @@ const os = require('os');
const config = {
gcloud: {
bucket: 'fldemo-files',
hash: 'ee24f1c4218f76f2439ec343363a5eab',
hash: 'afeefb9d49f5b7977577876b99532ac7',
},
bcrypt: {
saltRounds: 12,
@ -36,7 +36,7 @@ const config = {
},
uploadDir: os.tmpdir(),
email: {
from: 'Build SaaS app that analysis stock in Nigeria <app@flatlogic.app>',
from: 'StocksageAI <app@flatlogic.app>',
host: 'email-smtp.us-east-1.amazonaws.com',
port: 587,
auth: {

View File

@ -13,7 +13,7 @@ module.exports = {
username: 'postgres',
dialect: 'postgres',
password: '',
database: 'db_build_saas_app_that_analysis_stock_in_nigeria',
database: 'db_stocksageai',
host: process.env.DB_HOST || 'localhost',
logging: console.log,
seederStorage: 'sequelize',

View File

@ -107,7 +107,7 @@ const StocksData = [
score: 85.5,
market: 'nigeria',
market: 'us',
// type code here for "relation_many" field
@ -123,7 +123,7 @@ const StocksData = [
score: 78.3,
market: 'us',
market: 'nigeria',
// type code here for "relation_many" field
@ -139,7 +139,7 @@ const StocksData = [
score: 92.1,
market: 'nigeria',
market: 'us',
// type code here for "relation_many" field
@ -155,7 +155,7 @@ const StocksData = [
score: 88.7,
market: 'us',
market: 'nigeria',
// type code here for "relation_many" field
@ -165,7 +165,7 @@ const StocksData = [
const SubscriptionsData = [
{
type: 'premium',
type: 'freemium',
start_date: new Date('2023-10-01T00:00:00Z'),
@ -177,7 +177,7 @@ const SubscriptionsData = [
},
{
type: 'premium',
type: 'freemium',
start_date: new Date('2023-10-01T00:00:00Z'),
@ -189,7 +189,7 @@ const SubscriptionsData = [
},
{
type: 'premium',
type: 'corporate',
start_date: new Date('2023-10-01T00:00:00Z'),
@ -215,19 +215,19 @@ const SubscriptionsData = [
const OrganizationsData = [
{
name: 'Noam Chomsky',
name: 'Max von Laue',
},
{
name: 'Karl Landsteiner',
name: 'Archimedes',
},
{
name: 'William Harvey',
name: 'Gustav Kirchhoff',
},
{
name: 'Rudolf Virchow',
name: 'George Gaylord Simpson',
},
];

View File

@ -47,9 +47,9 @@ const options = {
openapi: '3.0.0',
info: {
version: '1.0.0',
title: 'Build SaaS app that analysis stock in Nigeria',
title: 'StocksageAI',
description:
'Build SaaS app that analysis stock in Nigeria Online REST API for Testing and Prototyping application. You can perform all major operations with your entities - create, delete and etc.',
'StocksageAI Online REST API for Testing and Prototyping application. You can perform all major operations with your entities - create, delete and etc.',
},
servers: [
{

View File

@ -12,6 +12,29 @@ const { parse } = require('json2csv');
const { checkCrudPermissions } = require('../middlewares/check-permissions');
// Market data endpoints
const marketDataService = require('../services/marketDataService');
// Get historical price data for different ranges
router.get('/:id/price-history', wrapAsync(async (req, res) => {
const stock = await StocksDBApi.findBy({ id: req.params.id });
if (!stock) {
return res.status(404).send({ message: 'Stock not found' });
}
const range = req.query.range || 'monthly';
const data = await marketDataService.getHistoricalPrices(stock.ticker, range);
res.status(200).send(data);
}));
// Get current market price
router.get('/:id/price-current', wrapAsync(async (req, res) => {
const stock = await StocksDBApi.findBy({ id: req.params.id });
if (!stock) {
return res.status(404).send({ message: 'Stock not found' });
}
const price = await marketDataService.getCurrentPrice(stock.ticker);
res.status(200).send({ price });
}));
router.use(checkCrudPermissions('stocks'));
/**

View File

@ -0,0 +1,32 @@
const yahooFinance = require('yahoo-finance2').default;
async function getCurrentPrice(ticker) {
const quote = await yahooFinance.quote(ticker);
return quote.regularMarketPrice;
}
async function getHistoricalPrices(ticker, range) {
const now = new Date();
let days;
switch (range) {
case 'daily': days = 1; break;
case 'weekly': days = 7; break;
case 'monthly': days = 30; break;
case '3m': days = 90; break;
case '6m': days = 180; break;
case '1y': days = 365; break;
case '3y': days = 365 * 3; break;
case '5y': days = 365 * 5; break;
default: days = 30;
}
const from = new Date(now.getTime() - days * 24 * 60 * 60 * 1000);
const options = { period1: from, period2: now, interval: '1d' };
const result = await yahooFinance.historical(ticker, options);
// Return array of { date, price }
return result.map(item => ({ date: item.date, price: item.close }));
}
module.exports = {
getCurrentPrice,
getHistoricalPrices,
};

View File

@ -1,6 +1,6 @@
const errors = {
app: {
title: 'Build SaaS app that analysis stock in Nigeria',
title: 'StocksageAI',
},
auth: {

View File

@ -25,7 +25,7 @@ services:
- ./data/db:/var/lib/postgresql/data
environment:
- POSTGRES_HOST_AUTH_METHOD=trust
- POSTGRES_DB=db_build_saas_app_that_analysis_stock_in_nigeria
- POSTGRES_DB=db_stocksageai
ports:
- "5432:5432"
logging:

View File

@ -1,4 +1,4 @@
# Build SaaS app that analysis stock in Nigeria
# StocksageAI
## This project was generated by Flatlogic Platform.

View File

@ -0,0 +1 @@
{}

View File

@ -76,9 +76,7 @@ export default function AsideMenuLayer({
>
<div className='text-center flex-1 lg:text-left lg:pl-6 xl:text-center xl:pl-0'>
<Link href={'/home'}>
<b className='font-black'>
Build SaaS app that analysis stock in Nigeria
</b>
<b className='font-black'>StocksageAI</b>
</Link>
{organizationName && <p>{organizationName}</p>}

View File

@ -17,9 +17,9 @@ export default function WebSiteFooter({ projectName }: WebSiteFooterProps) {
const borders = useAppSelector((state) => state.style.borders);
const websiteHeder = useAppSelector((state) => state.style.websiteHeder);
const style = FooterStyle.WITH_PROJECT_NAME;
const style = FooterStyle.WITH_PAGES;
const design = FooterDesigns.DEFAULT_DESIGN;
const design = FooterDesigns.DESIGN_DIVERSITY;
return (
<div

View File

@ -19,7 +19,7 @@ export default function WebSiteHeader({ projectName }: WebSiteHeaderProps) {
const style = HeaderStyle.PAGES_RIGHT;
const design = HeaderDesigns.DESIGN_DIVERSITY;
const design = HeaderDesigns.DEFAULT_DESIGN;
return (
<header id='websiteHeader' className='overflow-hidden'>
<div

View File

@ -140,9 +140,8 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
setStepsEnabled(false);
};
const title = 'Build SaaS app that analysis stock in Nigeria';
const description =
'Build SaaS app that analysis stock in Nigeria generated by Flatlogic';
const title = 'StocksageAI';
const description = 'StocksageAI generated by Flatlogic';
const url = 'https://flatlogic.com/';
const image = `https://flatlogic.com/logo.svg`;
const imageWidth = '1920';

View File

@ -24,7 +24,7 @@ import AboutUsSection from '../components/WebPageComponents/AboutUsComponent';
export default function WebSite() {
const cardsStyle = useAppSelector((state) => state.style.cardsStyle);
const bgColor = useAppSelector((state) => state.style.bgLayoutColor);
const projectName = 'Build SaaS app that analysis stock in Nigeria';
const projectName = 'StocksageAI';
useEffect(() => {
const darkElement = document.querySelector('body .dark');
@ -129,19 +129,14 @@ export default function WebSite() {
return (
<div className='flex flex-col min-h-screen'>
<Head>
<title>{`StockSageAI - Discover Undervalued Stocks with AI Insights`}</title>
<meta
name='description'
<title>{`StocksageAI - Discover Undervalued Stocks with AI Insights`}</title>
content={`Explore StockSageAI, the AI-powered platform that analyzes stocks in Nigeria and US markets using fundamental, technical, and sentiment data to identify undervalued stocks poised for growth.`}
/>
content={`Explore StocksageAI, the AI-powered platform that analyzes stocks in Nigeria and US markets using fundamental, technical, and sentiment data to identify undervalued stocks poised for growth.`}
</Head>
<WebSiteHeader
projectName={'Build SaaS app that analysis stock in Nigeria'}
pages={pages}
/>
<WebSiteHeader projectName={'StocksageAI'} pages={pages} />
<main className={`flex-grow bg-white rounded-none `}>
<HeroSection
projectName={'Build SaaS app that analysis stock in Nigeria'}
projectName={'StocksageAI'}
image={['AI analyzing stock charts']}
mainText={`Unlock Stock Potential with ${projectName}`}
subTitle={`${projectName} leverages AI to analyze stocks in Nigeria and US markets, identifying undervalued opportunities for rapid growth. Discover your next investment today.`}
@ -150,9 +145,9 @@ export default function WebSite() {
/>
<FeaturesSection
projectName={'Build SaaS app that analysis stock in Nigeria'}
projectName={'StocksageAI'}
image={['AI-driven stock analysis']}
withBg={1}
withBg={0}
features={features_points}
mainText={`Explore ${projectName} Features`}
subTitle={`Discover how ${projectName} empowers investors with AI-driven insights and tools to make informed decisions.`}
@ -160,14 +155,14 @@ export default function WebSite() {
/>
<PricingSection
projectName={'Build SaaS app that analysis stock in Nigeria'}
projectName={'StocksageAI'}
withBg={1}
features={pricing_features}
description={description}
/>
<AboutUsSection
projectName={'Build SaaS app that analysis stock in Nigeria'}
projectName={'StocksageAI'}
image={['Team collaborating on stock analysis']}
mainText={`Empowering Investors with ${projectName}`}
subTitle={`At ${projectName}, we harness the power of AI to provide investors with unparalleled insights into the stock market. Our mission is to simplify investment decisions and maximize growth potential.`}
@ -175,10 +170,7 @@ export default function WebSite() {
buttonText={`Learn More About Us`}
/>
</main>
<WebSiteFooter
projectName={'Build SaaS app that analysis stock in Nigeria'}
pages={pages}
/>
<WebSiteFooter projectName={'StocksageAI'} pages={pages} />
</div>
);
}

View File

@ -18,8 +18,10 @@ import { getPageTitle } from '../config';
import { findMe, loginUser, resetAction } from '../stores/authSlice';
import { useAppDispatch, useAppSelector } from '../stores/hooks';
import Link from 'next/link';
import placeholderImage from '../assets/login-placeholder.jpg';
// Removed Pexels dependencies and will use a static placeholder image instead
import { toast, ToastContainer } from 'react-toastify';
import { getPexelsImage, getPexelsVideo } from '../helpers/pexels';
export default function Login() {
const { t } = useTranslation('common');
@ -52,18 +54,8 @@ export default function Login() {
remember: true,
});
const title = 'Build SaaS app that analysis stock in Nigeria';
const title = 'StocksageAI';
// Fetch Pexels image/video
useEffect(() => {
async function fetchData() {
const image = await getPexelsImage();
const video = await getPexelsVideo();
setIllustrationImage(image);
setIllustrationVideo(video);
}
fetchData();
}, []);
// Fetch user data
useEffect(() => {
if (token) {

View File

@ -0,0 +1,320 @@
import React, { useEffect, useState } from 'react';
import type { ReactElement } from 'react';
import Head from 'next/head';
import { useTranslation } from 'next-i18next';
import BaseButton from '../components/BaseButton';
import CardBox from '../components/CardBox';
import BaseIcon from '../components/BaseIcon';
import { mdiInformation, mdiEye, mdiEyeOff } from '@mdi/js';
import SectionFullScreen from '../components/SectionFullScreen';
import LayoutGuest from '../layouts/Guest';
import { Field, Form, Formik } from 'formik';
import FormField from '../components/FormField';
import FormCheckRadio from '../components/FormCheckRadio';
import BaseDivider from '../components/BaseDivider';
import BaseButtons from '../components/BaseButtons';
import { useRouter } from 'next/router';
import { getPageTitle } from '../config';
import { findMe, loginUser, resetAction } from '../stores/authSlice';
import { useAppDispatch, useAppSelector } from '../stores/hooks';
import Link from 'next/link';
import placeholderImage from '../assets/login-placeholder.jpg';
// Removed Pexels dependencies and will use a static placeholder image instead
import { toast, ToastContainer } from 'react-toastify';
export default function Login() {
const { t } = useTranslation('common');
const router = useRouter();
const dispatch = useAppDispatch();
const textColor = useAppSelector((state) => state.style.linkColor);
const iconsColor = useAppSelector((state) => state.style.iconsColor);
const notify = (type, msg) => toast(msg, { type });
const [illustrationImage, setIllustrationImage] = useState({
src: undefined,
photographer: undefined,
photographer_url: undefined,
});
const [illustrationVideo, setIllustrationVideo] = useState({
video_files: [],
});
const [contentType, setContentType] = useState('video');
const [contentPosition, setContentPosition] = useState('left');
const [showPassword, setShowPassword] = useState(false);
const {
currentUser,
isFetching,
errorMessage,
token,
notify: notifyState,
} = useAppSelector((state) => state.auth);
const [initialValues, setInitialValues] = React.useState({
email: 'super_admin@flatlogic.com',
password: '8ca3e282',
remember: true,
});
const title = 'StocksageAI';
// Fetch user data
useEffect(() => {
if (token) {
dispatch(findMe());
}
}, [token, dispatch]);
// Redirect to dashboard if user is logged in
useEffect(() => {
if (currentUser?.id) {
router.push('/dashboard');
}
}, [currentUser?.id, router]);
// Show error message if there is one
useEffect(() => {
if (errorMessage) {
notify('error', errorMessage);
}
}, [errorMessage]);
// Show notification if there is one
useEffect(() => {
if (notifyState?.showNotification) {
notify('success', notifyState?.textNotification);
dispatch(resetAction());
}
}, [notifyState?.showNotification]);
const togglePasswordVisibility = () => {
setShowPassword(!showPassword);
};
const handleSubmit = async (value) => {
const { remember, ...rest } = value;
await dispatch(loginUser(rest));
};
const setLogin = (target: HTMLElement) => {
setInitialValues((prev) => ({
...prev,
email: target.innerText.trim(),
password: target.dataset.password ?? '',
}));
};
const imageBlock = (image) => (
<div
className='hidden md:flex flex-col justify-end relative flex-grow-0 flex-shrink-0 w-1/3'
style={{
backgroundImage: `${
image
? `url(${image.src?.original})`
: 'linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.5))'
}`,
backgroundSize: 'cover',
backgroundPosition: 'left center',
backgroundRepeat: 'no-repeat',
backgroundPosition: 'left center',
backgroundRepeat: 'no-repeat',
}
: {}
}
>
<Head>
<title>
{getPageTitle(t('pages.login.pageTitle', { defaultValue: 'Login' }))}
</title>
</Head>
<SectionFullScreen bg='violet'>
<div
className={`flex ${
contentPosition === 'right' ? 'flex-row-reverse' : 'flex-row'
} min-h-screen w-full`}
>
{contentType === 'image' && contentPosition !== 'background'
? imageBlock(illustrationImage)
: null}
{contentType === 'video' && contentPosition !== 'background'
? videoBlock(illustrationVideo)
: null}
<div className='flex items-center justify-center flex-col space-y-4 w-full lg:w-full'>
<CardBox id='loginRoles' className='w-full md:w-3/5 lg:w-2/3'>
<Link href={'/home'}>
<h2 className='text-4xl font-semibold my-4'> {title}</h2>
</Link>
<div className='flex flex-row text-gray-500 justify-between'>
<div>
<p className='mb-2'>
Use{' '}
<code
className={`cursor-pointer ${textColor} `}
data-password='8ca3e282'
onClick={(e) => setLogin(e.target)}
>
super_admin@flatlogic.com
</code>
{' / '}
<code className={`${textColor}`}>8ca3e282</code>
{' / '}
to login as Super Admin
</p>
<p className='mb-2'>
Use{' '}
<code
className={`cursor-pointer ${textColor} `}
data-password='8ca3e282'
onClick={(e) => setLogin(e.target)}
>
admin@flatlogic.com
</code>
{' / '}
<code className={`${textColor}`}>8ca3e282</code>
{' / '}
to login as Admin
</p>
<p>
Use{' '}
<code
className={`cursor-pointer ${textColor} `}
data-password='4ab6dd8858d8'
onClick={(e) => setLogin(e.target)}
>
client@hello.com
</code>
{' / '}
<code className={`${textColor}`}>4ab6dd8858d8</code>
{' / '}
to login as User
</p>
</div>
<div>
<BaseIcon
className={`${iconsColor}`}
w='w-16'
h='h-16'
size={48}
path={mdiInformation}
/>
</div>
</div>
</CardBox>
<CardBox className='w-full md:w-3/5 lg:w-2/3'>
<Formik
initialValues={initialValues}
enableReinitialize
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField
label={t('pages.login.form.loginLabel', {
defaultValue: 'Login',
})}
help={t('pages.login.form.loginHelp', {
defaultValue: 'Please enter your login',
})}
>
<Field name='email' />
</FormField>
<div className='relative'>
<FormField
label={t('pages.login.form.passwordLabel', {
defaultValue: 'Password',
})}
help={t('pages.login.form.passwordHelp', {
defaultValue: 'Please enter your password',
})}
>
<Field
name='password'
type={showPassword ? 'text' : 'password'}
/>
</FormField>
<div
className='absolute bottom-8 right-0 pr-3 flex items-center cursor-pointer'
onClick={togglePasswordVisibility}
>
<BaseIcon
className='text-gray-500 hover:text-gray-700'
size={20}
path={showPassword ? mdiEyeOff : mdiEye}
/>
</div>
</div>
<div className={'flex justify-between'}>
<FormCheckRadio
type='checkbox'
label={t('pages.login.form.remember', {
defaultValue: 'Remember',
})}
>
<Field type='checkbox' name='remember' />
</FormCheckRadio>
<Link
className={`${textColor} text-blue-600`}
href={'/forgot'}
>
{t('pages.login.form.forgotPassword', {
defaultValue: 'Forgot password?',
})}
</Link>
</div>
<BaseDivider />
<BaseButtons>
<BaseButton
className={'w-full'}
type='submit'
label={
isFetching
? t('pages.login.form.loading', {
defaultValue: 'Loading...',
})
: t('pages.login.form.loginButton', {
defaultValue: 'Login',
})
}
color='info'
disabled={isFetching}
/>
</BaseButtons>
<br />
<p className={'text-center'}>
{t('pages.login.form.noAccountYet', {
defaultValue: 'Dont have an account yet?',
})}{' '}
<Link className={`${textColor}`} href={'/register'}>
{t('pages.login.form.newAccount', {
defaultValue: 'New Account',
})}
</Link>
</p>
</Form>
</Formik>
</CardBox>
</div>
</div>
</SectionFullScreen>
<div className='bg-black text-white flex flex-col text-center justify-center md:flex-row'>
<p className='py-6 text-sm'>
© 2024 <span>{title}</span>.{' '}
{t('pages.login.footer.copyright', {
defaultValue: '© All rights reserved',
})}
</p>
<Link className='py-6 ml-4 text-sm' href='/privacy-policy/'>
{t('pages.login.footer.privacy', { defaultValue: 'Privacy Policy' })}
</Link>
</div>
<ToastContainer />
</div>
);
}
Login.getLayout = function getLayout(page: ReactElement) {
return <LayoutGuest>{page}</LayoutGuest>;
};

View File

@ -5,7 +5,7 @@ import LayoutGuest from '../layouts/Guest';
import { getPageTitle } from '../config';
export default function PrivacyPolicy() {
const title = 'Build SaaS app that analysis stock in Nigeria';
const title = 'StocksageAI';
const [projectUrl, setProjectUrl] = useState('');
useEffect(() => {

View File

@ -1,4 +1,4 @@
import React, { ReactElement, useEffect } from 'react';
import React, { ReactElement, useEffect, useState } from 'react';
import Head from 'next/head';
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
@ -17,6 +17,21 @@ import CardBox from '../../components/CardBox';
import BaseButton from '../../components/BaseButton';
import BaseDivider from '../../components/BaseDivider';
import { mdiChartTimelineVariant } from '@mdi/js';
import axios from 'axios';
import { Line } from 'react-chartjs-2';
import {
Chart as ChartJS,
LineElement,
PointElement,
CategoryScale,
LinearScale,
Tooltip,
Legend,
} from 'chart.js';
ChartJS.register(LineElement, PointElement, CategoryScale, LinearScale, Tooltip, Legend);
import { SwitchField } from '../../components/SwitchField';
import FormField from '../../components/FormField';
@ -34,6 +49,33 @@ const StocksView = () => {
function removeLastCharacter(str) {
console.log(str, `str`);
return str.slice(0, -1);
// Chart timeframe controls and data state
const ranges = ['daily','weekly','monthly','3m','6m','1y','3y','5y'];
const [selectedRange, setSelectedRange] = useState('monthly');
const [chartData, setChartData] = useState([]);
useEffect(() => {
if (!id) return;
axios.get(`/api/stocks/${id}/price-history?range=${selectedRange}`)
.then(res => setChartData(res.data))
.catch(err => console.error(err));
}, [id, selectedRange]);
// Prepare data for Chart.js
const chartLabels = chartData.map(item => dayjs(item.date).format('YYYY-MM-DD'));
const chartPrices = chartData.map(item => item.price);
const chartJsData = {
labels: chartLabels,
datasets: [{
label: `Price (${selectedRange})`,
data: chartPrices,
borderColor: '#4F46E5',
backgroundColor: 'rgba(79,70,229,0.5)',
fill: false,
}]
};
}
useEffect(() => {
@ -43,6 +85,27 @@ const StocksView = () => {
return (
<>
<Head>
<div className="mb-4">
<div className="flex space-x-2 mb-4">
{ranges.map(range => (
<button
key={range}
onClick={() => setSelectedRange(range)}
className={
selectedRange === range
? 'px-3 py-1 rounded border bg-blue-500 text-white'
: 'px-3 py-1 rounded border bg-white text-blue-500'
}
>
{range.toUpperCase()}
</button>
))}
</div>
<div className="h-64 mb-4">
<Line data={chartJsData} options={{ responsive: true, maintainAspectRatio: false }} />
</div>
</div>
<title>{getPageTitle('View stocks')}</title>
</Head>
<SectionMain>

View File

@ -5,7 +5,7 @@ import LayoutGuest from '../layouts/Guest';
import { getPageTitle } from '../config';
export default function PrivacyPolicy() {
const title = 'Build SaaS app that analysis stock in Nigeria';
const title = 'StocksageAI';
const [projectUrl, setProjectUrl] = useState('');
useEffect(() => {

View File

@ -21,7 +21,7 @@ import FaqSection from '../../components/WebPageComponents/FaqComponent';
export default function WebSite() {
const cardsStyle = useAppSelector((state) => state.style.cardsStyle);
const bgColor = useAppSelector((state) => state.style.bgLayoutColor);
const projectName = 'Build SaaS app that analysis stock in Nigeria';
const projectName = 'StocksageAI';
useEffect(() => {
const darkElement = document.querySelector('body .dark');
@ -67,17 +67,15 @@ export default function WebSite() {
<div className='flex flex-col min-h-screen'>
<Head>
<title>{`Contact StockSageAI Support`}</title>
<meta
<title>{`Contact StocksageAI Support`}</title>
name='description'
content={`Get in touch with StockSageAI for any inquiries, support, or feedback. Our team is here to assist you with your stock analysis needs.`}
/>
content={`Get in touch with StocksageAI for any inquiries, support, or feedback. Our team is here to assist you with your stock analysis needs.`}
</Head>
<WebSiteHeader
projectName={'Build SaaS app that analysis stock in Nigeria'}
/>
<WebSiteHeader projectName={'StocksageAI'} />
<main className={`flex-grow bg-white rounded-none `}>
<HeroSection
projectName={'Build SaaS app that analysis stock in Nigeria'}
projectName={'StocksageAI'}
image={['Customer support team ready']}
mainText={`Connect with ${projectName} Support Team`}
subTitle={`Have questions or need assistance? Our dedicated support team at ${projectName} is here to help you with any inquiries or feedback. Reach out to us today.`}
@ -86,23 +84,21 @@ export default function WebSite() {
/>
<FaqSection
projectName={'Build SaaS app that analysis stock in Nigeria'}
projectName={'StocksageAI'}
design={FaqDesigns.TWO_COLUMN || ''}
faqs={faqs}
mainText={`${projectName} Support FAQs `}
/>
<ContactFormSection
projectName={'Build SaaS app that analysis stock in Nigeria'}
projectName={'StocksageAI'}
design={ContactFormDesigns.WITH_IMAGE || ''}
image={['Email communication illustration']}
mainText={`Reach Out to ${projectName} `}
subTitle={`We're here to assist you. Contact us anytime, and our team will respond promptly to your inquiries. Your feedback is valuable to us at ${projectName}.`}
/>
</main>
<WebSiteFooter
projectName={'Build SaaS app that analysis stock in Nigeria'}
/>
<WebSiteFooter projectName={'StocksageAI'} />
</div>
);
}

View File

@ -24,7 +24,7 @@ import AboutUsSection from '../../components/WebPageComponents/AboutUsComponent'
export default function WebSite() {
const cardsStyle = useAppSelector((state) => state.style.cardsStyle);
const bgColor = useAppSelector((state) => state.style.bgLayoutColor);
const projectName = 'Build SaaS app that analysis stock in Nigeria';
const projectName = 'StocksageAI';
useEffect(() => {
const darkElement = document.querySelector('body .dark');
@ -114,17 +114,14 @@ export default function WebSite() {
<div className='flex flex-col min-h-screen'>
<Head>
<title>{`StockSageAI - Discover Undervalued Stocks with AI Insights`}</title>
<meta
name='description'
<title>{`StocksageAI - Discover Undervalued Stocks with AI Insights`}</title>
content={`Explore StockSageAI, the AI-powered platform that analyzes stocks in Nigeria and US markets using fundamental, technical, and sentiment data to identify undervalued stocks poised for growth.`}
/>
content={`Explore StocksageAI, the AI-powered platform that analyzes stocks in Nigeria and US markets using fundamental, technical, and sentiment data to identify undervalued stocks poised for growth.`}
</Head>
<WebSiteHeader
projectName={'Build SaaS app that analysis stock in Nigeria'}
/>
<WebSiteHeader projectName={'StocksageAI'} />
<main className={`flex-grow bg-white rounded-none `}>
<HeroSection
projectName={'Build SaaS app that analysis stock in Nigeria'}
projectName={'StocksageAI'}
image={['AI analyzing stock charts']}
mainText={`Unlock Stock Potential with ${projectName}`}
subTitle={`${projectName} leverages AI to analyze stocks in Nigeria and US markets, identifying undervalued opportunities for rapid growth. Discover your next investment today.`}
@ -133,9 +130,9 @@ export default function WebSite() {
/>
<FeaturesSection
projectName={'Build SaaS app that analysis stock in Nigeria'}
projectName={'StocksageAI'}
image={['AI-driven stock analysis']}
withBg={0}
withBg={1}
features={features_points}
mainText={`Explore ${projectName} Features`}
subTitle={`Discover how ${projectName} empowers investors with AI-driven insights and tools to make informed decisions.`}
@ -143,14 +140,14 @@ export default function WebSite() {
/>
<PricingSection
projectName={'Build SaaS app that analysis stock in Nigeria'}
projectName={'StocksageAI'}
withBg={0}
features={pricing_features}
description={description}
/>
<AboutUsSection
projectName={'Build SaaS app that analysis stock in Nigeria'}
projectName={'StocksageAI'}
image={['Team collaborating on stock analysis']}
mainText={`Empowering Investors with ${projectName}`}
subTitle={`At ${projectName}, we harness the power of AI to provide investors with unparalleled insights into the stock market. Our mission is to simplify investment decisions and maximize growth potential.`}
@ -158,9 +155,7 @@ export default function WebSite() {
buttonText={`Learn More About Us`}
/>
</main>
<WebSiteFooter
projectName={'Build SaaS app that analysis stock in Nigeria'}
/>
<WebSiteFooter projectName={'StocksageAI'} />
</div>
);
}

View File

@ -21,7 +21,7 @@ import FaqSection from '../../components/WebPageComponents/FaqComponent';
export default function WebSite() {
const cardsStyle = useAppSelector((state) => state.style.cardsStyle);
const bgColor = useAppSelector((state) => state.style.bgLayoutColor);
const projectName = 'Build SaaS app that analysis stock in Nigeria';
const projectName = 'StocksageAI';
useEffect(() => {
const darkElement = document.querySelector('body .dark');
@ -111,17 +111,15 @@ export default function WebSite() {
<div className='flex flex-col min-h-screen'>
<Head>
<title>{`StockSageAI Pricing Plans`}</title>
<meta
<title>{`StocksageAI Pricing Plans`}</title>
name='description'
content={`Explore the flexible pricing plans of StockSageAI, designed to cater to individual investors, small businesses, and enterprises with AI-driven stock insights.`}
/>
content={`Explore the flexible pricing plans of StocksageAI, designed to cater to individual investors, small businesses, and enterprises with AI-driven stock insights.`}
</Head>
<WebSiteHeader
projectName={'Build SaaS app that analysis stock in Nigeria'}
/>
<WebSiteHeader projectName={'StocksageAI'} />
<main className={`flex-grow bg-white rounded-none `}>
<HeroSection
projectName={'Build SaaS app that analysis stock in Nigeria'}
projectName={'StocksageAI'}
image={['Diverse pricing plans illustration']}
mainText={`Choose Your ${projectName} Plan Today`}
subTitle={`Discover flexible pricing options with ${projectName} tailored to meet the needs of individual investors, startups, and enterprises. Unlock the power of AI-driven stock insights.`}
@ -130,22 +128,20 @@ export default function WebSite() {
/>
<PricingSection
projectName={'Build SaaS app that analysis stock in Nigeria'}
withBg={0}
projectName={'StocksageAI'}
withBg={1}
features={pricing_features}
description={description}
/>
<FaqSection
projectName={'Build SaaS app that analysis stock in Nigeria'}
projectName={'StocksageAI'}
design={FaqDesigns.ACCORDION || ''}
faqs={faqs}
mainText={`${projectName} Frequently Asked Questions `}
/>
</main>
<WebSiteFooter
projectName={'Build SaaS app that analysis stock in Nigeria'}
/>
<WebSiteFooter projectName={'StocksageAI'} />
</div>
);
}