Skip to content

Commit

Permalink
Merge pull request #5 from MinaFoundation/feature/dockerfile-2
Browse files Browse the repository at this point in the history
feat: get proposal data via HTTP
  • Loading branch information
iluxonchik authored Sep 17, 2024
2 parents 4507991 + 193837e commit 6c352c0
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 119 deletions.
1 change: 0 additions & 1 deletion astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ import tailwind from '@astrojs/tailwind';
export default defineConfig({
integrations: [tailwind()],
output: 'server',

});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "",
"name": "pgtgovbotocvfrontend",
"type": "module",
"version": "0.0.1",
"scripts": {
Expand Down
4 changes: 2 additions & 2 deletions src/components/ProposalCard.astro
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
import type { ProposalData } from "../models/Proposal";
import type { ProposalAttributes } from "../models/Proposal";
interface Props {
proposal: ProposalData;
proposal: ProposalAttributes;
}
const { proposal } = Astro.props;
Expand Down
66 changes: 10 additions & 56 deletions src/models/Proposal.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { Model, DataTypes } from 'sequelize';
import sequelize from '../db/connection';
import { Model, DataTypes } from "sequelize";
import sequelize from "../db/connection";

export enum ProposalStatus {
DRAFT = 'DRAFT',
CONSIDERATION_PHASE = 'CONSIDERATION_VOTE',
DELIBERATION_PHASE = 'DELIBERATION_VOTE',
FUNDING_VOTING_PHASE = 'FUNDING_VOTE',
FUNDED = 'FUNDED',
CANCELLED = 'CANCELLED',
DRAFT = "DRAFT",
CONSIDERATION_PHASE = "CONSIDERATION_VOTE",
DELIBERATION_PHASE = "DELIBERATION_VOTE",
FUNDING_VOTING_PHASE = "FUNDING_VOTE",
FUNDED = "FUNDED",
CANCELLED = "CANCELLED",
}

export interface ProposalAttributes {
Expand All @@ -19,52 +19,6 @@ export interface ProposalAttributes {
fundingRoundId: number | null;
forumThreadId: string | null;
status: ProposalStatus;
createdAt: string;
updatedAt: string;
}

export class Proposal extends Model {
}

Proposal.init(
{
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
},
name: {
type: DataTypes.STRING(32),
allowNull: false,
},
proposerDuid: {
type: DataTypes.STRING,
allowNull: false,
},
budget: {
type: DataTypes.DECIMAL(10, 2),
allowNull: false,
},
uri: {
type: DataTypes.STRING(255),
allowNull: false,
},
fundingRoundId: {
type: DataTypes.INTEGER,
allowNull: true,
},
status: {
type: DataTypes.ENUM(...Object.values(ProposalStatus)),
allowNull: false,
defaultValue: ProposalStatus.DRAFT,
},
forumThreadId: {
type: DataTypes.STRING,
allowNull: true,
},
},
{
sequelize,
tableName: 'proposals',
}
);

export default Proposal;
49 changes: 25 additions & 24 deletions src/pages/api/proposal/[id].ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
import type { APIRoute } from 'astro';
import Proposal from '../../../models/Proposal';
import type { APIRoute } from "astro";
import { fetchProposal } from "../../../services/apiService";

export const get: APIRoute = async ({ params }) => {
export const GET: APIRoute = async ({ params }) => {
const { id } = params;


if (!id || isNaN(parseInt(id))) {
return new Response(JSON.stringify({ error: "Invalid proposal ID" }), {
status: 400,
headers: {
"Content-Type": "application/json",
},
});
}

try {
const proposal = await Proposal.findByPk(id);
if (proposal) {
return new Response(JSON.stringify(proposal), {
status: 200,
headers: {
"Content-Type": "application/json"
}
});
} else {
return new Response(JSON.stringify({ error: 'Proposal not found' }), {
status: 404,
headers: {
"Content-Type": "application/json"
}
});
}
const proposal = await fetchProposal(parseInt(id));
return new Response(JSON.stringify(proposal), {
status: 200,
headers: {
"Content-Type": "application/json",
},
});
} catch (error) {
return new Response(JSON.stringify({ error: 'Internal Server Error' }), {
console.error("Error fetching proposal:", error);
return new Response(JSON.stringify({ error: "Failed to fetch proposal" }), {
status: 500,
headers: {
"Content-Type": "application/json"
}
"Content-Type": "application/json",
},
});
}
}
};
63 changes: 33 additions & 30 deletions src/pages/index.astro
Original file line number Diff line number Diff line change
@@ -1,43 +1,46 @@
---
import MainLayout from '../layouts/MainLayout.astro';
import WalletConnectButton from '../components/WalletConnectButton.astro';
import NetworkSwitch from '../components/NetworkSwitch.astro';
import Proposal from '../models/Proposal';
import MainLayout from "../layouts/MainLayout.astro";
import WalletConnectButton from "../components/WalletConnectButton.astro";
import NetworkSwitch from "../components/NetworkSwitch.astro";
import { fetchActiveProposals } from "../services/apiService";
import type { ProposalAttributes } from "../models/Proposal";
let proposals: Proposal[] = [];
let proposals: ProposalAttributes[] = [];
let error = null;
try {
proposals = await Proposal.findAll({
where: {
status: 'FUNDING_VOTE'
},
order: [['createdAt', 'DESC']]
});
proposals = await fetchActiveProposals();
} catch (e) {
error = 'Error fetching proposals';
error = "Error fetching proposals";
}
---

<MainLayout title="Mina Proposal Voting">
<WalletConnectButton />
<NetworkSwitch />

<h2 class="text-2xl font-bold mt-8 mb-4">Active Proposals</h2>

{error ? (
<p class="text-red-500">{error}</p>
) : proposals.length > 0 ? (
<ul class="space-y-4">
{proposals.map((proposal) => (
<li class="bg-white p-4 rounded-lg shadow-md">
<h3 class="text-xl font-semibold mb-2">{proposal.name}</h3>
<p class="mb-2">Budget: {proposal.budget} MINA</p>
<a href={`/vote/${proposal.id}`} class="text-blue-500 hover:underline">Vote on this proposal</a>
</li>
))}
</ul>
) : (
<p>No active proposals at the moment.</p>
)}
</MainLayout>

{
error ? (
<p class="text-red-500">{error}</p>
) : proposals.length > 0 ? (
<ul class="space-y-4">
{proposals.map((proposal) => (
<li class="bg-white p-4 rounded-lg shadow-md">
<h3 class="text-xl font-semibold mb-2">{proposal.name}</h3>
<p class="mb-2">Budget: {proposal.budget} MINA</p>
<a
href={`/vote/${proposal.id}`}
class="text-blue-500 hover:underline"
>
Vote on this proposal
</a>
</li>
))}
</ul>
) : (
<p>No active proposals at the moment.</p>
)
}
</MainLayout>
11 changes: 6 additions & 5 deletions src/pages/vote/[id].astro
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@ import VotingInterface from "../../components/VotingInterface.astro";
import ProgressTracker from "../../components/ProgressTracker.astro";
import StepInstructions from "../../components/StepInstructions.astro";
import VotingExplanation from "../../components/VotingExplanation.astro";
import { Proposal } from "../../models/Proposal";
import { VotingStep } from "../../models/VotingState";
import { currentStep, updateStep } from "../../store/votingStore";
import { setProposalId } from "../../store/proposalStore";
import { fetchProposal } from "../../services/apiService";
const { id } = Astro.params;
const proposalId = parseInt(id);
const proposal = await Proposal.findByPk(proposalId);
setProposalId(proposalId);
let proposal;
if (!proposal) {
try {
proposal = await fetchProposal(proposalId);
setProposalId(proposalId);
} catch (error) {
return Astro.redirect("/404");
}
Expand Down
23 changes: 23 additions & 0 deletions src/services/apiService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { ProposalAttributes } from "../models/Proposal";

const { API_BASE_URL } = import.meta.env;

export async function fetchProposal(id: number): Promise<ProposalAttributes> {
const response = await fetch(`${API_BASE_URL}/api/projects/${id}`);
if (!response.ok) {
throw new Error("Failed to fetch proposal");
}
const data = await response.json();
return data.proposal;
}

export async function fetchActiveProposals(): Promise<ProposalAttributes[]> {
const response = await fetch(
`${API_BASE_URL}/api/projects?status=FUNDING_VOTE`
);
if (!response.ok) {
throw new Error("Failed to fetch active proposals");
}
const data = await response.json();
return data.proposals;
}

0 comments on commit 6c352c0

Please sign in to comment.