diff --git a/code/__DEFINES/announcements.dm b/code/__DEFINES/announcements.dm
index 3a2edf6d6f7..b40303514ea 100644
--- a/code/__DEFINES/announcements.dm
+++ b/code/__DEFINES/announcements.dm
@@ -5,3 +5,7 @@
#define ANNOUNCEMENT_TYPE_CAPTAIN "Captain"
/// Make it sound like it's coming from the Syndicate
#define ANNOUNCEMENT_TYPE_SYNDICATE "Syndicate"
+
+//Defines for newscaster news stations, the defined thing is what it'll be called in the Newscaster.
+#define NEWSCASTER_STATION_ANNOUNCEMENTS "Station Announcements"
+#define NEWSCASTER_SPACE_BETTING "SpaceBet"
diff --git a/code/__HELPERS/priority_announce.dm b/code/__HELPERS/priority_announce.dm
index 3e458bbb33f..e49001b4e72 100644
--- a/code/__HELPERS/priority_announce.dm
+++ b/code/__HELPERS/priority_announce.dm
@@ -63,7 +63,7 @@
header += SUBHEADER_ANNOUNCEMENT_TITLE(title)
if(ANNOUNCEMENT_TYPE_CAPTAIN)
header = MAJOR_ANNOUNCEMENT_TITLE("Captain's Announcement")
- GLOB.news_network.submit_article(text, "Captain's Announcement", "Station Announcements", null)
+ GLOB.news_network.submit_article(text, "Captain's Announcement", NEWSCASTER_STATION_ANNOUNCEMENTS, null)
if(ANNOUNCEMENT_TYPE_SYNDICATE)
header = MAJOR_ANNOUNCEMENT_TITLE("Syndicate Captain's Announcement")
else
@@ -87,9 +87,9 @@
if(isnull(sender_override) && players == GLOB.player_list)
if(length(title) > 0)
- GLOB.news_network.submit_article(title + "
" + text, "[command_name()]", "Station Announcements", null)
+ GLOB.news_network.submit_article(title + "
" + text, "[command_name()]", NEWSCASTER_STATION_ANNOUNCEMENTS, null)
else
- GLOB.news_network.submit_article(text, "[command_name()] Update", "Station Announcements", null)
+ GLOB.news_network.submit_article(text, "[command_name()] Update", NEWSCASTER_STATION_ANNOUNCEMENTS, null)
/proc/print_command_report(text = "", title = null, announce=TRUE)
if(!title)
diff --git a/code/controllers/subsystem/economy.dm b/code/controllers/subsystem/economy.dm
index aed9222b40d..9aff9693914 100644
--- a/code/controllers/subsystem/economy.dm
+++ b/code/controllers/subsystem/economy.dm
@@ -191,7 +191,7 @@ SUBSYSTEM_DEF(economy)
update_alerts = TRUE
inflict_moneybags(moneybags)
earning_report += "That's all from the Nanotrasen Economist Division."
- GLOB.news_network.submit_article(earning_report, "Station Earnings Report", "Station Announcements", null, update_alert = update_alerts)
+ GLOB.news_network.submit_article(earning_report, "Station Earnings Report", NEWSCASTER_STATION_ANNOUNCEMENTS, null, update_alert = update_alerts)
return TRUE
/**
diff --git a/code/game/machinery/newscaster/newscaster_data.dm b/code/game/machinery/newscaster/newscaster_data.dm
index 3b3287b2513..d67e7e99365 100644
--- a/code/game/machinery/newscaster/newscaster_data.dm
+++ b/code/game/machinery/newscaster/newscaster_data.dm
@@ -185,7 +185,8 @@ GLOBAL_LIST_EMPTY(request_list)
var/message_count = 0
/datum/feed_network/New()
- create_feed_channel("Station Announcements", "SS13", "Company news, staff announcements, and all the latest information. Have a secure shift!", locked = TRUE, hardset_channel = 1000)
+ create_feed_channel(NEWSCASTER_STATION_ANNOUNCEMENTS, "SS13", "Company news, staff announcements, and all the latest information. Have a secure shift!", locked = TRUE, hardset_channel = 1000)
+ create_feed_channel(NEWSCASTER_SPACE_BETTING, "NtOS", "News from the SpaceBet PDA App! Download now and make your own bets!", locked = TRUE, hardset_channel = 1001)
wanted_issue = new /datum/wanted_message
/datum/feed_network/proc/create_feed_channel(channel_name, author, desc, locked, adminChannel = FALSE, hardset_channel = null, author_ckey = null, cross_sector = FALSE, cross_sector_delay = null, receiving_cross_sector = FALSE)
@@ -236,7 +237,6 @@ GLOBAL_LIST_EMPTY(request_list)
newMsg.parent_ID = channel.channel_ID
if (!channel.cross_sector)
break
-
// Newscaster articles could be huge, and usefulness of first 50 symbols is dubious
message_admins(span_adminnotice("Outgoing cross-sector newscaster article by [key_name(author_mob) || author] in channel [channel_name]."))
var/list/payload = list(
@@ -249,6 +249,18 @@ GLOBAL_LIST_EMPTY(request_list)
for(var/obj/machinery/newscaster/caster in GLOB.allCasters)
caster.news_alert(channel_name, update_alert)
+ return newMsg
+
+///Submits a comment on the news network
+/datum/feed_network/proc/submit_comment(mob/user, comment_text, newscaster_username, datum/feed_message/current_message)
+ var/datum/feed_comment/new_feed_comment = new/datum/feed_comment
+ new_feed_comment.author = newscaster_username
+ new_feed_comment.body = comment_text
+ new_feed_comment.time_stamp = station_time_timestamp()
+ GLOB.news_network.last_action ++
+ current_message.comments += new_feed_comment
+ if(user)
+ user.log_message("(as [newscaster_username]) commented on message [current_message.return_body(-1)] -- [current_message.body]", LOG_COMMENT)
/datum/feed_network/proc/submit_wanted(criminal, body, scanned_user, datum/picture/picture, adminMsg = FALSE, newMessage = FALSE)
wanted_issue.active = TRUE
diff --git a/code/game/machinery/newscaster/newscaster_machine.dm b/code/game/machinery/newscaster/newscaster_machine.dm
index da243f81a35..208166ef231 100644
--- a/code/game/machinery/newscaster/newscaster_machine.dm
+++ b/code/game/machinery/newscaster/newscaster_machine.dm
@@ -741,13 +741,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30)
if(!newscaster_username)
creating_comment = FALSE
return TRUE
- var/datum/feed_comment/new_feed_comment = new/datum/feed_comment
- new_feed_comment.author = newscaster_username
- new_feed_comment.body = comment_text
- new_feed_comment.time_stamp = station_time_timestamp()
- GLOB.news_network.last_action ++
- current_message.comments += new_feed_comment
- user.log_message("(as [newscaster_username]) commented on message [current_message.return_body(-1)] -- [current_message.body]", LOG_COMMENT)
+ GLOB.news_network.submit_comment(user, comment_text, newscaster_username, current_message)
creating_comment = FALSE
/**
diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm
index 394ed99e9dd..60ad61f8cf5 100644
--- a/code/game/machinery/requests_console.dm
+++ b/code/game/machinery/requests_console.dm
@@ -191,7 +191,7 @@ GLOBAL_LIST_EMPTY(req_console_ckey_departments)
message = L.treat_message(message)["message"]
minor_announce(message, "[department] Announcement:", html_encode = FALSE, sound_override = ANNOUNCER_DEPARTMENTAL) // SKYRAT EDIT CHANGE - Announcer Sounds
- GLOB.news_network.submit_article(message, department, "Station Announcements", null)
+ GLOB.news_network.submit_article(message, department, NEWSCASTER_STATION_ANNOUNCEMENTS, null)
usr.log_talk(message, LOG_SAY, tag="station announcement from [src]")
message_admins("[ADMIN_LOOKUPFLW(usr)] has made a station announcement from [src] at [AREACOORD(usr)].")
deadchat_broadcast(" made a station announcement from [span_name("[get_area_name(usr, TRUE)]")].", span_name("[usr.real_name]"), usr, message_type=DEADCHAT_ANNOUNCEMENT)
diff --git a/code/modules/modular_computers/file_system/programs/betting.dm b/code/modules/modular_computers/file_system/programs/betting.dm
new file mode 100644
index 00000000000..19b47dd89d2
--- /dev/null
+++ b/code/modules/modular_computers/file_system/programs/betting.dm
@@ -0,0 +1,285 @@
+GLOBAL_LIST_EMPTY_TYPED(active_bets, /datum/active_bet)
+
+///Max amount of characters you can have in an active bet's title
+#define MAX_LENGTH_TITLE 64
+///Max amount of characters you can have in an active bet's description
+#define MAX_LENGTH_DESCRIPTION 200
+
+/datum/computer_file/program/betting
+ filename = "betting"
+ filedesc = "SpaceBet"
+ downloader_category = PROGRAM_CATEGORY_GAMES
+ program_open_overlay = "gambling"
+ extended_desc = "A multi-platform network for placing requests across the station, with payment across the network being possible."
+ program_flags = PROGRAM_ON_NTNET_STORE | PROGRAM_REQUIRES_NTNET
+ can_run_on_flags = PROGRAM_PDA
+ size = 4
+ tgui_id = "NtosSpaceBetting"
+ program_icon = "dice"
+
+ ///The active bet this program made, as we can only have 1 going at a time to prevent flooding/spam.
+ var/datum/active_bet/created_bet
+
+/datum/computer_file/program/betting/New()
+ . = ..()
+ RegisterSignal(src, COMSIG_COMPUTER_FILE_DELETE, PROC_REF(on_delete))
+
+///Called when we're deleted, we'll be taking the bet with us.
+/datum/computer_file/program/betting/proc/on_delete(datum/source, obj/item/modular_computer/computer_uninstalling)
+ SIGNAL_HANDLER
+
+ created_bet.payout()
+ QDEL_NULL(created_bet)
+
+/datum/computer_file/program/betting/ui_data(mob/user)
+ var/list/data = list()
+ data["active_bets"] = list()
+ for(var/datum/active_bet/bets as anything in GLOB.active_bets)
+ data["active_bets"] += list(list(
+ "name" = bets.name,
+ "description" = bets.description,
+ "owner" = bets == created_bet,
+ "creator" = bets.bet_owner,
+ "current_bets" = bets.get_bets(computer.computer_id_slot?.registered_account),
+ "locked" = bets.locked,
+ ))
+
+ data["can_create_bet"] = !!isnull(created_bet)
+ if(isnull(computer.computer_id_slot))
+ data["bank_name"] = null
+ data["bank_money"] = null
+ else
+ data["bank_name"] = computer.computer_id_slot.registered_account.account_holder
+ data["bank_money"] = computer.computer_id_slot.registered_account.account_balance
+
+ return data
+
+/datum/computer_file/program/betting/ui_static_data(mob/user)
+ var/list/data = list()
+ data["max_title_length"] = MAX_LENGTH_TITLE
+ data["max_description_length"] = MAX_LENGTH_DESCRIPTION
+ return data
+
+/datum/computer_file/program/betting/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
+ . = ..()
+ var/mob/user = ui.user
+ if(isnull(computer.computer_id_slot))
+ to_chat(user, span_danger("\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning."))
+ return
+ switch(action)
+ if("create_bet")
+ var/title = reject_bad_name(params["title"], allow_numbers = TRUE, max_length = MAX_LENGTH_TITLE, cap_after_symbols = FALSE)
+ var/description = reject_bad_name(params["description"], allow_numbers = TRUE, max_length = MAX_LENGTH_DESCRIPTION, cap_after_symbols = FALSE)
+ if(isnull(title) || isnull(description))
+ return
+ var/list/options = list(params["option1"], params["option2"], params["option3"], params["option4"])
+ for(var/option in options)
+ options -= option
+ //remove nulls, empty, and duplicates.
+ if(isnull(option) || option == "" || options.Find(option))
+ continue
+ options += option
+ option = reject_bad_name(option, allow_numbers = TRUE, max_length = MAX_LENGTH_TITLE, cap_after_symbols = FALSE)
+ if(length(options) < 2)
+ to_chat(user, span_danger("2 options minimum required to start a bet."))
+ return
+ created_bet = new(user, title, description, options)
+ return TRUE
+ if("place_bet")
+ var/datum/active_bet/bet_placed_on
+ for(var/datum/active_bet/bets as anything in GLOB.active_bets)
+ if(bets.name == params["bet_selected"])
+ bet_placed_on = bets
+ //can't bet on your own bet
+ if(isnull(bet_placed_on))
+ return
+ if(bet_placed_on == created_bet)
+ to_chat(user, span_danger("You can't bet on your own poll!"))
+ return
+ var/money_betting = params["money_betting"]
+ if(!isnum(money_betting))
+ return
+ var/option = params["option_selected"]
+ if(isnull(bet_placed_on))
+ return
+ bet_placed_on.bet_money(computer.computer_id_slot.registered_account, money_betting, option)
+ return TRUE
+ if("cancel_bet")
+ var/datum/active_bet/bet_cancelling
+ for(var/datum/active_bet/bets as anything in GLOB.active_bets)
+ if(bets.name == params["bet_selected"])
+ bet_cancelling = bets
+ bet_cancelling.cancel_bet(computer.computer_id_slot.registered_account)
+ return TRUE
+ if("select_winner")
+ var/datum/active_bet/bets_ending
+ for(var/datum/active_bet/bets as anything in GLOB.active_bets)
+ if(bets.name == params["bet_selected"])
+ bets_ending = bets
+ if(isnull(bets_ending) || bets_ending != created_bet)
+ return
+ created_bet.payout(params["winning_answer"])
+ QDEL_NULL(created_bet)
+ return TRUE
+ if("lock_betting")
+ var/datum/active_bet/bet_locking
+ for(var/datum/active_bet/bets as anything in GLOB.active_bets)
+ if(bets.name == params["bet_selected"])
+ bet_locking = bets
+ if(bet_locking != created_bet)
+ return
+ bet_locking.locked = TRUE
+
+/**
+ * The active bet that our app will create & use, handles following who owns the bet,
+ * who is betting, and also takes care of paying out at the end.
+ */
+/datum/active_bet
+ ///The person owning the bet, who will choose which option has won.
+ var/bet_owner
+ ///The name of the bet
+ var/name
+ ///The description of the bet
+ var/description
+ ///Boolean on whether the bet is locked from getting new betters, or current ones from taking their money out.
+ var/locked
+ ///Total amount of money that has been bet.
+ var/total_amount_bet
+ /** Assoc list of options, with each option having a list of people betting and the amount they've bet.
+ options = list(
+ OPTION_A = list(
+ PERSON_1_ACCOUNT = bet_amount,
+ PERSON_2_ACCOUNT = bet_amount,
+ ),
+ OPTION_B = list(
+ PERSON_3_ACCOUNT = bet_amount,
+ ),
+ )
+ */
+ var/list/options
+
+ ///The message we sent to the newscaster, which we'll then reply to once the betting is over.
+ var/datum/feed_message/newscaster_message
+
+/datum/active_bet/New(creator, name, description, options)
+ src.bet_owner = creator
+ src.name = name
+ src.description = description
+ src.options = options
+ GLOB.active_bets += src
+ for(var/option in options)
+ if(!length(options[option]))
+ options[option] = list()
+ //we'll only advertise it on the first bet of the round, as to not make this overly annoying.
+ var/should_alert = FALSE
+ for(var/datum/feed_channel/FC in GLOB.news_network.network_channels)
+ if(FC.channel_name == NEWSCASTER_SPACE_BETTING)
+ if(!length(FC.messages))
+ should_alert = TRUE
+ newscaster_message = GLOB.news_network.submit_article("The bet [name] has started, place your bets now!", "NtOS Space Betting App", NEWSCASTER_SPACE_BETTING, null, update_alert = should_alert)
+
+/datum/active_bet/Destroy(force)
+ GLOB.active_bets -= src
+ newscaster_message = null
+ return ..()
+
+///Returns how many bets there is per option
+/datum/active_bet/proc/get_bets(datum/bank_account/user_account)
+ var/list/bets_per_option = list()
+ for(var/option in options)
+ var/amount_personally_invested = 0
+ var/total_amount = 0
+ for(var/list/existing_bets in options[option])
+ var/existing_bet_amount = text2num(existing_bets[2])
+ if(user_account && (existing_bets[1] == user_account))
+ amount_personally_invested = existing_bet_amount
+ total_amount += existing_bet_amount
+ bets_per_option += list(list("option_name" = option, "amount" = total_amount, "personally_invested" = amount_personally_invested))
+ return bets_per_option
+
+///Pays out the loser's money equally to all the winners, or refunds it all if no winning option was given.
+/datum/active_bet/proc/payout(winning_option)
+ if(isnull(winning_option) || !(winning_option in options))
+ //no winner was selected (likely the host's PDA was destroyed or attempted href exploit), so let's refund everyone.
+ for(var/list/option in options)
+ for(var/list/existing_bets in options[option])
+ var/datum/bank_account/refunded_account = existing_bets[1]
+ refunded_account.adjust_money(text2num(existing_bets[2]), "Refund: [name] gamble cancelled.")
+ return
+ GLOB.news_network.submit_comment(
+ comment_text = "The bet [name] has ended, the winner was [winning_option]!",
+ newscaster_username = "NtOS Betting Results",
+ current_message = newscaster_message,
+ )
+ var/list/winners = options[winning_option]
+ if(!length(winners))
+ return
+ for(var/list/winner in winners)
+ //they aren't winning their own money, so people betting a ton of money won't lose their money to those who bet few.
+ total_amount_bet -= text2num(winner[2])
+ for(var/list/winner in winners)
+ var/datum/bank_account/winner_account = winner[1]
+ var/money_won = text2num(winner[2]) + total_amount_bet / length(winners)
+ winner_account.adjust_money(money_won, "Won gamble: [name]") //give them their money back & whatever they won.
+ //they only made their money back, don't tell them they won anything.
+ if((money_won - text2num(winner[2])) == 0)
+ continue
+ winner_account.bank_card_talk("You won [money_won]cr from having a correct guess on [name]!")
+
+///Puts a bank account's money bet on a given option.
+/datum/active_bet/proc/bet_money(datum/bank_account/better, money_betting, option_betting)
+ if(locked)
+ return
+ for(var/option in options)
+ for(var/list/existing_bets in options[option])
+ if(existing_bets[1] == better)
+ //We're already betting, but now we're betting on another one, clear our previous and we'll bet on the new.
+ if(option != option_betting)
+ better.adjust_money(text2num(existing_bets[2]), "Refunded: changed bet for [name].")
+ options[option] -= list(existing_bets)
+ //We're already betting on the same one, we'll add it together instead of making it a separate bet, or the user is taking money out.
+ else
+ //putting more money in
+ if(text2num(existing_bets[2]) < money_betting)
+ if(better.account_balance < money_betting)
+ return
+ var/money_adding_in = money_betting - text2num(existing_bets[2])
+ total_amount_bet += money_adding_in
+ better.bank_card_talk("Additional [money_adding_in]cr deducted for your bet on [name].")
+ better.adjust_money(-money_adding_in, "Gambling on [name].")
+ existing_bets[2] = "[money_betting]"
+ return
+ //taking it all out, we remove them from the list so they aren't a winner with bets of 0.
+ if(money_betting == 0)
+ var/money_taking_out = text2num(existing_bets[2])
+ total_amount_bet -= money_taking_out
+ better.adjust_money(money_taking_out, "Refunded: changed bet for [name].")
+ options[option] -= list(existing_bets)
+ return
+ //taking money out
+ if(text2num(existing_bets[2]) > money_betting)
+ var/money_taking_out = text2num(existing_bets[2]) - money_betting
+ total_amount_bet -= money_taking_out
+ better.bank_card_talk("Refunded [money_taking_out]cr for taking money out of your bet on [name].")
+ better.adjust_money(money_taking_out, "Refund from gambling on [name].")
+ existing_bets[2] = "[money_betting]"
+ return
+
+ total_amount_bet += money_betting
+ options[option_betting] += list(list(better, "[money_betting]"))
+ better.adjust_money(-money_betting, "Gambling on [name]")
+ better.bank_card_talk("Deducted [money_betting]cr for your bet on [name].")
+
+///Cancels your bet, removing your bet and refunding your money.
+/datum/active_bet/proc/cancel_bet(datum/bank_account/better)
+ for(var/option in options)
+ for(var/list/existing_bets in options[option])
+ if(existing_bets[1] == better)
+ var/money_refunding = text2num(existing_bets[2])
+ total_amount_bet -= money_refunding
+ better.bank_card_talk("Refunded [money_refunding]cr for cancelling your bet on [name].")
+ better.adjust_money(money_refunding, "Refunded: changed bet for [name].")
+ options[option] -= list(existing_bets)
+
+#undef MAX_LENGTH_TITLE
+#undef MAX_LENGTH_DESCRIPTION
diff --git a/icons/obj/devices/modular_pda.dmi b/icons/obj/devices/modular_pda.dmi
index 6981b1de37f..a427eb143ce 100644
Binary files a/icons/obj/devices/modular_pda.dmi and b/icons/obj/devices/modular_pda.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index 3600bc307d7..64838712168 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -5648,6 +5648,7 @@
#include "code\modules\modular_computers\file_system\programs\alarm.dm"
#include "code\modules\modular_computers\file_system\programs\arcade.dm"
#include "code\modules\modular_computers\file_system\programs\atmosscan.dm"
+#include "code\modules\modular_computers\file_system\programs\betting.dm"
#include "code\modules\modular_computers\file_system\programs\borg_monitor.dm"
#include "code\modules\modular_computers\file_system\programs\bounty_board.dm"
#include "code\modules\modular_computers\file_system\programs\budgetordering.dm"
diff --git a/tgui/packages/tgui/interfaces/NtosSpaceBetting.tsx b/tgui/packages/tgui/interfaces/NtosSpaceBetting.tsx
new file mode 100644
index 00000000000..c8bdb11ccfd
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/NtosSpaceBetting.tsx
@@ -0,0 +1,263 @@
+import { useState } from 'react';
+import {
+ Box,
+ Button,
+ Collapsible,
+ Divider,
+ Icon,
+ Input,
+ NumberInput,
+ Section,
+ Stack,
+ TextArea,
+} from 'tgui-core/components';
+import { BooleanLike } from 'tgui-core/react';
+
+import { useBackend } from '../backend';
+import { NtosWindow } from '../layouts';
+
+type Data = {
+ active_bets: ActiveBets[];
+ bank_name: string;
+ bank_money: number;
+ can_create_bet: BooleanLike;
+ max_title_length: number;
+ max_description_length: number;
+};
+
+type ActiveBets = {
+ name: string;
+ description: string;
+ owner: BooleanLike;
+ creator: string;
+ current_bets: CurrentBets[];
+ locked: BooleanLike;
+};
+
+type CurrentBets = {
+ option_name: string;
+ total_amount: number;
+ personally_invested: number;
+};
+
+export const NtosSpaceBetting = () => {
+ const { act, data } = useBackend();
+ const { bank_name, bank_money, can_create_bet } = data;
+ return (
+
+
+
+
+
+
+
+
+ Username: {bank_name}
+ Money Available: {bank_money}cr
+
+
+
+
+ {!!can_create_bet && }
+
+
+ );
+};
+
+export const PollsSection = () => {
+ const { act, data } = useBackend();
+ const { active_bets = [] } = data;
+ const [Winner, set_winner] = useState('');
+ return (
+
+ {!active_bets.length ? (
+
+ There's currently no active polls to bet on, create one below!
+
+ ) : (
+ active_bets.map(
+ (
+ { name, description, owner, creator, current_bets = [], locked },
+ index,
+ ) => (
+
+
+
+ {description}
+
+ {current_bets.map(
+ (
+ { option_name, total_amount, personally_invested },
+ index,
+ ) => (
+
+
+
+ {option_name} (Has {total_amount || 0}cr bet on it)
+ {!owner ? (
+
+ act('place_bet', {
+ bet_selected: name,
+ option_selected: option_name,
+ money_betting: value,
+ })
+ }
+ />
+ ) : (
+ set_winner(option_name)}
+ />
+ )}
+
+
+
+ ),
+ )}
+ {!!owner &&
+ (!locked ? (
+
+
+ act('lock_betting', { bet_selected: name })
+ }
+ >
+ Lock Betting
+
+
+ ) : (
+
+ act('select_winner', {
+ bet_selected: name,
+ winning_answer: Winner,
+ })
+ }
+ >
+ Finalize Results
+
+ ))}
+
+
+
+
+
+
+ ),
+ )
+ )}
+
+ );
+};
+
+export const BettingCreation = () => {
+ const { act, data } = useBackend();
+ const { max_title_length, max_description_length } = data;
+ const [Title, setTitle] = useState('');
+ const [Desc, setDesc] = useState('');
+ const [Option1, setOption1] = useState('');
+ const [Option2, setOption2] = useState('');
+ const [Option3, setOption3] = useState('');
+ const [Option4, setOption4] = useState('');
+ return (
+
+
+
+ setTitle(value)}
+ />
+
+
+
+ setOption1(value)}
+ />
+ setOption2(value)}
+ />
+ setOption3(value)}
+ />
+ setOption4(value)}
+ />
+
+
+
+
+
+ );
+};