Compare commits
No commits in common. "ai-dev" and "master" have entirely different histories.
@ -38,7 +38,6 @@ const commuter_profilesRoutes = require('./routes/commuter_profiles');
|
|||||||
const reward_catalog_itemsRoutes = require('./routes/reward_catalog_items');
|
const reward_catalog_itemsRoutes = require('./routes/reward_catalog_items');
|
||||||
|
|
||||||
const campaignsRoutes = require('./routes/campaigns');
|
const campaignsRoutes = require('./routes/campaigns');
|
||||||
const publicCampaignsRoutes = require('./routes/public_campaigns');
|
|
||||||
|
|
||||||
const ad_creativesRoutes = require('./routes/ad_creatives');
|
const ad_creativesRoutes = require('./routes/ad_creatives');
|
||||||
|
|
||||||
@ -131,7 +130,6 @@ app.use('/api/commuter_profiles', passport.authenticate('jwt', {session: false})
|
|||||||
app.use('/api/reward_catalog_items', passport.authenticate('jwt', {session: false}), reward_catalog_itemsRoutes);
|
app.use('/api/reward_catalog_items', passport.authenticate('jwt', {session: false}), reward_catalog_itemsRoutes);
|
||||||
|
|
||||||
app.use('/api/campaigns', passport.authenticate('jwt', {session: false}), campaignsRoutes);
|
app.use('/api/campaigns', passport.authenticate('jwt', {session: false}), campaignsRoutes);
|
||||||
app.use('/api/public-campaigns', publicCampaignsRoutes);
|
|
||||||
|
|
||||||
app.use('/api/ad_creatives', passport.authenticate('jwt', {session: false}), ad_creativesRoutes);
|
app.use('/api/ad_creatives', passport.authenticate('jwt', {session: false}), ad_creativesRoutes);
|
||||||
|
|
||||||
|
|||||||
@ -1,14 +0,0 @@
|
|||||||
const express = require('express');
|
|
||||||
const CampaignsDBApi = require('../db/api/campaigns');
|
|
||||||
const wrapAsync = require('../helpers').wrapAsync;
|
|
||||||
const router = express.Router();
|
|
||||||
|
|
||||||
router.get('/', wrapAsync(async (req, res) => {
|
|
||||||
// Public access: fetch active campaigns
|
|
||||||
// Assuming a findAll method exists in CampaignsDBApi
|
|
||||||
// We bypass auth for this specific route
|
|
||||||
const payload = await CampaignsDBApi.findAll(req.query, true, { public: true });
|
|
||||||
res.status(200).send(payload);
|
|
||||||
}));
|
|
||||||
|
|
||||||
module.exports = router;
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
export default function WebSiteFooter({ projectName }: { projectName: string }) {
|
|
||||||
return (
|
|
||||||
<footer className="border-t border-gray-200 py-6 mt-10">
|
|
||||||
<div className="container mx-auto px-6 text-center text-gray-500">
|
|
||||||
© {new Date().getFullYear()} {projectName}. All rights reserved.
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import Link from 'next/link';
|
|
||||||
|
|
||||||
export default function WebSiteHeader({ projectName }: { projectName: string }) {
|
|
||||||
return (
|
|
||||||
<header className="border-b border-gray-200 py-4">
|
|
||||||
<div className="container mx-auto px-6 flex justify-between items-center">
|
|
||||||
<div className="text-xl font-bold">{projectName}</div>
|
|
||||||
<nav>
|
|
||||||
<Link href="/" className="px-4 text-gray-700">Home</Link>
|
|
||||||
<Link href="/watch-ads" className="px-4 text-gray-700">Watch Ads</Link>
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,79 +0,0 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
|
||||||
import type { ReactElement } from 'react';
|
|
||||||
import Head from 'next/head';
|
|
||||||
import axios from 'axios';
|
|
||||||
import LayoutGuest from '../layouts/Guest';
|
|
||||||
import WebSiteHeader from '../components/WebPageComponents/Header';
|
|
||||||
import WebSiteFooter from '../components/WebPageComponents/Footer';
|
|
||||||
import BaseButton from '../components/BaseButton';
|
|
||||||
import { mdiPlayCircle } from '@mdi/js';
|
|
||||||
|
|
||||||
interface Campaign {
|
|
||||||
id: string;
|
|
||||||
campaign_name: string;
|
|
||||||
notes_internal: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function WatchAdsPage() {
|
|
||||||
const projectName = 'CommuterAds';
|
|
||||||
const [campaigns, setCampaigns] = useState<Campaign[]>([]);
|
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Log the request to see what's happening
|
|
||||||
console.log('Fetching campaigns...');
|
|
||||||
axios.get('/public-campaigns')
|
|
||||||
.then(response => {
|
|
||||||
console.log('Campaigns response:', response.data);
|
|
||||||
// Based on Campaign API, payload is in .rows
|
|
||||||
setCampaigns(response.data.rows || []);
|
|
||||||
setLoading(false);
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Error fetching campaigns:', error);
|
|
||||||
setLoading(false);
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Head>
|
|
||||||
<title>Watch Ads | CommuterAds</title>
|
|
||||||
</Head>
|
|
||||||
<WebSiteHeader projectName={projectName} />
|
|
||||||
<main className="flex-grow bg-gray-50 py-10">
|
|
||||||
<div className="container mx-auto px-6">
|
|
||||||
<h1 className="text-4xl font-bold mb-8 text-gray-900">Watch & Earn</h1>
|
|
||||||
{loading ? (
|
|
||||||
<p>Loading campaigns...</p>
|
|
||||||
) : campaigns.length > 0 ? (
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
||||||
{campaigns.map((campaign) => (
|
|
||||||
<div key={campaign.id} className="bg-white p-6 rounded-3xl shadow-sm border border-gray-100">
|
|
||||||
<div className="h-48 bg-emerald-100 rounded-2xl mb-4 flex items-center justify-center text-emerald-700 text-6xl">
|
|
||||||
{campaign.campaign_name.charAt(0)}
|
|
||||||
</div>
|
|
||||||
<h2 className="text-xl font-bold mb-2">{campaign.campaign_name}</h2>
|
|
||||||
<p className="text-gray-600 mb-4">{campaign.notes_internal || 'Watch to earn rewards!'}</p>
|
|
||||||
<BaseButton
|
|
||||||
label="Watch & Earn"
|
|
||||||
icon={mdiPlayCircle}
|
|
||||||
color="success"
|
|
||||||
className="w-full"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<p>No campaigns available right now.</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
<WebSiteFooter projectName={projectName} />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
WatchAdsPage.getLayout = function getLayout(page: ReactElement) {
|
|
||||||
return <LayoutGuest>{page}</LayoutGuest>;
|
|
||||||
};
|
|
||||||
Loading…
x
Reference in New Issue
Block a user