first commit 2

This commit is contained in:
hmw1001
2026-06-11 18:47:38 +09:00
parent c768729ce6
commit 6f534e33a6
11095 changed files with 1595758 additions and 0 deletions
@@ -0,0 +1,451 @@
<?php
if (!defined('_GNUBOARD_'))
exit;
/**
* 💡 [추가] 툴팁 아이콘을 동적으로 생성하는 헬퍼 함수
* 툴팁 텍스트가 있을 경우에만 아이콘과 내용을 포함한 HTML을 반환합니다.
* @param string $text 툴팁에 표시될 내용
* @return string HTML 문자열 또는 빈 문자열
*/
function render_tooltip_icon($text)
{
if (empty(trim($text))) {
return ''; // 툴팁 내용이 없으면 아무것도 출력하지 않음
}
$text_processed = nl2br(htmlspecialchars($text)); // HTML 특수문자 처리 및 줄바꿈 적용
return <<<HTML
<div class="tooltip-wrapper">
<i class="fa fa-info-circle tooltip-icon" aria-hidden="true"></i>
<span class="tooltip-text">{$text_processed}</span>
</div>
HTML;
}
// 전문가 상담 설정 로드
$expert_config = [
'visit_fee' => 50000,
'account_info' => '국민은행 123-456-789012 (주)창호전문',
'enabled' => true
];
if (file_exists(G5_ADMIN_PATH . '/order_manage/classes/ReservationManager.class.php')) {
require_once(G5_ADMIN_PATH . '/order_manage/classes/ReservationManager.class.php');
$config_manager = new ReservationManager();
$expert_settings = $config_manager->getConfigTable();
// if ($expert_settings) {
// $config=[];
// while ($row = sql_fetch_array($expert_settings)) {
// $config[$row['config_key']] = $row['config_value'];
// }
// $expert_config = array_merge($expert_config, $config);
// }
}
// 💡 [수정] EstimateManager를 포함하고, 수정 모드일 때 데이터를 불러옵니다.
if (file_exists(G5_ADMIN_PATH . '/order_manage/classes/EstimateManager.class.php')) {
require_once(G5_ADMIN_PATH . '/order_manage/classes/EstimateManager.class.php');
$estimateManager = new EstimateManager();
$estimate_data = null;
if ($w == 'u' && $wr_id) { // $w == 'u'는 수정 모드를 의미합니다.
$estimate_data = $estimateManager->loadEstimateDataByWrId($wr_id);
}
}
$loaded_items = $estimate_data['items'] ?? []; // JS로 전달할 아이템 목록
// 1. 기본값(Fallback) 리소스 파일을 먼저 로드합니다.
$res = include(__DIR__ . '/order.defaults.php');
// 2. DB에서 관리되는 리소스를 가져옵니다.
if (file_exists(G5_ADMIN_PATH . '/order_manage/classes/FormManager.class.php')) {
require_once(G5_ADMIN_PATH . '/order_manage/classes/FormManager.class.php');
$formManager = new FormManager();
$db_res = $formManager->getResources('order_form');
if (!empty($db_res)) {
$res = array_replace_recursive($res, $db_res);
}
}
// 3. 회원 정보 처리
$mb_zip = $member['mb_zip'] ?? '';
$mb_addr1 = $member['mb_addr1'] ?? '';
$mb_addr2 = $member['mb_addr2'] ?? '';
$mb_addr3 = $member['mb_addr3'] ?? '';
// 4. JavaScript로 전달할 데이터 준비
$window_options = [];
if (isset($res['dynamic_window']['window_type_data']['options'])) {
foreach ($res['dynamic_window']['window_type_data']['options'] as $opt) {
$window_options[] = $opt['name'];
}
}
?>
<!-- 💡 [수정] 모든 하드코딩된 텍스트와 옵션을 $res 배열에서 동적으로 가져옵니다. -->
<!-- 💡 [수정] 요청하신 필드 목록과 기능에 맞춰 재구성된 공통 사양 입력 폼 -->
<div class="row">
<div class="col-lg-6">
<div class="form-group">
<label><?php echo $res['address']['address_label']['label']; ?></label>
<div class="address-zip-group">
<input type="text" name="zip_code" id="zip_code"
value="<?php echo htmlspecialchars($estimate_data['zip_code'] ?? $mb_zip); ?>"
placeholder="<?php echo $res['placeholders']['zipcode']['label']; ?>" class="zip-input">
<button type="button" id="postcode-btn"
class="popup-btn postcode-btn"><?php echo $res['address']['postcode_button']['label']; ?></button>
</div>
<div class="address-main-group">
<input type="text" name="address1" id="address1"
value="<?php echo htmlspecialchars($estimate_data['address1'] ?? $mb_addr1); ?>"
placeholder="<?php echo $res['placeholders']['address_main']['label']; ?>" class="addr-input">
<input type="text" name="address2" id="address2"
value="<?php echo htmlspecialchars($estimate_data['address2'] ?? $mb_addr2); ?>"
placeholder="<?php echo $res['placeholders']['address_detail']['label']; ?>" class="addr-input">
</div>
<input type="hidden" name="address3" id="address3"
value="<?php echo htmlspecialchars($estimate_data['address3'] ?? $mb_addr3); ?>"
placeholder="<?php echo $res['placeholders']['address_extra']['label']; ?>">
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label><?php echo $res['house_info']['house_type_label']['label']; ?></label>
<div class="options options-left">
<?php foreach ($res['house_info']['house_type_data']['options'] as $opt): ?>
<label>
<input type="radio" name="house_type" id="house_type" value="<?php echo $opt['key']; ?>" <?php echo (isset($estimate_data['house_type']) && $estimate_data['house_type'] == $opt['key']) ? 'checked' : ''; ?>> <?php echo $opt['name']; ?>
</label>
<?php endforeach; ?>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label><?php echo $res['house_info']['house_size_label']['label']; ?></label>
<input type="text" class="input-short" name="house_size" id="house_size"
value="<?php echo htmlspecialchars($estimate_data['house_size'] ?? ''); ?>"
placeholder="<?php echo $res['placeholders']['house_size']['label']; ?>" required>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label><?php echo $res['common_options']['material_label']['label']; ?></label>
<div class="options options-left">
<?php foreach ($res['common_options']['material_data']['options'] as $opt): ?>
<label><input type="radio" name="material" id='material' value="<?php echo $opt['key']; ?>" <?php echo (isset($estimate_data['material']) && $estimate_data['material'] == $opt['key']) ? 'checked' : ''; ?>> <?php echo $opt['name']; ?></label>
<?php endforeach; ?>
<div>
<font size="" color="red">**알루미늄(AL)창호와 시스템창호는 추후 서비스 예정입니다. </font>
</div>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label><?php echo $res['common_options']['color_label']['label']; ?></label>
<div class="options options-left" id="common-color-group">
<?php foreach ($res['common_options']['color_data']['options'] as $i => $opt): ?>
<label><input type="radio" name="common_color" value="<?php echo $opt['key']; ?>" <?php echo (isset($estimate_data['color']) && $estimate_data['color'] == $opt['key']) ? 'checked' : ''; ?>> <?php echo $opt['name']; ?></label>
<?php endforeach; ?>
<!-- '색지정' 선택 시 나타날 입력창 -->
<input type="text" name="common_color_custom" id="common_color_custom" class="input-short"
value="<?php echo htmlspecialchars($estimate_data['temp_2'] ?? ''); ?>"
placeholder="<?php echo $res['placeholders']['custom_color']['label']; ?>" style="display: none;">
</div>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label><?php echo $res['common_options']['glass_thick_label']['label']; ?></label>
<div class="options options-left">
<select name="common_glass_thickness" id="common_glass_thick"
class="pretty-select select-medium form-group-align-left">
<?php foreach ($res['common_options']['glass_thick_data']['options'] as $opt): ?>
<option value="<?php echo $opt['key']; ?>"><?php echo $opt['name']; ?></option>
<?php endforeach; ?>
</select>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label class="label-with-tooltip">
<?php echo $res['common_options']['construct_label']['label']; ?>
<?php echo render_tooltip_icon($res['common_options']['construct_label']['tooltip']); ?>
</label>
<div class="options options-left">
<?php foreach ($res['common_options']['construct_data']['options'] as $i => $opt): ?>
<label><input type="radio" name="construction_main" value="<?php echo $opt['key']; ?>" <?php echo (isset($estimate_data['install']) && $estimate_data['install'] == $opt['key']) ? 'checked' : ''; ?>> <?php echo $opt['name']; ?></label>
<?php endforeach; ?>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label class="label-with-tooltip">
<?php echo $res['common_options']['product_label']['label']; ?>
<!-- --><?php //echo render_tooltip_icon($res['common_options']['product_label']['tooltip']); ?>
</label>
<div class="options options-left">
<?php foreach ($res['common_options']['product_data']['options'] as $i => $opt): ?>
<label><input type="radio" name="product_main" value="<?php echo $opt['key']; ?>" <?php echo (isset($estimate_data['temp_1']) && $estimate_data['temp_1'] == $opt['key']) ? 'checked' : ''; ?>> <?php echo $opt['name']; ?></label>
<?php endforeach; ?>
</div>
</div>
</div>
<!-- 💡 [삭제] '시정장치'와 '유리사양' 필드가 여기에서 삭제되고 아래 템플릿으로 이동했습니다. -->
</div>
<!-- 동적으로 창 폼이 추가될 컨테이너 -->
<div id="dynamic-window-forms" class="row"></div>
<!-- <div style="border: 2px solid #1976d2; background: #f5faff; padding: 20px; margin: 20px 0; max-width: 1200px; text-align: left;width:100%;"> -->
<!--<div class='row'
style="border: 2px solid #1976d2; background: #f5faff; padding: 20px; margin: 20px 0; max-width: 1200px; text-align: left;width:100%;">
<div class="col-lg-6">
<div class="form-group">
<?php /*echo $res['footer_notice']['main_notice']['label']; */?>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<?php /*echo $res['footer_notice']['main_notice_sub']['label']; */?>
</div>
</div>
</div>-->
<!-- 팝업창 HTML 구조 -->
<div id="guide-modal" class="modal-overlay" data-skin-url="<?php echo $board_skin_url; ?>">
<div class="modal-content">
<button class="modal-close-btn">&times;</button>
<?php include_once('guide.php'); ?>
</div>
</div>
<div id="tutorial-modal" class="modal-overlay" data-skin-url="<?php echo $board_skin_url; ?>">
<div class="modal-content">
<button class="modal-close-btn">&times;</button>
<?php include_once('tutorial.php'); ?>
</div>
</div>
<div id="usage-guide-modal" class="modal-overlay" data-skin-url="<?php echo $board_skin_url; ?>">
<div class="modal-content">
<button class="modal-close-btn">&times;</button>
<?php include_once('usage_guide.php'); ?>
</div>
</div>
<!-- 액션 툴바 -->
<div id="action-toolbar">
<div class="toolbar-group main-action">
<label><?php echo $res['action_toolbar']['section_label']['label']; ?></label>
<button type="button" id="add-window-btn" class="popup-btn add-btn">
<i class="xi-plus"></i> <?php echo $res['action_toolbar']['add_window_button']['label']; ?>
</button>
</div>
<div class="toolbar-group sub-action">
<label><?php echo $res['action_toolbar']['help_label']['label']; ?></label>
<button type="button" class="popup-btn help-btn guide-popup-btn">
<i class="xi-help-o"></i> <?php echo $res['action_toolbar']['guide_button']['label']; ?>
</button>
<button type="button" class="popup-btn help-btn tutorial-popup-btn">
<i class="xi-help-o"></i> <?php echo $res['action_toolbar']['tutorial_button']['label']; ?>
</button>
<button type="button" class="popup-btn help-btn usage-guide-popup-btn">
<i class="xi-book-o"></i> 사용법
</button>
</div>
</div>
<!-- 💡 [개선] 구조를 통일하고 오류를 수정한 창 폼 템플릿 -->
<template id="window-form-template">
<div class="col-lg-6 col-sm-12 dynamic-box">
<div class="well2" style="margin-bottom:25px;">
<div class="well-actions">
<button type="button"
class="popup-btn help-btn guide-popup-btn"><?php echo $res['action_toolbar']['guide_button']['label']; ?></button>
<button type="button"
class="popup-btn help-btn tutorial-popup-btn"><?php echo $res['action_toolbar']['tutorial_button']['label']; ?></button>
<button type="button" class="remove-window-btn2" title="이 창 삭제">&times;</button>
<?php echo render_tooltip_icon($res['dynamic_window_template']['individual_setting_tooltip']['tooltip']); ?>
</div>
<!-- 1. 창 종류 선택 -->
<div class="form-group form-group-align-left">
<label for="window_type___INDEX__" class="dynamic-label">
__INDEX_NO__<?php echo $res['dynamic_window_template']['window_label']['label']; ?>
<?php echo render_tooltip_icon($res['dynamic_window_template']['window_label']['tooltip']); ?>
</label>
<select name="estimate[__INDEX__][location]" id="window_type___INDEX__" required
class="pretty-select window-type-select">
<option value="">창 종류 선택</option>
<!-- 옵션은 JS에서 동적으로 채워집니다. -->
</select>
</div>
<!-- 2. 기존창 규격 -->
<div class="form-group">
<label class="dynamic-label">
<?php echo $res['dynamic_window_template']['size_label']['label']; ?>
<?php echo render_tooltip_icon($res['dynamic_window_template']['size_label']['tooltip']); ?>
</label>
<div class="options input-inline">
<input type="text" class="window-size" name="estimate[__INDEX__][spec_width]"
placeholder="<?php echo $res['placeholders']['size_width']['label']; ?>" required>
<span class="x-mark">X</span>
<input type="text" class="window-size" name="estimate[__INDEX__][spec_height]"
placeholder="<?php echo $res['placeholders']['size_height']['label']; ?>" required>
</div>
</div>
<!-- 3. 창호 형태 (2단계 선택 방식으로 변경) -->
<div class="form-group window-form-group">
<label
class="dynamic-label"><?php echo $res['dynamic_window_template']['window_main_type_label']['label']; ?></label>
<!-- 1차 선택: 일반창 / 프로젝트창 -->
<div class="options input-inline window-main-type-group">
<?php foreach ($res['dynamic_window_template']['window_main_type_data']['options'] as $i => $opt): ?>
<label>
<input type="radio" name="estimate[__INDEX__][window_main_type]"
value="<?php echo $opt['key']; ?>" <?php echo $i === 0 ? 'checked' : ''; ?>>
<?php echo $opt['name']; ?>
</label>
<?php endforeach; ?>
</div>
<!-- 2차 선택: 단창 / 이중창 (JS로 제어됨) -->
<div class="options input-inline window-sub-type-group" style="margin-top: 10px; padding-left: 15px;">
<?php foreach ($res['dynamic_window_template']['window_sub_type_data']['options'] as $i => $opt): ?>
<label data-sub-type="<?php echo $opt['key']; ?>">
<input type="radio" name="estimate[__INDEX__][windowType]" value="<?php echo $opt['key']; ?>"
<?php echo $i === 0 ? 'checked' : ''; ?>>
<?php echo $opt['name']; ?>
</label>
<?php endforeach; ?>
</div>
</div>
<!-- 4. 창 비율 (일반 창호에만 표시) -->
<div class="form-group ratio-selector-group">
<label
class="dynamic-label"><?php echo $res['dynamic_window_template']['window_ratio_label']['label']; ?></label>
<div class="ratio-image-selector">
<?php foreach ($res['dynamic_window_template']['window_ratio_data']['options'] as $i => $opt): ?>
<label class="ratio-option">
<input type="radio" name="estimate[__INDEX__][windowRatio]" value="<?php echo $opt['key']; ?>"
class="sound_only" <?php echo $i === 0 ? 'checked' : ''; ?>>
<img src="<?php echo $opt['image']; ?>" alt="<?php echo $opt['name']; ?>">
<span><?php echo $opt['name']; ?></span>
</label>
<?php endforeach; ?>
</div>
</div>
<!-- 💡 [추가] 유리사양(색상) 옵션 -->
<div class="form-group glass-color-group">
<label
class="dynamic-label"><?php echo $res['dynamic_window_template']['glass_color_label']['label']; ?></label>
<select name="estimate[__INDEX__][glass_color]"
class="pretty-select select-medium form-group-align-left">
<?php foreach ($res['dynamic_window_template']['glass_color_data']['options'] as $opt): ?>
<option value="<?php echo $opt['key']; ?>"><?php echo $opt['name']; ?></option>
<?php endforeach; ?>
</select>
</div>
<!-- 💡 [추가] 시정장치(핸들) 옵션 -->
<div class="form-group handle-group">
<label class="dynamic-label">
<?php echo $res['dynamic_window_template']['handle_label']['label']; ?>
<?php echo render_tooltip_icon($res['dynamic_window_template']['handle_label']['tooltip']); ?>
</label>
<div class="options input-inline">
<?php foreach ($res['dynamic_window_template']['handle_data']['options'] as $i => $opt): ?>
<label><input type="radio" name="estimate[__INDEX__][handle]" value="<?php echo $opt['key']; ?>"
<?php echo $i === 0 ? 'checked' : ''; ?>> <?php echo $opt['name']; ?></label>
<?php endforeach; ?>
</div>
</div>
<!-- 5. 특수창 전용 유리 옵션 (화장실/주방/터닝도어에만 표시) -->
<div class="form-group special-glass-group" style="display: none;">
<label
class="dynamic-label"><?php echo $res['dynamic_window_template']['special_glass_label']['label']; ?></label>
<div class="options input-inline">
<?php foreach ($res['dynamic_window_template']['special_glass_data']['options'] as $i => $opt): ?>
<label><input type="radio" name="estimate[__INDEX__][glass_color]"
value="<?php echo $opt['key']; ?>" <?php echo $i === 0 ? 'checked' : ''; ?>>
<?php echo $opt['name']; ?></label>
<?php endforeach; ?>
</div>
</div>
<!-- 6. 교체 위치 (터닝도어 제외하고 표시) -->
<!-- <div class="form-group replace-part-group">
<label
class="dynamic-label"><?php /*echo $res['dynamic_window_template']['replace_label']['label']; */?></label>
<div class="options input-inline">
<label><input type="radio" name="estimate[__INDEX__][replacePart]" value="외부접한창" checked>
<?php /*echo $res['dynamic_window_template']['replace_option_outer']['label']; */?></label>
<label><input type="radio" name="estimate[__INDEX__][replacePart]" value="내창">
<?php /*echo $res['dynamic_window_template']['replace_option_inner']['label']; */?></label>
</div>
</div>
-->
<!-- 7. 비고 (셀렉트 박스 + 직접 입력 방식으로 변경) -->
<div class="form-group remarks-group form-group-align-left">
<label
class="dynamic-label"><?php echo $res['dynamic_window_template']['remarks_label']['label']; ?></label>
<div class="remarks-control-group"
style="display: flex; flex-direction: column; gap: 8px; width: 100%;">
<select class="pretty-select remarks-select" style="width: 100%;">
<?php foreach ($res['dynamic_window_template']['remarks_data']['options'] as $opt): ?>
<option value="<?php echo htmlspecialchars($opt['key']); ?>">
<?php echo htmlspecialchars($opt['name']); ?>
</option>
<?php endforeach; ?>
</select>
<input type="text" class="remarks-input-custom"
placeholder="<?php echo $res['placeholders']['remarks']['label']; ?>"
style="display:none; width: 100%;">
</div>
<!-- 최종 값을 저장할 히든 필드 -->
<input type="hidden" name="estimate[__INDEX__][extra_1]" class="remarks-final-value">
</div>
<label
style="display: block; margin-top: 10px; color: #e53e3e; font-size: 13px; font-weight: 500;"><?php echo $res['dynamic_window_template']['screen_notice']['label']; ?></label>
<!-- 공통 옵션을 저장할 히든 필드들 -->
<!-- <input type="hidden" name="estimate[__INDEX__][color]" value="">-->
<!-- <input type="hidden" name="estimate[__INDEX__][glass_thickness]" value="">-->
<!-- <input type="hidden" name="estimate[__INDEX__][install]" value="">-->
</div>
</div>
</template>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css" />
<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script>
<!-- 💡 [핵심] JavaScript로 DB에서 불러온 창 종류 옵션을 전달합니다. -->
<script>
const g5_window_options = <?php echo json_encode($window_options, JSON_UNESCAPED_UNICODE); ?>;
const g5_loaded_items = <?php echo json_encode($loaded_items, JSON_UNESCAPED_UNICODE); ?>;
const expert_config = <?php echo json_encode($expert_config, JSON_UNESCAPED_UNICODE); ?>;
const g5_bbs_skin_url = "<?php echo $board_skin_url; ?>";
const g5_expert_skin_url = "<?php echo G5_SKIN_URL; ?>/board/order";
</script>