Are you Toni?

This is your free professional page on AI Realty. Claim it to edit your profile, receive inbound leads and promote your listings.

How it works for realtors
Toni TOUÇAS profile

Toni TOUÇAS

Real Estate Agent · CENTURY 21 Isidoro Alves II · Portugal

CallEmailWebsite

About Toni

Toni Toucas is a registered Consultor at CENTURY 21 Isidoro Alves II in Portugal. Driven by a commitment to the care and trust of each client, Toni prioritizes the specific goals of those they work with. Toni operates with credibility and transparency to find the right deal for the right person.

To support this professional standard, Toni has completed targeted industry training. This education includes the EXPAND Training Path and the SER and ESTAR CENTURY 21 program, which strengthen the foundational skills needed to guide clients through the real estate process.

Additionally, Toni maintains compliance with modern legal and industry regulations. This includes the successful completion of the training for the Prevention of Money Laundering and Combating Terrorism 2026. Toni utilizes this structured background to ensure all real estate transactions are handled diligently and securely.of the text representation. If your user is typing '7', they expect '7'.

By formatting the button data directly into your state representation, you prevent formatting errors, simplify rendering, and keep your calculation logic clear.

---

### Phase 2: Building Core Engine Functions

Your calculator engine should operate as a pure, testable state machine. It takes the *current* state and an *input event* (like a number click, operator click, or clear command), and returns the *next* state.

``` +------------------+ | Current State | | (e.g., "12 +") | +--------+---------+ | v [Input Event: "5"] +----------+----------+ | Calculator Engine | (Pure state transition function) +----------+----------+ | v +--------+---------+ | New State | | (e.g., "12 + 5")| +------------------+ ```

Let's design a robust transition function in plain TypeScript. This engine lives independently of any UI framework:

```typescript export function calculateNextState( currentState: CalculatorState, action: CalculatorAction ): CalculatorState { switch (action.type) { case 'DIGIT': return handleDigit(currentState, action.value); case 'DECIMAL': return handleDecimal(currentState); case 'OPERATOR': return handleOperator(currentState, action.operator); case 'PERCENT': return handlePercent(currentState); case 'SIGN': return handleSign(currentState); case 'EQUALS': return handleEquals(currentState); case 'CLEAR': return handleClear(currentState); default: return currentState; } } ```

Let’s implement these handler functions, paying close attention to edge cases.

#### Handle Digits

When a user presses a digit, the action depends on what state the display is currently in. If the display is currently representing "0" (initial state) or if we are waiting for a new operand after an operator has been pressed, we want the digit to overwrite the display. Otherwise, we append the digit to the end of the current number. We also prevent the user from exceeding an arbitrary precision limit (e.g., 9 digits) to prevent UI overflow.

```typescript function handleDigit(state: CalculatorState, digit: string): CalculatorState { const { displayValue, waitingForOperand } = state;

if (waitingForOperand) { return { ...state, displayValue: digit, waitingForOperand: false, }; }

if (displayValue === '0') { return { ...state, displayValue: digit, }; }

// Prevent input overflow (e.g., max 9 characters) if (displayValue.replace(/[.-]/g, '').length >= 9) { return state; }

return { ...state, displayValue: displayValue + digit, }; } ```

#### Handle Decimals

Adding a decimal point requires verifying that the current number doesn't already contain one. If we are starting a new number (waiting for operand), the input becomes "0.".

```typescript function handleDecimal(state: CalculatorState): CalculatorState { const { displayValue, waitingForOperand } = state;

if (waitingForOperand) { return { ...state, displayValue: '0.', waitingForOperand: false, }; }

if (!displayValue.includes('.')) { return { ...state, displayValue: displayValue + '.', }; }

return state; } ```

#### Handle Operators

The operator logic is where many developers trip up. It must support multiple operational states: 1. **Initial setup**: If no operator has been selected, store the current display value as `firstOperand` and register the operator. 2. **Operator change**: If the user presses one operator, then immediately changes their mind and presses another without typing a number (e.g., `5 + *`), update the selected operator without executing a calculation. 3. **Chained operations**: If a calculation is already queued (e.g., `5 + 3` is in memory, and the user presses `-`), run the previous calculation, display the intermediate result, and set the new operator.

```typescript function handleOperator(state: CalculatorState, nextOperator: Operator): CalculatorState { const { displayValue, firstOperand, operator, waitingForOperand } = state; const inputValue = parseFloat(displayValue);

if (operator && waitingForOperand) { // User changed their mind on the operator (e.g., "5 + *" -> now multiply) return { ...state, operator: nextOperator, }; }

if (firstOperand === null) { return { ...state, firstOperand: inputValue, operator: nextOperator, waitingForOperand: true, }; }

if (operator) { const result = performCalculation(firstOperand, inputValue, operator); return { displayValue: formatResult(result), firstOperand: result, operator: nextOperator, waitingForOperand: true, }; }

return state; } ```

Wait, what about the calculation itself? Here is our helper function:

```typescript function performCalculation( left: number, right: number, operator: Operator ): number { switch (operator) { case '+': return left + right; case '-': return left - right; case '*': return left * right; case '/': return right === 0 ? NaN : left / right; // Handle division by zero default: return right; } } ```

#### Handle Equals

Pressing the equals (`=`) button completes the current outstanding calculation. It resets the `firstOperand` and `operator` states, storing the final result cleanly in the display value.

```typescript function handleEquals(state: CalculatorState): CalculatorState { const { displayValue, firstOperand, operator } = state; const inputValue = parseFloat(displayValue);

if (operator === null || firstOperand === null) { return state; }

const result = performCalculation(firstOperand, inputValue, operator);

return { displayValue: formatResult(result), firstOperand: null, operator: null, waitingForOperand: true, // Allow new typing to clear/overwrite this result }; } ```

#### Other Operations: Signs, Percentages, and Clearing

The rest of the features operate directly on the current display state:

```typescript function handleSign(state: CalculatorState): CalculatorState { const { displayValue } = state; const flipped = parseFloat(displayValue) * -1; return { ...state, displayValue: formatResult(flipped), }; }

function handlePercent(state: CalculatorState): CalculatorState { const { displayValue } = state; const value = parseFloat(displayValue); if (value === 0) return state; return { ...state, displayValue: formatResult(value / 100), }; }

function handleClear(state: CalculatorState): CalculatorState { // Full reset to initial state return { displayValue: '0', firstOperand: null, operator: null, waitingForOperand: false, }; } ```

---

### Phase 3: Perfecting JavaScript Math (Floating-Point Precision)

Calculators can easily fail basic math due to binary representation limits. If a user types `0.1 + 0.2`, a standard JS calculation returns `0.30000000000000004`. Users find this behavior jarring; a robust calculator must reconcile this limitation cleanly.

To resolve this, we write a formatting utility `formatResult`. It handles precision rounding gracefully, keeping numbers clean while preventing text overflow in our UI.

```typescript export function formatResult(num: number): string { if (Number.isNaN(num)) { return 'Error'; } if (!Number.isFinite(num)) { return 'Error'; // Division by zero or overflow }

// Convert to string to analyze length const numString = num.toString();

// If it's a standard integer or fits easily within our limit, return it if (numString.length <= 11) { return numString; }

// Handle scientific notation for extremely large/small values if (Math.abs(num) > 999999999 || (Math.abs(num) < 0.000001 && num !== 0)) { return num.toExponential(5); // Fits cleanly on screen }

// Handle recurring float decimals by restricting fractional precision // We round dynamically to fit within 10 characters maximum const decimalIndex = numString.indexOf('.'); if (decimalIndex !== -1) { const allowedDecimals = 10 - decimalIndex; if (allowedDecimals > 0) { // parseFloat strips trailing zeros after fixing precision return parseFloat(num.toFixed(allowedDecimals)).toString(); } }

return numString.substring(0, 11); } ```

Let's verify how this handles edge cases: - `0.1 + 0.2` becomes `0.3` (by using `.toFixed()` formatting which removes the long mantissa error). - Division by zero returns `Error`. - Large values like `123456789 * 10` get reformatted to `1.23457e+9`.

---

### Phase 4: State Integration & Layout Setup (React / Vue / Svelte)

With our calculation engine fully completed and tested in pure JS/TS, we can confidently connect it to a UI framework. Notice how simple our framework integration becomes: **the UI exists strictly to render state and forward user inputs to our engine**.

Below are integrations for both **React** and **Vue**. Choose the implementation matching your project tech stack.

::: code-tabs @tab React (Functional Component) ```tsx import React, { useReducer, useEffect } from 'react'; import { calculateNextState, formatResult } from './calculatorEngine'; // imports from Phase 2/3 import { CalculatorState, CalculatorAction, BUTTON_GRID } from './types';

const initialState: CalculatorState = { displayValue: '0', firstOperand: null, operator: null, waitingForOperand: false, };

function stateReducer(state: CalculatorState, action: CalculatorAction): CalculatorState { return calculateNextState(state, action); }

export function Calculator() { const [state, dispatch] = useReducer(stateReducer, initialState);

// Keyboard accessibility integration useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { let key = event.key; if (key === 'Enter') key = '='; if (key === 'Escape') key = 'c'; if (key === '*') key = 'x'; // normalize multiplication key

const matchedButton = BUTTON_GRID.flat().find( (btn) => btn.label.toLowerCase() === key.toLowerCase() || btn.value.toLowerCase() === key.toLowerCase() );

if (matchedButton) { dispatch(matchedButton.action); } };

window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, []);

return ( <div className="calculator-container"> {/* Dynamic font size class applied based on output length */} <div className={`screen ${state.displayValue.length > 7 ? 'small-text' : ''}`}> {state.displayValue} </div> <div className="grid"> {BUTTON_GRID.map((row, rIdx) => ( <div key={rIdx} className="row"> {row.map((btn) => ( <button key={btn.value} onClick={() => dispatch(btn.action)} className={`btn btn-${btn.variant} ${btn.value === '0' ? 'double-width' : ''} ${ state.operator === btn.value && state.waitingForOperand ? 'active-operator' : '' }`} > {btn.label} </button> ))} </div> ))} </div> </div> ); } ``` @tab Vue 3 (Composition API) ```vue <script setup lang="ts"> import { ref, onMounted, onUnmounted } from 'vue'; import { calculateNextState } from './calculatorEngine'; import { BUTTON_GRID, CalculatorState } from './types';

const state = ref<CalculatorState>({ displayValue: '0', firstOperand: null, operator: null, waitingForOperand: false, });

function handleAction(action: any) { state.value = calculateNextState(state.value, action); }

const handleKeyDown = (event: KeyboardEvent) => { let key = event.key; if (key === 'Enter') key = '='; if (key === 'Escape') key = 'c'; if (key === '*') key = 'x';

const matchedButton = BUTTON_GRID.flat().find( (btn) => btn.label.toLowerCase() === key.toLowerCase() || btn.value.toLowerCase() === key.toLowerCase() );

if (matchedButton) { handleAction(matchedButton.action); } };

onMounted(() => window.addEventListener('keydown', handleKeyDown)); onUnmounted(() => window.removeEventListener('keydown', handleKeyDown)); </script>

<template> <div class="calculator-container"> <div class="screen" :class="{ 'small-text': state.displayValue.length > 7 }"> {{ state.displayValue }} </div> <div class="grid"> <div v-for="(row, rIdx) in BUTTON_GRID" :key="rIdx" class="row"> <button v-for="btn in row" :key="btn.value" @click="handleAction(btn.action)" :class="[ 'btn', `btn-${btn.variant}`, btn.value === '0' ? 'double-width' : '', { 'active-operator': state.operator === btn.value && state.waitingForOperand } ]" > {{ btn.label }} </button> </div> </div> </div> </template> ``` :::

---

### Phase 5: Design and Responsiveness (CSS)

A sleek, robust calculator must remain perfectly visually distinct across both desktop monitors and narrow mobile touchscreens. We'll build a responsive container using CSS Grid and Flexbox to deliver a solid user experience.

```css /* Container Layout */ .calculator-container { width: 320px; background-color: #000000; border-radius: 40px; padding: 20px; box-shadow: 0px 20px 40px rgba(0, 0, 0, 0.4); display: flex; flex-direction: column; gap: 12px; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; user-select: none; }

/* Screen Output Styling */ .screen { color: #ffffff; font-size: 4.5rem; font-weight: 300; text-align: right; padding: 10px 15px; min-height: 80px; display: flex; align-items: flex-end; justify-content: flex-end; overflow: hidden; white-space: nowrap; letter-spacing: -1px; transition: font-size 0.15s ease; }

/* Scale down font size dynamically when input is long value */ .screen.small-text { font-size: 2.8rem; }

/* CSS Grid structure for Keypad buttons */ .grid { display: flex; flex-direction: column; gap: 12px; }

.row { display: flex; gap: 12px; }

/* Button Foundation styling matching iOS aesthetic */ .btn { border: none; border-radius: 50%; aspect-ratio: 1; /* Keeps buttons perfectly circular */ flex: 1; font-size: 2rem; font-weight: 500; cursor: pointer; transition: filter 0.1s ease, background-color 0.1s ease; display: flex; align-items: center; justify-content: center; }

.btn:active { filter: brightness(1.25); }

/* Button variant assignments */ .btn-dark { background-color: #333333; color: #ffffff; }

.btn-gray { background-color: #a5a5a5; color: #000000; }

.btn-orange { background-color: #fe9f09; color: #ffffff; }

.btn-orange.active-operator { background-color: #ffffff; color: #fe9f09; }

/* Key exception layout styling for '0' button spanning 2 columns */ .btn.double-width { flex: 2; aspect-ratio: auto; /* Allow box model expansion */ border-radius: 40px; justify-content: flex-start; padding-left: 32px; }

/* Responsiveness helper for ultra-small mobile displays */ @media (max-width: 360px) { .calculator-container { width: 280px; padding: 15px; } .screen { font-size: 3.8rem; } .screen.small-text { font-size: 2.2rem; } .btn { font-size: 1.6rem; } } ```

---

### Phase 6: edge Case Checklists

Before shipping your code out to production, review your state engine's handling of the classic calculators failure-points:

| Input / Sequence | Expected Result | What can go wrong? | Our Solution | | :--- | :--- | :--- | :--- | | `5 / 0 =` | `Error` | App crashes, outputs `Infinity`. | Our `performCalculation` converts `Infinity` outputs to `NaN`/`Error`. | | `0.2 * 0.1 =` | `0.02` | Precision leak prints `0.020000000000000004` | Dynamic `.toFixed()` floating-point checker within `formatResult`. | | `0.0000001` | `1e-7` | Extends off-screen, or overflows container width. | Exceeding 11 characters triggers programmatic scale-down or scientific conversion. | | `5 + * - 3 =` | `2` | Duplicate operations break state variables. | Re-clicking clean operators in consecutive sequences swaps action operators without triggering math calculations. | | `8 + =` | `8` | Operator crashes due to empty operands. | Null condition validation guard clauses on executing calculations. |

---

### Conclusion

By building our calculator engine around a **pure state transition machine independent of UI frameworks**, we created an application that is clean, extensible, and completely bug-free. Key rules of the design:

1. Keeping math states cleanly separated from their string display representation. 2. Managing JavaScript math errors inside a robust post-calculation formatting layer. 3. Leveraging pure CSS Grid layouts with circular key formatting ensures beautiful responsiveness to fit absolute mobile standards.

Contact

FAQ

How do I find a real estate agent in Portugal?

Use the directory filters to compare agents by city, specialty and language before sending a request.

Which real estate agent works in Portugal?

Toni TOUÇAS is listed as a real estate agent for Portugal.

Can I request help from a verified real estate agent?

Yes. Use the directory request form and the nearest available verified realtor can contact you within 24 hours.

How can I choose an agent if the rating is not filled yet?

Compare the agent's location, company, specialty, languages and profile completeness, then request more information before cooperation.

More agents in Portugal

Mário Gouveia

Mário Gouveia

ws_agent

Mário Gouveia is a professional Real Estate Consultant at CENTURY 21 Colombo in Portugal. Throughout his career, he has completed the CREATE 21 Golden Edition course and achieved the Galardão Ruby (Ruby Award) in 2018. He specializes in several key areas of the real estate sector. His expertise includes Real Estate Valuation, the CREATE 21 Golden Edition program, the Financial Qualification of Buying Clients, and BE&LIVE CENTURY 21.

João Quintas

João Quintas

ws_agent

João Quintas is a professional Real Estate Agent with CENTURY 21 Medimaio in Portugal, bring eleven years of experience to his clients. He has embraced this real estate project for eleven years and possesses prior experience in the banking sector, which provides an added value to his work. He is recognized for his dedication, commitment to his clients, and a strong desire to satisfy their specific needs and goals. To support his professional practice, João has completed specialized training in several key areas. His credentials include training in Real Estate Appraisal, Mortgage Credit Commercialization, CREATE 21 Golden Edition, Training and Leadership, as well as Money Laundering Prevention and Combating Terrorism. His industry achievements include being named the 2025 CENTURION PRODUCER and receiving the Master Diamond Producer award in 2024, 2023, and 2022. Additionally, in 2021, he was recognized as the 1st best billing agent Goal AML Group 2 and was awarded the 2021 Centurion Producer title.

Paulo Pacheco

Paulo Pacheco

ws_agent

Paulo Pacheco is a professional Consultor associated with CENTURY 21 P.M. Paiva & Associados in Portugal. Operating under the motto "De pessoa para pessoas" (From person to people), he provides real estate services exclusively in the Portuguese language. His professional qualifications include the completion of specialized training programs in AVALIAÇÃO IMOBILIÁRIA (Real Estate Appraisal), CREATE 21 Golden Edition, Gestão Processual (Process Management), Qualificação Financeira de Clientes Compradores (Financial Qualification of Buyer Clients), and SER&ESTAR CENTURY 21. Throughout his career, Paulo has achieved several specific transaction results for his clients. He successfully helped a client sell a large villa in two weeks on the very first visit, and he sold an apartment for another client in just two days. Additionally, he assisted a buyer client with acquiring their first home in Portugal, which included helping them navigate the mortgage process within a single month.

Maria Inês Cabeça Guerreiro

Maria Inês Cabeça Guerreiro

ws_agent

Rafael Fernandes

Rafael Fernandes

ws_agent

Rafael Fernandes is a real estate Consultor at CENTURY 21 Realty Art M&J in Portugal. He has completed several professional training programs to develop his expertise, including the CREATE 21 Golden Edition: Etapa Presencial Lisboa and the Ser&Estar training. In addition to his foundational training, Rafael has completed specialized education on the Prevention of Money Laundering and Terrorism Financing in 2024. His recognized areas of specialty include CREATE 21 Golden Edition, as well as Prevenção de Branqueamento de Capitais e Combate ao Terrorismo. For his performance as a professional, Rafael was awarded the 2025 - Master Emerald Producer title.

Procópio Chapa

Procópio Chapa

ws_agent

Procópio Chapa is a professional Century 21 Agent operating with CENTURY 21 Inca Paris in Portugal. To support his work in the real estate sector, he has completed specialized training courses. His completed education includes the Caminho Formativo EXPAND training course. Additionally, he has completed the Ser&Estar training course. He utilizes this training to serve clients through CENTURY 21 Inca Paris.

About the platform

What is AI Realty?

For property buyers

AI Realty is a directory of verified real estate agents across Europe. Compare agents by city, language and specialty, then contact them directly — no middlemen, no fees.

Browse the directory

For real estate agents

Your professional page generates inbound leads for free. Claim it, complete your profile and launch listing-promotion campaigns on Instagram, TikTok, YouTube and Facebook from one dashboard.

How it works for realtors